ソースを参照

meta: (almost) transparent dll/.so support with ENTT_API

Michele Caini 6 年 前
コミット
c7b8e82ada
5 ファイル変更101 行追加76 行削除
  1. 25 28
      src/entt/meta/meta.hpp
  2. 1 1
      test/CMakeLists.txt
  3. 25 17
      test/lib/meta/lib.cpp
  4. 32 27
      test/lib/meta/main.cpp
  5. 18 3
      test/lib/meta/types.h

+ 25 - 28
src/entt/meta/meta.hpp

@@ -8,6 +8,7 @@
 #include <type_traits>
 #include "../config/config.h"
 #include "../core/type_traits.hpp"
+#include "../lib/attribute.h"
 
 
 namespace entt {
@@ -188,43 +189,33 @@ bool compare(const void *lhs, const void *rhs) {
 }
 
 
-template<typename...>
-struct meta_node;
-
-
-template<>
-struct meta_node<> {
-    inline static meta_type_node *node = nullptr;
-};
-
-
-template<typename Type>
-struct meta_node<Type> {
-    static_assert(std::is_same_v<Type, std::remove_cv_t<std::remove_reference_t<Type>>>);
+template<typename... Type>
+struct ENTT_API meta_node {
+    static_assert(std::is_same_v<Type..., std::remove_cv_t<std::remove_reference_t<Type>>...>);
 
     static meta_type_node * resolve() ENTT_NOEXCEPT {
         static meta_type_node node{
             {},
             nullptr,
             nullptr,
-            std::is_void_v<Type>,
-            std::is_integral_v<Type>,
-            std::is_floating_point_v<Type>,
-            std::is_array_v<Type>,
-            std::is_enum_v<Type>,
-            std::is_union_v<Type>,
-            std::is_class_v<Type>,
-            std::is_pointer_v<Type>,
-            std::is_pointer_v<Type> && std::is_function_v<std::remove_pointer_t<Type>>,
-            std::is_member_object_pointer_v<Type>,
-            std::is_member_function_pointer_v<Type>,
-            std::extent_v<Type>,
-            &compare<Type>, // workaround for an issue with VS2017
+            std::is_void_v<Type...>,
+            std::is_integral_v<Type...>,
+            std::is_floating_point_v<Type...>,
+            std::is_array_v<Type...>,
+            std::is_enum_v<Type...>,
+            std::is_union_v<Type...>,
+            std::is_class_v<Type...>,
+            std::is_pointer_v<Type...>,
+            std::is_pointer_v<Type...> && std::is_function_v<std::remove_pointer_t<Type>...>,
+            std::is_member_object_pointer_v<Type...>,
+            std::is_member_function_pointer_v<Type...>,
+            std::extent_v<Type...>,
+            &compare<Type...>, // workaround for an issue with VS2017
             []() ENTT_NOEXCEPT -> meta_type_node * {
-                return meta_node<std::remove_const_t<std::remove_pointer_t<Type>>>::resolve();
+                return meta_node<std::remove_const_t<std::remove_pointer_t<Type>>...>::resolve();
             },
             []() ENTT_NOEXCEPT -> meta_type_node * {
-                return meta_node<std::remove_const_t<std::remove_extent_t<Type>>>::resolve();
+                return meta_node<std::remove_const_t<std::remove_extent_t<Type>>...>::resolve();
             }
         };
 
@@ -233,6 +224,12 @@ struct meta_node<Type> {
 };
 
 
+template<>
+struct ENTT_API meta_node<> {
+    inline static meta_type_node *node = nullptr;
+};
+
+
 template<typename... Type>
 struct meta_info: meta_node<std::remove_cv_t<std::remove_reference_t<Type>>...> {};
 

+ 1 - 1
test/CMakeLists.txt

@@ -46,7 +46,7 @@ endif()
 if(BUILD_LIB)
 #    SETUP_AND_ADD_LIB_TEST(dispatcher)
 #    SETUP_AND_ADD_LIB_TEST(emitter)
-#    SETUP_AND_ADD_LIB_TEST(meta)
+    SETUP_AND_ADD_LIB_TEST(meta)
 #    SETUP_AND_ADD_LIB_TEST(registry)
 endif()
 

+ 25 - 17
test/lib/meta/lib.cpp

@@ -1,26 +1,34 @@
+#define ENTT_API_EXPORT
+
+#include <entt/core/hashed_string.hpp>
+#include <entt/lib/attribute.h>
 #include <entt/meta/factory.hpp>
+#include <entt/meta/meta.hpp>
 #include "types.h"
 
-#ifndef LIB_EXPORT
-#if defined _WIN32 || defined __CYGWIN__
-#define LIB_EXPORT __declspec(dllexport)
-#elif defined __GNUC__
-#define LIB_EXPORT __attribute__((visibility("default")))
-#else
-#define LIB_EXPORT
-#endif
-#endif
 
-LIB_EXPORT void bind_ctx(entt::meta_ctx context) {
-    entt::meta_ctx::bind(context);
+position create_position(int x, int y) {
+    return position{x, y};
+}
+
+ENTT_EXPORT void meta_set_up() {
+    entt::meta<position>()
+            .type("position"_hs)
+            .ctor<&create_position>()
+            .data<&position::x>("x"_hs)
+            .data<&position::y>("y"_hs);
+
+    entt::meta<velocity>()
+            .ctor<>()
+            .data<&velocity::dx>("dx"_hs)
+            .data<&velocity::dy>("dy"_hs);
 }
 
-LIB_EXPORT void meta_init() {
-    entt::meta<char>().type().data<'c'>("c"_hs);
-    entt::meta<int>().type().data<0>("0"_hs);
+ENTT_EXPORT void meta_tear_down() {
+    entt::meta<position>().reset();
+    entt::meta<velocity>().reset();
 }
 
-LIB_EXPORT void meta_deinit() {
-    entt::meta<char>().reset();
-    entt::meta<int>().reset();
+ENTT_EXPORT entt::meta_any wrap_int(int value) {
+    return value;
 }

+ 32 - 27
test/lib/meta/main.cpp

@@ -1,34 +1,39 @@
+#define ENTT_API_IMPORT
+
 #include <gtest/gtest.h>
+#include <entt/lib/attribute.h>
 #include <entt/meta/factory.hpp>
+#include <entt/meta/meta.hpp>
 #include "types.h"
 
-extern void bind_ctx(entt::meta_ctx);
-extern void meta_init();
-extern void meta_deinit();
+ENTT_IMPORT void meta_set_up();
+ENTT_IMPORT void meta_tear_down();
+ENTT_IMPORT entt::meta_any wrap_int(int);
 
 TEST(Lib, Meta) {
-    ASSERT_FALSE(entt::resolve("double"_hs));
-    ASSERT_FALSE(entt::resolve("char"_hs));
-    ASSERT_FALSE(entt::resolve("int"_hs));
-    ASSERT_FALSE(entt::resolve<int>().data("0"_hs));
-    ASSERT_FALSE(entt::resolve<char>().data("c"_hs));
-
-    bind_ctx(entt::meta_ctx{});
-    entt::meta<double>().type("double"_hs).conv<int>();
-    meta_init();
-
-    ASSERT_TRUE(entt::resolve("double"_hs));
-    ASSERT_TRUE(entt::resolve("char"_hs));
-    ASSERT_TRUE(entt::resolve("int"_hs));
-    ASSERT_TRUE(entt::resolve<int>().data("0"_hs));
-    ASSERT_TRUE(entt::resolve<char>().data("c"_hs));
-
-    meta_deinit();
-    entt::meta<double>().reset();
-
-    ASSERT_FALSE(entt::resolve("double"_hs));
-    ASSERT_FALSE(entt::resolve("char"_hs));
-    ASSERT_FALSE(entt::resolve("int"_hs));
-    ASSERT_FALSE(entt::resolve<int>().data("0"_hs));
-    ASSERT_FALSE(entt::resolve<char>().data("c"_hs));
+    ASSERT_FALSE(entt::resolve("position"_hs));
+
+    meta_set_up();
+    entt::meta<double>().conv<int>();
+
+    ASSERT_TRUE(entt::resolve("position"_hs));
+
+    auto pos = entt::resolve("position"_hs).construct(42., 3.);
+    auto vel = entt::resolve<velocity>().ctor().invoke();
+
+    ASSERT_TRUE(pos && vel);
+
+    ASSERT_EQ(pos.type().data("x"_hs).type(), entt::resolve<int>());
+    ASSERT_TRUE(pos.type().data("y"_hs).get(*pos).try_cast<int>());
+    ASSERT_EQ(pos.type().data("x"_hs).get(*pos).cast<int>(), 42);
+    ASSERT_EQ(pos.type().data("y"_hs).get(*pos).cast<int>(), 3);
+
+    ASSERT_EQ(vel.type().data("dx"_hs).type(), entt::resolve<double>());
+    ASSERT_TRUE(vel.type().data("dy"_hs).get(*vel).convert<int>());
+    ASSERT_EQ(vel.type().data("dx"_hs).get(*vel).cast<double>(), 0.);
+    ASSERT_EQ(vel.type().data("dy"_hs).get(*vel).cast<double>(), 0.);
+
+    ASSERT_EQ(wrap_int(1).type(), entt::resolve<int>());
+
+    meta_tear_down();
 }

+ 18 - 3
test/lib/meta/types.h

@@ -1,4 +1,19 @@
-#include <entt/core/type_traits.hpp>
+#ifndef ENTT_LIB_META_TYPES_H
+#define ENTT_LIB_META_TYPES_H
 
-ENTT_NAMED_TYPE(int);
-ENTT_NAMED_TYPE(char);
+
+#include <entt/lib/attribute.h>
+
+
+struct ENTT_API position {
+    int x{};
+    int y{};
+};
+
+struct ENTT_API velocity {
+    double dx{};
+    double dy{};
+};
+
+
+#endif // ENTT_LIB_META_TYPES_H