Browse Source

aob: removed mod stuff

Michele Caini 6 years ago
parent
commit
8aacd4d022
6 changed files with 27 additions and 499 deletions
  1. 0 1
      CMakeLists.txt
  2. 0 1
      TODO
  3. 0 20
      cmake/in/duktape.in
  4. 27 52
      docs/md/entity.md
  5. 0 16
      test/CMakeLists.txt
  6. 0 409
      test/mod/mod.cpp

+ 0 - 1
CMakeLists.txt

@@ -160,7 +160,6 @@ if(BUILD_TESTING)
 
     option(BUILD_BENCHMARK "Build benchmark." OFF)
     option(BUILD_LIB "Build lib example." OFF)
-    option(BUILD_MOD "Build mod example." OFF)
     option(BUILD_SNAPSHOT "Build snapshot example." OFF)
 
     enable_testing()

+ 0 - 1
TODO

@@ -17,5 +17,4 @@
 * observer: user defined filters (eg .replace<T, &function> or .group<T, U, &func>)
 * any-of rule for views/groups (eg entity has A and any of B/C/D)
   - get -> all, exclude -> none
-* remove duktape example (and eventually provide a new one)?
 * extract only the type within type_info, hash its name (more portable)

+ 0 - 20
cmake/in/duktape.in

@@ -1,20 +0,0 @@
-project(duktape-download NONE)
-cmake_minimum_required(VERSION 3.2)
-
-include(ExternalProject)
-
-ExternalProject_Add(
-    duktape
-    GIT_REPOSITORY https://github.com/svaarala/duktape-releases.git
-    GIT_TAG v2.2.0
-    GIT_SHALLOW 1
-    DOWNLOAD_DIR ${DUKTAPE_DEPS_DIR}
-    TMP_DIR ${DUKTAPE_DEPS_DIR}/tmp
-    STAMP_DIR ${DUKTAPE_DEPS_DIR}/stamp
-    SOURCE_DIR ${DUKTAPE_DEPS_DIR}/src
-    BINARY_DIR ${DUKTAPE_DEPS_DIR}/build
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND ""
-    INSTALL_COMMAND ""
-    TEST_COMMAND ""
-)

+ 27 - 52
docs/md/entity.md

@@ -15,8 +15,6 @@
 * [The Registry, the Entity and the Component](#the-registry-the-entity-and-the-component)
   * [Observe changes](#observe-changes)
     * [They call me Reactive System](#they-call-me-reactive-system)
-  * [Runtime components](#runtime-components)
-    * [A journey through a plugin](#a-journey-through-a-plugin)
   * [Sorting: is it possible?](#sorting-is-it-possible)
   * [Helpers](#helpers)
     * [Null entity](#null-entity)
@@ -30,6 +28,7 @@
     * [Continuous loader](#continuous-loader)
     * [Archives](#archives)
     * [One example to rule them all](#one-example-to-rule-them-all)
+  * [Runtime components](#runtime-components)
 * [Views and Groups](#views-and-groups)
   * [Views](#views)
   * [Runtime views](#runtime-views)
@@ -551,54 +550,6 @@ multiple elements in the exclusion list. Moreover, every matcher can have it's
 own clause and multiple clauses for the same matcher are combined in a single
 one.
 
-## Runtime components
-
-Defining components at runtime is useful to support plugin systems and mods in
-general. However, it seems impossible with a tool designed around a bunch of
-templates. Indeed it's not that difficult.<br/>
-Of course, some features cannot be easily exported into a runtime
-environment. As an example, sorting a group of components defined at runtime
-isn't for free if compared to most of the other operations. However, the basic
-functionalities of an entity-component system such as `EnTT` fit the problem
-perfectly and can also be used to manage runtime components if required.<br/>
-All that is necessary to do it is to know the identifiers of the components. An
-identifier is nothing more than a number or similar that can be used at runtime
-to work with the type system.
-
-In `EnTT`, identifiers are easily accessible:
-
-```cpp
-entt::registry registry;
-
-// component identifier
-auto type = registry.type<position>();
-```
-
-Once the identifiers are made available, almost everything becomes pretty
-simple.
-
-### A journey through a plugin
-
-`EnTT` comes with an example (actually a test) that shows how to integrate
-compile-time and runtime components in a stack based JavaScript environment. It
-uses [`Duktape`](https://github.com/svaarala/duktape) under the hood, mainly
-because I wanted to learn how it works at the time I was writing the code.
-
-The code is not production-ready and overall performance can be highly improved.
-However, I sacrificed optimizations in favor of a more readable piece of code. I
-hope I succeeded.<br/>
-Note also that this isn't neither the only nor (probably) the best way to do it.
-In fact, the right way depends on the scripting language and the problem one is
-facing in general.<br/>
-That being said, feel free to use it at your own risk.
-
-The basic idea is that of creating a compile-time component aimed to map all the
-runtime components assigned to an entity.<br/>
-Identifiers come in use to address the right function from a map when invoked
-from the runtime environment and to filter entities when iterating.<br/>
-With a bit of gymnastic, one can narrow views and improve the performance to
-some extent but it was not the goal of the example.
-
 ## Sorting: is it possible?
 
 It goes without saying that sorting entities and components is possible with
@@ -1035,6 +986,30 @@ the best way to do it. However, feel free to use it at your own risk.
 The basic idea is to store everything in a group of queues in memory, then bring
 everything back to the registry with different loaders.
 
+## Runtime components
+
+Defining components at runtime is useful to support plugin systems and mods in
+general. However, it seems impossible with a tool designed around a bunch of
+templates. Indeed it's not that difficult.<br/>
+Of course, some features cannot be easily exported into a runtime environment.
+As an example, sorting a group of components defined at runtime isn't for free
+if compared to most of the other operations. However, the basic functionalities
+of an entity-component system such as `EnTT` fit the problem perfectly and can
+also be used to manage runtime components if required.<br/>
+All that is necessary to do it is to know the identifiers of the components. An
+identifier is nothing more than a number or similar that can be used at runtime
+to work with the type system.
+
+In `EnTT`, identifiers are easily accessible:
+
+```cpp
+// component identifier
+const auto type = entt::type_info<position>::id();
+```
+
+Once the identifiers are made available, almost everything becomes pretty
+simple.
+
 # Views and Groups
 
 First of all, it is worth answering an obvious question: why views and
@@ -1192,7 +1167,7 @@ thrown away. The reasons for this go far beyond the scope of this document.<br/>
 To iterate a runtime view, either use it in a range-for loop:
 
 ```cpp
-entt::component types[] = { registry.type<position>(), registry.type<velocity>() };
+entt::component types[] = { entt::type_info<position>::id(), entt::type_info<velocity>::id() };
 auto view = registry.runtime_view(std::cbegin(types), std::cend(types));
 
 for(auto entity: view) {
@@ -1210,7 +1185,7 @@ for(auto entity: view) {
 Or rely on the `each` member function to iterate entities:
 
 ```cpp
-entt::component types[] = { registry.type<position>(), registry.type<velocity>() };
+entt::component types[] = { entt::type_info<position>::id(), entt::type_info<velocity>::id() };
 
 registry.runtime_view(std::cbegin(types), std::cend(types)).each([](auto entity) {
     // ...

+ 0 - 16
test/CMakeLists.txt

@@ -102,22 +102,6 @@ if(BUILD_LIB)
     SETUP_PLUGIN_TEST(registry_plugin_std ENTT_STANDARD_CPP)
 endif()
 
-# Test mod
-
-if(BUILD_MOD)
-    enable_language(C)
-
-    set(DUKTAPE_DEPS_DIR ${EnTT_SOURCE_DIR}/deps/duktape)
-    configure_file(${EnTT_SOURCE_DIR}/cmake/in/duktape.in ${DUKTAPE_DEPS_DIR}/CMakeLists.txt)
-    execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . WORKING_DIRECTORY ${DUKTAPE_DEPS_DIR})
-    execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${DUKTAPE_DEPS_DIR})
-    set(DUKTAPE_SRC_DIR ${DUKTAPE_DEPS_DIR}/src/src)
-
-    set(MOD_TEST_SOURCE ${DUKTAPE_SRC_DIR}/duktape.c mod/mod.cpp)
-    SETUP_BASIC_TEST(mod "${MOD_TEST_SOURCE}")
-    target_include_directories(mod PRIVATE ${DUKTAPE_SRC_DIR})
-endif()
-
 # Test snapshot
 
 if(BUILD_SNAPSHOT)

+ 0 - 409
test/mod/mod.cpp

@@ -1,409 +0,0 @@
-#include <type_traits>
-#include <cassert>
-#include <map>
-#include <string>
-#include <duktape.h>
-#include <gtest/gtest.h>
-#include <entt/core/type_info.hpp>
-#include <entt/entity/registry.hpp>
-
-template<typename Type>
-struct tag { using type = Type; };
-
-struct position {
-    double x;
-    double y;
-};
-
-struct renderable {};
-
-struct duktape_runtime {
-    std::map<duk_uint_t, std::string> components;
-};
-
-template<typename Comp>
-duk_ret_t set(duk_context *ctx, entt::registry &registry) {
-    const entt::entity entity{duk_require_uint(ctx, 0)};
-
-    if constexpr(std::is_same_v<Comp, position>) {
-        const auto x = duk_require_number(ctx, 2);
-        const auto y = duk_require_number(ctx, 3);
-        registry.assign_or_replace<position>(entity, x, y);
-    } else if constexpr(std::is_same_v<Comp, duktape_runtime>) {
-        const auto type = duk_require_uint(ctx, 1);
-
-        duk_dup(ctx, 2);
-
-        if(!registry.has<duktape_runtime>(entity)) {
-            registry.assign<duktape_runtime>(entity).components[type] = duk_json_encode(ctx, -1);
-        } else {
-            registry.get<duktape_runtime>(entity).components[type] = duk_json_encode(ctx, -1);
-        }
-
-        duk_pop(ctx);
-    } else {
-        registry.assign_or_replace<Comp>(entity);
-    }
-
-    return 0;
-}
-
-template<typename Comp>
-duk_ret_t unset(duk_context *ctx, entt::registry &registry) {
-    const entt::entity entity{duk_require_uint(ctx, 0)};
-
-    if constexpr(std::is_same_v<Comp, duktape_runtime>) {
-        const auto type = duk_require_uint(ctx, 1);
-
-        auto &components = registry.get<duktape_runtime>(entity).components;
-        assert(components.find(type) != components.cend());
-        components.erase(type);
-
-        if(components.empty()) {
-            registry.remove<duktape_runtime>(entity);
-        }
-    } else {
-        registry.remove<Comp>(entity);
-    }
-
-    return 0;
-}
-
-template<typename Comp>
-duk_ret_t has(duk_context *ctx, entt::registry &registry) {
-    const entt::entity entity{duk_require_uint(ctx, 0)};
-
-    if constexpr(std::is_same_v<Comp, duktape_runtime>) {
-        duk_push_boolean(ctx, registry.has<duktape_runtime>(entity));
-
-        if(registry.has<duktape_runtime>(entity)) {
-            const auto type = duk_require_uint(ctx, 1);
-            const auto &components = registry.get<duktape_runtime>(entity).components;
-            duk_push_boolean(ctx, components.find(type) != components.cend());
-        } else {
-            duk_push_false(ctx);
-        }
-    } else {
-        duk_push_boolean(ctx, registry.has<Comp>(entity));
-    }
-
-    return 1;
-}
-
-template<typename Comp>
-duk_ret_t get(duk_context *ctx, entt::registry &registry) {
-    [[maybe_unused]] const entt::entity entity{duk_require_uint(ctx, 0)};
-
-    if constexpr(std::is_same_v<Comp, position>) {
-        const auto &pos = registry.get<position>(entity);
-
-        const auto idx = duk_push_object(ctx);
-
-        duk_push_string(ctx, "x");
-        duk_push_number(ctx, pos.x);
-        duk_def_prop(ctx, idx, DUK_DEFPROP_HAVE_VALUE);
-
-        duk_push_string(ctx, "y");
-        duk_push_number(ctx, pos.y);
-        duk_def_prop(ctx, idx, DUK_DEFPROP_HAVE_VALUE);
-    } if constexpr(std::is_same_v<Comp, duktape_runtime>) {
-        const auto type = duk_require_uint(ctx, 1);
-
-        auto &runtime = registry.get<duktape_runtime>(entity);
-        assert(runtime.components.find(type) != runtime.components.cend());
-
-        duk_push_string(ctx, runtime.components[type].c_str());
-        duk_json_decode(ctx, -1);
-    } else {
-        assert(registry.has<Comp>(entity));
-        duk_push_object(ctx);
-    }
-
-    return 1;
-}
-
-class duktape_registry {
-    struct func_map {
-        using func_type = duk_ret_t(*)(duk_context *, entt::registry &);
-
-        func_type set;
-        func_type unset;
-        func_type has;
-        func_type get;
-    };
-
-    template<typename... Comp>
-    void reg() {
-        ((func[entt::type_info<Comp>::id()] = {
-                &::set<Comp>,
-                &::unset<Comp>,
-                &::has<Comp>,
-                &::get<Comp>
-        }), ...);
-    }
-
-    static duktape_registry & instance(duk_context *ctx) {
-        duk_push_this(ctx);
-
-        duk_push_string(ctx, DUK_HIDDEN_SYMBOL("dreg"));
-        duk_get_prop(ctx, -2);
-        auto &dreg = *static_cast<duktape_registry *>(duk_require_pointer(ctx, -1));
-        duk_pop_2(ctx);
-
-        return dreg;
-    }
-
-    template<func_map::func_type func_map::*Op>
-    static duk_ret_t invoke(duk_context *ctx) {
-        auto &dreg = instance(ctx);
-        auto &func = dreg.func;
-        auto &registry = dreg.registry;
-        auto type = duk_require_uint(ctx, 1);
-
-        const auto it = func.find(type);
-
-        return (it == func.cend())
-                ? (func[entt::type_info<duktape_runtime>::id()].*Op)(ctx, registry)
-                : (it->second.*Op)(ctx, registry);
-    }
-
-public:
-    duktape_registry(entt::registry &ref)
-        : registry{ref}
-    {
-        reg<position, renderable, duktape_runtime>();
-    }
-
-    static duk_ret_t identifier(duk_context *ctx) {
-        static ENTT_ID_TYPE next{1000u};
-        duk_push_uint(ctx, next++);
-        return 1;
-    }
-
-    static duk_ret_t create(duk_context *ctx) {
-        auto &dreg = instance(ctx);
-        const auto entity = dreg.registry.create();
-        duk_push_uint(ctx, static_cast<std::underlying_type_t<entt::entity>>(entity));
-        return 1;
-    }
-
-    static duk_ret_t set(duk_context *ctx) {
-        return invoke<&func_map::set>(ctx);
-    }
-
-    static duk_ret_t unset(duk_context *ctx) {
-        return invoke<&func_map::unset>(ctx);
-    }
-
-    static duk_ret_t has(duk_context *ctx) {
-        return invoke<&func_map::has>(ctx);
-    }
-
-    static duk_ret_t get(duk_context *ctx) {
-        return invoke<&func_map::get>(ctx);
-    }
-
-    static duk_ret_t entities(duk_context *ctx) {
-        const duk_idx_t nargs = duk_get_top(ctx);
-        auto &dreg = instance(ctx);
-
-        duk_push_array(ctx);
-
-        std::vector<ENTT_ID_TYPE> components;
-        std::vector<ENTT_ID_TYPE> runtime;
-
-        for(duk_idx_t arg = 0; arg < nargs; arg++) {
-            auto type = duk_require_uint(ctx, arg);
-
-            if(dreg.func.find(type) == dreg.func.cend()) {
-                if(runtime.empty()) {
-                    components.push_back(entt::type_info<duktape_runtime>::id());
-                }
-
-                runtime.push_back(type);
-            } else {
-                components.push_back(type);
-            }
-        }
-
-        auto view = dreg.registry.runtime_view(components.cbegin(), components.cend());
-        duk_uarridx_t pos = 0;
-
-        for(const auto entity: view) {
-            if(runtime.empty()) {
-                duk_push_uint(ctx, static_cast<std::underlying_type_t<entt::entity>>(entity));
-                duk_put_prop_index(ctx, -2, pos++);
-            } else {
-                const auto &others = dreg.registry.get<duktape_runtime>(entity).components;
-                const auto match = std::all_of(runtime.cbegin(), runtime.cend(), [&others](const auto type) {
-                    return others.find(type) != others.cend();
-                });
-
-                if(match) {
-                    duk_push_uint(ctx, static_cast<std::underlying_type_t<entt::entity>>(entity));
-                    duk_put_prop_index(ctx, -2, pos++);
-                }
-            }
-        }
-
-        return 1;
-    }
-
-private:
-    std::map<duk_uint_t, func_map> func;
-    entt::registry &registry;
-};
-
-const duk_function_list_entry js_duktape_registry_methods[] = {
-    { "identifier", &duktape_registry::identifier, 0 },
-    { "create", &duktape_registry::create, 0 },
-    { "set", &duktape_registry::set, DUK_VARARGS },
-    { "unset", &duktape_registry::unset, 2 },
-    { "has", &duktape_registry::has, 2 },
-    { "get", &duktape_registry::get, 2 },
-    { "entities", &duktape_registry::entities, DUK_VARARGS },
-    { nullptr, nullptr, 0 }
-};
-
-void export_types(duk_context *context) {
-    auto export_type = [idx = duk_push_object(context)](auto *ctx, auto type, const auto *name) {
-        duk_push_string(ctx, name);
-        duk_push_uint(ctx, entt::type_info<typename decltype(type)::type>::id());
-        duk_def_prop(ctx, idx, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_CLEAR_WRITABLE);
-    };
-
-    export_type(context, tag<position>{}, "position");
-    export_type(context, tag<renderable>{}, "renderable");
-
-    duk_put_global_string(context, "Types");
-}
-
-void export_duktape_registry(duk_context *ctx, duktape_registry &dreg) {
-    auto idx = duk_push_object(ctx);
-
-    duk_push_string(ctx, DUK_HIDDEN_SYMBOL("dreg"));
-    duk_push_pointer(ctx, &dreg);
-    duk_put_prop(ctx, idx);
-
-    duk_put_function_list(ctx, idx, js_duktape_registry_methods);
-    duk_put_global_string(ctx, "Registry");
-}
-
-TEST(Mod, Duktape) {
-    entt::registry registry;
-    duktape_registry dreg{registry};
-    duk_context *ctx = duk_create_heap_default();
-
-    if(!ctx) {
-        FAIL();
-    }
-
-    export_types(ctx);
-    export_duktape_registry(ctx, dreg);
-
-    const char *s0 = ""
-            "Types[\"PLAYING_CHARACTER\"] = Registry.identifier();"
-            "Types[\"VELOCITY\"] = Registry.identifier();"
-            "";
-
-    if(duk_peval_string(ctx, s0)) {
-        FAIL();
-    }
-
-    const auto e0 = registry.create();
-    registry.assign<position>(e0, 0., 0.);
-    registry.assign<renderable>(e0);
-
-    const auto e1 = registry.create();
-    registry.assign<position>(e1, 0., 0.);
-
-    const char *s1 = ""
-            "Registry.entities(Types.position, Types.renderable).forEach(function(entity) {"
-                "Registry.set(entity, Types.position, 100., 100.);"
-            "});"
-            "var entity = Registry.create();"
-            "Registry.set(entity, Types.position, 100., 100.);"
-            "Registry.set(entity, Types.renderable);"
-            "";
-
-    if(duk_peval_string(ctx, s1)) {
-        FAIL();
-    }
-
-    ASSERT_EQ(registry.view<duktape_runtime>().size(), 0u);
-    ASSERT_EQ(registry.view<position>().size(), 3u);
-    ASSERT_EQ(registry.view<renderable>().size(), 2u);
-
-    registry.view<position>().each([&registry](auto entity, const auto &position) {
-        ASSERT_FALSE(registry.has<duktape_runtime>(entity));
-
-        if(registry.has<renderable>(entity)) {
-            ASSERT_EQ(position.x, 100.);
-            ASSERT_EQ(position.y, 100.);
-        } else {
-            ASSERT_EQ(position.x, 0.);
-            ASSERT_EQ(position.y, 0.);
-        }
-    });
-
-    const char *s2 = ""
-            "Registry.entities(Types.position).forEach(function(entity) {"
-                "if(!Registry.has(entity, Types.renderable)) {"
-                    "Registry.set(entity, Types.VELOCITY, { \"dx\": -100., \"dy\": -100. });"
-                    "Registry.set(entity, Types.PLAYING_CHARACTER, {});"
-                "}"
-            "});"
-            "";
-
-    if(duk_peval_string(ctx, s2)) {
-        FAIL();
-    }
-
-    ASSERT_EQ(registry.view<duktape_runtime>().size(), 1u);
-    ASSERT_EQ(registry.view<position>().size(), 3u);
-    ASSERT_EQ(registry.view<renderable>().size(), 2u);
-
-    registry.view<duktape_runtime>().each([](const duktape_runtime &runtime) {
-        ASSERT_EQ(runtime.components.size(), 2u);
-    });
-
-    const char *s3 = ""
-            "Registry.entities(Types.position, Types.renderable, Types.VELOCITY, Types.PLAYING_CHARACTER).forEach(function(entity) {"
-                "var velocity = Registry.get(entity, Types.VELOCITY);"
-                "Registry.set(entity, Types.position, velocity.dx, velocity.dy)"
-            "});"
-            "";
-
-    if(duk_peval_string(ctx, s3)) {
-        FAIL();
-    }
-
-    ASSERT_EQ(registry.view<duktape_runtime>().size(), 1u);
-    ASSERT_EQ(registry.view<position>().size(), 3u);
-    ASSERT_EQ(registry.view<renderable>().size(), 2u);
-
-    registry.view<position, renderable, duktape_runtime>().each([](const position &position, auto &&...) {
-        ASSERT_EQ(position.x, -100.);
-        ASSERT_EQ(position.y, -100.);
-    });
-
-    const char *s4 = ""
-            "Registry.entities(Types.VELOCITY, Types.PLAYING_CHARACTER).forEach(function(entity) {"
-                "Registry.unset(entity, Types.VELOCITY);"
-                "Registry.unset(entity, Types.PLAYING_CHARACTER);"
-            "});"
-            "Registry.entities(Types.position).forEach(function(entity) {"
-                "Registry.unset(entity, Types.position);"
-            "});"
-            "";
-
-    if(duk_peval_string(ctx, s4)) {
-        FAIL();
-    }
-
-    ASSERT_EQ(registry.view<duktape_runtime>().size(), 0u);
-    ASSERT_EQ(registry.view<position>().size(), 0u);
-    ASSERT_EQ(registry.view<renderable>().size(), 2u);
-
-    duk_destroy_heap(ctx);
-}