changeset 81:301599387b40

Common: remove class prefix in resources_locator|loader
author David Demelier <markand@malikania.fr>
date Sun, 22 Jan 2017 10:11:17 +0100
parents a162f380f02e
children ee850a6ab89e
files examples/animation/main.cpp examples/font/main.cpp examples/image/main.cpp examples/js-animation/main.cpp examples/js-font/main.cpp examples/js-image/main.cpp examples/js-sprite/main.cpp examples/sprite/main.cpp libclient/malikania/client_resources_loader.hpp libcommon-js/malikania/js_resources_loader.cpp libcommon-js/malikania/js_resources_loader.hpp libcommon/CMakeLists.txt libcommon/malikania/common-config.hpp libcommon/malikania/loader.cpp libcommon/malikania/loader.hpp libcommon/malikania/locator.cpp libcommon/malikania/locator.hpp libcommon/malikania/resources_loader.cpp libcommon/malikania/resources_loader.hpp libcommon/malikania/resources_locator.cpp libcommon/malikania/resources_locator.hpp
diffstat 21 files changed, 394 insertions(+), 408 deletions(-) [+]
line wrap: on
line diff
--- a/examples/animation/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/animation/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -23,7 +23,7 @@
 #include <malikania/animation.hpp>
 #include <malikania/animator.hpp>
 #include <malikania/client_resources_loader.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 #include <malikania/window.hpp>
 
 int main()
@@ -32,7 +32,7 @@
 
     try {
         mlk::window win(400, 400);
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         mlk::animation animation = loader.load_animation("animations/margins.json");
         mlk::animator animator(animation);
--- a/examples/font/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/font/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -22,8 +22,8 @@
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/color.hpp>
 #include <malikania/font.hpp>
+#include <malikania/locator.hpp>
 #include <malikania/point.hpp>
-#include <malikania/resources_locator.hpp>
 #include <malikania/window.hpp>
 
 using namespace std::chrono_literals;
@@ -108,7 +108,7 @@
 {
     try {
         mlk::window window(400, 400);
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         mlk::font font = loader.load_font("DejaVuSans.ttf", 10);
 
--- a/examples/image/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/image/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -21,7 +21,7 @@
 
 #include <malikania/client_resources_loader.hpp>
 #include <malikania/image.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 #include <malikania/window.hpp>
 
 using namespace std::chrono_literals;
@@ -48,7 +48,7 @@
 {
     try {
         mlk::window window(400, 400);
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
 
         draw(window, loader);
--- a/examples/js-animation/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/js-animation/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -23,14 +23,14 @@
 #include <malikania/js_animation.hpp>
 #include <malikania/js_animator.hpp>
 #include <malikania/js_window.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 
 using namespace std::chrono_literals;
 
 int main()
 {
     try {
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         dukx_context m_ctx;
 
--- a/examples/js-font/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/js-font/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -22,7 +22,7 @@
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_font.hpp>
 #include <malikania/js_window.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 
 using namespace std::chrono_literals;
 
@@ -50,7 +50,7 @@
 int main()
 {
     try {
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         dukx_context ctx;
 
--- a/examples/js-image/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/js-image/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -22,7 +22,7 @@
 #include <malikania/js_client_resources_loader.hpp>
 #include <malikania/js_image.hpp>
 #include <malikania/js_window.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 
 using namespace std::chrono_literals;
 
@@ -65,7 +65,7 @@
 int main()
 {
     try {
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         dukx_context ctx;
 
--- a/examples/js-sprite/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/js-sprite/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -23,7 +23,7 @@
 #include <malikania/js_image.hpp>
 #include <malikania/js_sprite.hpp>
 #include <malikania/js_window.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 
 using namespace std::chrono_literals;
 
@@ -58,7 +58,7 @@
 int main()
 {
     try {
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         dukx_context ctx;
 
--- a/examples/sprite/main.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/examples/sprite/main.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -21,7 +21,7 @@
 #include <exception>
 
 #include <malikania/client_resources_loader.hpp>
-#include <malikania/resources_locator.hpp>
+#include <malikania/locator.hpp>
 #include <malikania/sprite.hpp>
 #include <malikania/window.hpp>
 
@@ -46,7 +46,7 @@
 int main()
 {
     try {
-        mlk::directory_resources_locator locator(SOURCE_DIRECTORY);
+        mlk::directory_locator locator(SOURCE_DIRECTORY);
         mlk::client_resources_loader loader(locator);
         mlk::window window(400, 400);
 
--- a/libclient/malikania/client_resources_loader.hpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/libclient/malikania/client_resources_loader.hpp	Sun Jan 22 10:11:17 2017 +0100
@@ -24,7 +24,7 @@
  * \brief Load client assets.
  */
 
-#include <malikania/resources_loader.hpp>
+#include <malikania/loader.hpp>
 
 #include "animation.hpp"
 #include "font.hpp"
@@ -37,7 +37,7 @@
 /**
  * \brief Load client resources.
  */
-class client_resources_loader : public resources_loader {
+class client_resources_loader : public loader {
 protected:
     /**
      * Require a size object from an object property.
@@ -77,8 +77,8 @@
      * \param window the window
      * \param locator the resources locator
      */
-    inline client_resources_loader(resources_locator& locator)
-        : resources_loader(locator)
+    inline client_resources_loader(mlk::locator& locator)
+        : loader(locator)
     {
     }
 
--- a/libcommon-js/malikania/js_resources_loader.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/libcommon-js/malikania/js_resources_loader.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -28,7 +28,7 @@
 
 } // !namespace
 
-void dukx_put_loader(duk_context *ctx, resources_loader& loader)
+void dukx_put_loader(duk_context *ctx, loader& loader)
 {
     assert(ctx);
 
@@ -38,17 +38,17 @@
     duk_put_global_string(ctx, variable.c_str());
 }
 
-resources_loader& duk_require_loader(duk_context* ctx)
+loader& duk_require_loader(duk_context* ctx)
 {
     assert(ctx);
 
     dukx_stack_assert sa(ctx);
 
     duk_get_global_string(ctx, variable.c_str());
-    auto ptr = static_cast<resources_loader*>(duk_to_pointer(ctx, -1));
+    auto ptr = static_cast<loader*>(duk_to_pointer(ctx, -1));
     duk_pop(ctx);
 
-    return *static_cast<resources_loader*>(ptr);
+    return *static_cast<loader*>(ptr);
 }
 
 } // !mlk
--- a/libcommon-js/malikania/js_resources_loader.hpp	Sun Jan 22 09:59:14 2017 +0100
+++ b/libcommon-js/malikania/js_resources_loader.hpp	Sun Jan 22 10:11:17 2017 +0100
@@ -20,13 +20,13 @@
 #define MALIKANIA_JS_RESOURCES_LOADER_H
 
 #include "duktape.hpp"
-#include "resources_loader.hpp"
+#include "loader.hpp"
 
 namespace mlk {
 
-void dukx_put_loader(duk_context* ctx, resources_loader&);
+void dukx_put_loader(duk_context* ctx, loader&);
 
-resources_loader& dukx_get_loader(duk_context* ctx);
+loader& dukx_get_loader(duk_context* ctx);
 
 } // !mlk
 
--- a/libcommon/CMakeLists.txt	Sun Jan 22 09:59:14 2017 +0100
+++ b/libcommon/CMakeLists.txt	Sun Jan 22 10:11:17 2017 +0100
@@ -22,15 +22,15 @@
     HEADERS
     ${libmlk-common_SOURCE_DIR}/malikania/game.hpp
     ${libmlk-common_SOURCE_DIR}/malikania/id.hpp
-    ${libmlk-common_SOURCE_DIR}/malikania/resources_loader.hpp
-    ${libmlk-common_SOURCE_DIR}/malikania/resources_locator.hpp
+    ${libmlk-common_SOURCE_DIR}/malikania/loader.hpp
+    ${libmlk-common_SOURCE_DIR}/malikania/locator.hpp
     ${libmlk-common_SOURCE_DIR}/malikania/util.hpp
 )
 
 set(
     SOURCES
-    ${libmlk-common_SOURCE_DIR}/malikania/resources_loader.cpp
-    ${libmlk-common_SOURCE_DIR}/malikania/resources_locator.cpp
+    ${libmlk-common_SOURCE_DIR}/malikania/loader.cpp
+    ${libmlk-common_SOURCE_DIR}/malikania/locator.cpp
     ${libmlk-common_SOURCE_DIR}/malikania/util.cpp
 )
 
--- a/libcommon/malikania/common-config.hpp	Sun Jan 22 09:59:14 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#ifndef COMMON_CONFIG_HPP
-#define COMMON_CONFIG_HPP
-
-#if defined(_WIN32)
-#  if defined(MALIKANIA_COMMON_BUILD)
-#    define MALIKANIA_COMMON_EXPORT __declspec(dllexport)
-#  else
-#    define MALIKANIA_COMMON_EXPORT __declspec(dllimport)
-#  endif
-#else
-#  define MALIKANIA_COMMON_EXPORT
-#endif
-
-#endif // !COMMON_CONFIG_HPP
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/malikania/loader.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -0,0 +1,108 @@
+/*
+ * loader.cpp -- load shared resources files
+ *
+ * Copyright (c) 2013-2017 Malikania Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <boost/format.hpp>
+
+#include <cassert>
+
+#include "game.hpp"
+#include "loader.hpp"
+#include "locator.hpp"
+
+namespace mlk {
+
+void loader::requires(const std::string& id,
+                      const nlohmann::json& object,
+                      const std::unordered_map<std::string, nlohmann::json::value_t>& props) const
+{
+    assert(object.is_object());
+
+    for (const auto& pair : props) {
+        auto it = object.find(pair.first);
+
+        if (it == object.end() || it->type() != pair.second) {
+            std::string type;
+
+            switch (pair.second) {
+            case nlohmann::json::value_t::array:
+                type = "array";
+                break;
+            case nlohmann::json::value_t::boolean:
+                type = "boolean";
+                break;
+            case nlohmann::json::value_t::number_unsigned:
+                type = "number";
+                break;
+            case nlohmann::json::value_t::object:
+                type = "object";
+                break;
+            case nlohmann::json::value_t::string:
+                type = "string";
+                break;
+            default:
+                break;
+            }
+
+            throw std::runtime_error(boost::str(
+                boost::format("%s: missing '%s' property (%s expected)") % id % pair.first % type));
+        }
+    }
+}
+
+std::string loader::require_string(const std::string& id,
+                                   const nlohmann::json& object,
+                                   const std::string& property) const
+{
+    assert(object.is_object());
+
+    auto it = object.find(property);
+
+    if (it == object.end() || !it->is_string()) {
+        throw std::runtime_error(id + ": missing '" + property + "' property (string expected)");
+    }
+
+    return *it;
+}
+
+loader::loader(mlk::locator& locator)
+    : m_locator(locator)
+{
+}
+
+game loader::load_game() const
+{
+    auto value = nlohmann::json::parse(m_locator.read("game.json"));
+
+    if (!value.is_object()) {
+        throw std::runtime_error("game.json: not a JSON object");
+    }
+
+    requires("game.json", value, {
+        { "name",       nlohmann::json::value_t::string },
+        { "version",    nlohmann::json::value_t::string },
+        { "requires",   nlohmann::json::value_t::string }
+    });
+
+    return game{value["name"],
+                value["version"],
+                value["requires"],
+                value.count("license") > 0 ? value["license"] : "",
+                value.count("author") > 0 ? value["author"] : ""};
+}
+
+} // !mlk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/malikania/loader.hpp	Sun Jan 22 10:11:17 2017 +0100
@@ -0,0 +1,114 @@
+/*
+ * loader.hpp -- load shared resources files
+ *
+ * Copyright (c) 2013-2017 Malikania Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MALIKANIA_LOADER_HPP
+#define MALIKANIA_LOADER_HPP
+
+#include <string>
+#include <unordered_map>
+
+#include <json.hpp>
+
+#include "locator.hpp"
+
+namespace mlk {
+
+class game;
+
+/**
+ * \brief Open resources files using a locator.
+ *
+ * This class is used to load resources files that are common to the server and
+ * the client.
+ *
+ * \see client_loader
+ */
+class loader {
+private:
+    mlk::locator& m_locator;
+
+protected:
+    /**
+     * Check that an object has the specified properties of the given type.
+     *
+     * Throws an error when any of the property is missing or not the correct
+     * type.
+     *
+     * You can use this function when you have lot of properties to extract,
+     * otherwise, you can use one of the require* or get* functions to avoid
+     * performances overhead.
+     *
+     * \pre object.is_object()
+     * \param id the resource id
+     * \param object the object
+     * \param props the properties
+     * \throw std::runtime_error when a property is missing / invalid
+     */
+    void requires(const std::string& id,
+                  const nlohmann::json& object,
+                  const std::unordered_map<std::string, nlohmann::json::value_t>& props) const;
+
+    /**
+     * Require a string.
+     *
+     * \pre object.isObject()
+     * \param id the resource id
+     * \param object the object
+     * \param property the property
+     * \return the string
+     * \throw std::runtime_error if the property is not a string or missing
+     */
+    std::string require_string(const std::string& id,
+                               const nlohmann::json& object,
+                               const std::string& property) const;
+
+public:
+    /**
+     * Construct the resources loader.
+     *
+     * \param locator the locator
+     */
+    loader(mlk::locator& locator);
+
+    /**
+     * Virtual destructor defaulted.
+     */
+    virtual ~loader() noexcept = default;
+
+    /**
+     * Get the underlying locator.
+     *
+     * \return the locator
+     */
+    inline mlk::locator& locator() noexcept
+    {
+        return m_locator;
+    }
+
+    /**
+     * Load a game.
+     *
+     * \return the game
+     * \throw std::runtime_error on errors
+     */
+    virtual game load_game() const;
+};
+
+} // !mlk
+
+#endif // !MALIKANIA_LOADER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/malikania/locator.cpp	Sun Jan 22 10:11:17 2017 +0100
@@ -0,0 +1,56 @@
+/*
+ * locator.cpp -- file and stream loader
+ *
+ * Copyright (c) 2013-2017 Malikania Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include <iterator>
+#include <stdexcept>
+
+#include "locator.hpp"
+
+namespace mlk {
+
+directory_locator::directory_locator(std::string path) noexcept
+    : m_path(std::move(path))
+{
+}
+
+std::string directory_locator::read(const std::string &id)
+{
+    std::ifstream in(m_path + "/" + id, std::ifstream::in | std::ifstream::binary);
+
+    if (!in) {
+        throw std::runtime_error(std::strerror(errno));
+    }
+
+    return std::string(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>());
+}
+
+std::unique_ptr<std::istream> directory_locator::open(const std::string &id)
+{
+    auto ptr = std::make_unique<std::ifstream>(m_path + "/" + id);
+
+    if (!(*ptr)) {
+        throw std::runtime_error(std::strerror(errno));
+    }
+
+    return std::move(ptr);
+}
+
+} // !mlk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcommon/malikania/locator.hpp	Sun Jan 22 10:11:17 2017 +0100
@@ -0,0 +1,85 @@
+/*
+ * locator.hpp -- file and stream loader
+ *
+ * Copyright (c) 2013-2017 Malikania Authors
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MALIKANIA_LOCATOR_HPP
+#define MALIKANIA_LOCATOR_HPP
+
+#include <string>
+#include <memory>
+#include <istream>
+
+namespace mlk {
+
+/**
+ * \brief Abstract assets locator.
+ */
+class locator {
+public:
+    /**
+     * Default destructor.
+     */
+    virtual ~locator() = default;
+
+    /**
+     * Read a whole resource as a string.
+     *
+     * \param id the resource id
+     * \return the string
+     * \throw std::runtime_error on any errors
+     */
+    virtual std::string read(const std::string& id) = 0;
+
+    /**
+     * Open a resource as a stream.
+     *
+     * \param id the resource id
+     * \return the stream
+     * \throw std::runtime_error on any errors
+     */
+    virtual std::unique_ptr<std::istream> open(const std::string& id) = 0;
+};
+
+/**
+ * \brief Load a game from a directory.
+ */
+class directory_locator : public locator {
+private:
+    std::string m_path;
+
+public:
+    /**
+     * Load the game from the directory.
+     *
+     * \param path the base directory
+     */
+    directory_locator(std::string path) noexcept;
+
+    /**
+     * \copydoc locator::read
+     */
+    std::string read(const std::string& id) override;
+
+    /**
+     * \copydoc locator::open
+     */
+    std::unique_ptr<std::istream> open(const std::string& id) override;
+};
+
+} // !mlk
+
+#endif // !MALIKANIA_RESOURCES_LOCATOR_HPP
--- a/libcommon/malikania/resources_loader.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * resources_loader.cpp -- load shared resources files
- *
- * Copyright (c) 2013-2017 Malikania Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <boost/format.hpp>
-
-#include <cassert>
-
-#include "game.hpp"
-#include "resources_loader.hpp"
-#include "resources_locator.hpp"
-
-namespace mlk {
-
-void resources_loader::requires(const std::string& id,
-                                const nlohmann::json& object,
-                                const std::unordered_map<std::string, nlohmann::json::value_t>& props) const
-{
-    assert(object.is_object());
-
-    for (const auto& pair : props) {
-        auto it = object.find(pair.first);
-
-        if (it == object.end() || it->type() != pair.second) {
-            std::string type;
-
-            switch (pair.second) {
-            case nlohmann::json::value_t::array:
-                type = "array";
-                break;
-            case nlohmann::json::value_t::boolean:
-                type = "boolean";
-                break;
-            case nlohmann::json::value_t::number_unsigned:
-                type = "number";
-                break;
-            case nlohmann::json::value_t::object:
-                type = "object";
-                break;
-            case nlohmann::json::value_t::string:
-                type = "string";
-                break;
-            default:
-                break;
-            }
-
-            throw std::runtime_error(boost::str(
-                boost::format("%s: missing '%s' property (%s expected)") % id % pair.first % type));
-        }
-    }
-}
-
-std::string resources_loader::require_string(const std::string& id,
-                                            const nlohmann::json& object,
-                                            const std::string& property) const
-{
-    assert(object.is_object());
-
-    auto it = object.find(property);
-
-    if (it == object.end() || !it->is_string()) {
-        throw std::runtime_error(id + ": missing '" + property + "' property (string expected)");
-    }
-
-    return *it;
-}
-
-resources_loader::resources_loader(resources_locator& locator)
-    : m_locator(locator)
-{
-}
-
-game resources_loader::load_game() const
-{
-    auto value = nlohmann::json::parse(m_locator.read("game.json"));
-
-    if (!value.is_object()) {
-        throw std::runtime_error("game.json: not a JSON object");
-    }
-
-    requires("game.json", value, {
-        { "name",       nlohmann::json::value_t::string },
-        { "version",    nlohmann::json::value_t::string },
-        { "requires",   nlohmann::json::value_t::string }
-    });
-
-    return game{value["name"],
-                value["version"],
-                value["requires"],
-                value.count("license") > 0 ? value["license"] : "",
-                value.count("author") > 0 ? value["author"] : ""};
-}
-
-} // !mlk
--- a/libcommon/malikania/resources_loader.hpp	Sun Jan 22 09:59:14 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * resources_loader.hpp -- load shared resources files
- *
- * Copyright (c) 2013-2017 Malikania Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef MALIKANIA_RESOURCES_LOADER_HPP
-#define MALIKANIA_RESOURCES_LOADER_HPP
-
-#include <string>
-#include <unordered_map>
-
-#include <json.hpp>
-
-#include "resources_locator.hpp"
-
-namespace mlk {
-
-class game;
-
-/**
- * \brief Open resources files using a resources_locator.
- *
- * This class is used to load resources files that are common to the server and
- * the client.
- *
- * \see client_resources_loader
- */
-class resources_loader {
-private:
-    resources_locator& m_locator;
-
-protected:
-    /**
-     * Check that an object has the specified properties of the given type.
-     *
-     * Throws an error when any of the property is missing or not the correct
-     * type.
-     *
-     * You can use this function when you have lot of properties to extract,
-     * otherwise, you can use one of the require* or get* functions to avoid
-     * performances overhead.
-     *
-     * \pre object.is_object()
-     * \param id the resource id
-     * \param object the object
-     * \param props the properties
-     * \throw std::runtime_error when a property is missing / invalid
-     */
-    void requires(const std::string& id,
-                  const nlohmann::json& object,
-                  const std::unordered_map<std::string, nlohmann::json::value_t>& props) const;
-
-    /**
-     * Require a string.
-     *
-     * \pre object.isObject()
-     * \param id the resource id
-     * \param object the object
-     * \param property the property
-     * \return the string
-     * \throw std::runtime_error if the property is not a string or missing
-     */
-    std::string require_string(const std::string& id,
-                               const nlohmann::json& object,
-                               const std::string& property) const;
-
-public:
-    /**
-     * Construct the resources loader.
-     *
-     * \param locator the locator
-     */
-    resources_loader(resources_locator& locator);
-
-    /**
-     * Virtual destructor defaulted.
-     */
-    virtual ~resources_loader() noexcept = default;
-
-    /**
-     * Get the underlying locator.
-     *
-     * \return the locator
-     */
-    inline resources_locator& locator() noexcept
-    {
-        return m_locator;
-    }
-
-    /**
-     * Load a game.
-     *
-     * \return the game
-     * \throw std::runtime_error on errors
-     */
-    virtual game load_game() const;
-};
-
-} // !mlk
-
-#endif // !MALIKANIA_RESOURCES_LOADER_HPP
--- a/libcommon/malikania/resources_locator.cpp	Sun Jan 22 09:59:14 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * resources_locator.cpp -- file and stream loader
- *
- * Copyright (c) 2013-2017 Malikania Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cerrno>
-#include <cstring>
-#include <fstream>
-#include <iterator>
-#include <stdexcept>
-
-#include "resources_locator.hpp"
-
-namespace mlk {
-
-directory_resources_locator::directory_resources_locator(std::string path) noexcept
-    : m_path(std::move(path))
-{
-}
-
-std::string directory_resources_locator::read(const std::string &id)
-{
-    std::ifstream in(m_path + "/" + id, std::ifstream::in | std::ifstream::binary);
-
-    if (!in) {
-        throw std::runtime_error(std::strerror(errno));
-    }
-
-    return std::string(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>());
-}
-
-std::unique_ptr<std::istream> directory_resources_locator::open(const std::string &id)
-{
-    auto ptr = std::make_unique<std::ifstream>(m_path + "/" + id);
-
-    if (!(*ptr)) {
-        throw std::runtime_error(std::strerror(errno));
-    }
-
-    return std::move(ptr);
-}
-
-} // !mlk
--- a/libcommon/malikania/resources_locator.hpp	Sun Jan 22 09:59:14 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * resources_locator.hpp -- file and stream loader
- *
- * Copyright (c) 2013-2017 Malikania Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef MALIKANIA_RESOURCES_LOCATOR_HPP
-#define MALIKANIA_RESOURCES_LOCATOR_HPP
-
-#include <string>
-#include <memory>
-#include <istream>
-
-namespace mlk {
-
-/**
- * \brief Abstract assets locator.
- */
-class resources_locator {
-public:
-    /**
-     * Default destructor.
-     */
-    virtual ~resources_locator() = default;
-
-    /**
-     * Read a whole resource as a string.
-     *
-     * \param id the resource id
-     * \return the string
-     * \throw std::runtime_error on any errors
-     */
-    virtual std::string read(const std::string& id) = 0;
-
-    /**
-     * Open a resource as a stream.
-     *
-     * \param id the resource id
-     * \return the stream
-     * \throw std::runtime_error on any errors
-     */
-    virtual std::unique_ptr<std::istream> open(const std::string& id) = 0;
-};
-
-/**
- * \brief Load a game from a directory.
- */
-class directory_resources_locator : public resources_locator {
-private:
-    std::string m_path;
-
-public:
-    /**
-     * Load the game from the directory.
-     *
-     * \param path the base directory
-     */
-    directory_resources_locator(std::string path) noexcept;
-
-    /**
-     * \copydoc resources_locator::read
-     */
-    std::string read(const std::string& id) override;
-
-    /**
-     * \copydoc resources_locator::open
-     */
-    std::unique_ptr<std::istream> open(const std::string& id) override;
-};
-
-} // !mlk
-
-#endif // !MALIKANIA_RESOURCES_LOCATOR_HPP