meta: (almost) transparent dll/.so support with ENTT_API
This commit is contained in:
@@ -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>>...> {};
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user