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

This commit is contained in:
Michele Caini
2019-12-04 00:09:31 +01:00
parent 882b91b221
commit 231036784d
10 changed files with 52 additions and 37 deletions

1
TODO
View File

@@ -39,6 +39,7 @@
* 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)
* sparse set: there exists an alternative to paginated sparse arrays?
* see warning (vs2017 only): d:\a\entt\entt\src\entt\entity\registry.hpp(108)
* Mission: get rid of named types
- make it possible to use custom generators (eg for plugins)

View File

@@ -30,8 +30,14 @@ struct ENTT_API generator {
*/
template<typename Type, typename... Generator>
struct ENTT_API family {
/*! @brief Statically generated unique identifier for the given type. */
inline static const ENTT_ID_TYPE type = generator<Generator...>::next();
/**
* @brief Statically generated unique identifier for a given type.
* @return The runtime unique identifier for the given type.
*/
static ENTT_ID_TYPE type() ENTT_NOEXCEPT {
static const ENTT_ID_TYPE value = generator<Generator...>::next();
return value;
}
};

View File

@@ -275,7 +275,7 @@ public:
*/
template<typename Component>
static component type() ENTT_NOEXCEPT {
return component{component_family<std::decay_t<Component>>::type};
return component{component_family<std::decay_t<Component>>::type()};
}
/**
@@ -1630,7 +1630,7 @@ public:
*/
template<typename Type, typename... Args>
Type & set(Args &&... args) {
const auto vtype = context_family<std::decay_t<Type>>::type;
const auto vtype = context_family<std::decay_t<Type>>::type();
if(!(vtype < vars.size())) {
vars.resize(vtype+1);
@@ -1646,7 +1646,7 @@ public:
*/
template<typename Type>
void unset() {
if(const auto vtype = context_family<std::decay_t<Type>>::type; vtype < vars.size()) {
if(const auto vtype = context_family<std::decay_t<Type>>::type(); vtype < vars.size()) {
vars[vtype].reset();
}
}
@@ -1676,7 +1676,7 @@ public:
*/
template<typename Type>
const Type * try_ctx() const {
const auto vtype = context_family<std::decay_t<Type>>::type;
const auto vtype = context_family<std::decay_t<Type>>::type();
return vtype < vars.size() && vars[vtype] ? &static_cast<variable_handler<Type> &>(*vars[vtype]).value : nullptr;
}

View File

@@ -31,8 +31,10 @@ namespace entt {
* crashes.
*/
class dispatcher {
struct ENTT_API dispatcher_event_family;
template<typename Type>
using event_family = family<Type, struct ENTT_API internal_dispatcher_event_family>;
using event_family = family<Type, dispatcher_event_family>;
struct basic_pool {
virtual ~basic_pool() = default;
@@ -80,7 +82,7 @@ class dispatcher {
template<typename Event>
pool_handler<Event> & assure() {
const auto etype = event_family<Event>::type;
const auto etype = event_family<Event>::type();
if(!(etype < pools.size())) {
pools.resize(etype+1);

View File

@@ -118,7 +118,7 @@ class emitter {
template<typename Event>
const pool_handler<Event> & assure() const {
const auto etype = event_family<std::decay_t<Event>>::type;
const auto etype = event_family<std::decay_t<Event>>::type();
if(!(etype < pools.size())) {
pools.resize(etype+1);

View File

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

View File

@@ -8,10 +8,10 @@ template<typename Type>
using another_family = entt::family<Type, struct another_family_type>;
TEST(Family, Functionalities) {
auto t1 = a_family<int>::type;
auto t2 = a_family<int>::type;
auto t3 = a_family<char>::type;
auto t4 = another_family<double>::type;
auto t1 = a_family<int>::type();
auto t2 = a_family<int>::type();
auto t3 = a_family<char>::type();
auto t4 = another_family<double>::type();
ASSERT_EQ(t1, t2);
ASSERT_NE(t1, t3);
@@ -19,7 +19,7 @@ TEST(Family, Functionalities) {
}
TEST(Family, Uniqueness) {
ASSERT_NE(a_family<int>::type, a_family<int &>::type);
ASSERT_NE(a_family<int>::type, a_family<int &&>::type);
ASSERT_NE(a_family<int>::type, a_family<const int &>::type);
ASSERT_NE(a_family<int>::type(), a_family<int &>::type());
ASSERT_NE(a_family<int>::type(), a_family<int &&>::type());
ASSERT_NE(a_family<int>::type(), a_family<const int &>::type());
}

View File

@@ -1,16 +1,11 @@
#define ENTT_API_EXPORT
#include <entt/lib/attribute.h>
#include <entt/signal/dispatcher.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
template struct entt::family<event, entt::dispatcher::dispatcher_event_family>;
LIB_EXPORT void trigger_event(int value, entt::dispatcher &dispatcher) {
dispatcher.trigger<event>(value);
ENTT_EXPORT void trigger(int value, entt::dispatcher &dispatcher) {
dispatcher.trigger<message>(value);
}

View File

@@ -1,12 +1,16 @@
#define ENTT_API_IMPORT
#include <gtest/gtest.h>
#include <entt/core/utility.hpp>
#include <entt/lib/attribute.h>
#include <entt/signal/dispatcher.hpp>
#include "types.h"
extern void trigger_event(int, entt::dispatcher &);
ENTT_API void trigger(int, entt::dispatcher &);
struct listener {
void on_int(int) { FAIL(); }
void on_event(event ev) { value = ev.payload; }
void on(event) { FAIL(); }
void on(message msg) { value = msg.payload; }
int value{};
};
@@ -14,9 +18,9 @@ TEST(Lib, Dispatcher) {
entt::dispatcher dispatcher;
listener listener;
dispatcher.sink<int>().connect<&listener::on_int>(listener);
dispatcher.sink<event>().connect<&listener::on_event>(listener);
trigger_event(42, dispatcher);
dispatcher.sink<event>().connect<entt::overload<void(event)>(&listener::on)>(listener);
dispatcher.sink<message>().connect<entt::overload<void(message)>(&listener::on)>(listener);
trigger(42, dispatcher);
ASSERT_EQ(listener.value, 42);
}

View File

@@ -1,5 +1,12 @@
#include <entt/core/type_traits.hpp>
#ifndef ENTT_LIB_DISPATCHER_TYPES_H
#define ENTT_LIB_DISPATCHER_TYPES_H
ENTT_NAMED_STRUCT(event, {
#include <entt/lib/attribute.h>
struct ENTT_API event {};
struct ENTT_API message {
int payload;
});
};
#endif // ENTT_LIB_DISPATCHER_TYPES_H