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

This commit is contained in:
Michele Caini
2019-12-03 09:10:21 +01:00
parent b8784863f2
commit c7b8e82ada
5 changed files with 97 additions and 72 deletions

View File

@@ -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>>...> {};

View File

@@ -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()

View File

@@ -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};
}
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_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_deinit() {
entt::meta<char>().reset();
entt::meta<int>().reset();
ENTT_EXPORT void meta_tear_down() {
entt::meta<position>().reset();
entt::meta<velocity>().reset();
}
ENTT_EXPORT entt::meta_any wrap_int(int value) {
return value;
}

View File

@@ -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));
ASSERT_FALSE(entt::resolve("position"_hs));
bind_ctx(entt::meta_ctx{});
entt::meta<double>().type("double"_hs).conv<int>();
meta_init();
meta_set_up();
entt::meta<double>().conv<int>();
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));
ASSERT_TRUE(entt::resolve("position"_hs));
meta_deinit();
entt::meta<double>().reset();
auto pos = entt::resolve("position"_hs).construct(42., 3.);
auto vel = entt::resolve<velocity>().ctor().invoke();
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_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();
}

View File

@@ -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