dispatcher works across boundaries now
This commit is contained in:
1
TODO
1
TODO
@@ -23,6 +23,5 @@
|
||||
* cleanup - see https://github.com/skypjack/entt/commit/ad5cedc08c83e8cbcc8aaeac9634d44624ffe35a#commitcomment-32380903
|
||||
|
||||
==> can we do more for shared libraries? who knows... see #144
|
||||
* to be updated: dispatcher
|
||||
* to be updated: emitter
|
||||
* to be updated: doc
|
||||
|
||||
@@ -159,9 +159,9 @@ as they are not strictly necessary.
|
||||
|
||||
I'm still working hard to make everything work across boundaries.<br/>
|
||||
The classes affected by the problem were `registry`, `dispatcher` and `emitter`.
|
||||
Currently, only the `registry` class fully support _shared types_. Using
|
||||
`dispatcher` and `emitter` across boundaries isn't allowed yet and can result in
|
||||
unexpected behavior on Windows in general and on GNU/Linux when default
|
||||
visibility is set to _hidden_.
|
||||
Currently, only `registry` and `dispatcher` fully support _shared types_. Using
|
||||
`emitter` across boundaries isn't allowed yet and can result in unexpected
|
||||
behavior on Windows in general and on GNU/Linux when default visibility is set
|
||||
to _hidden_.
|
||||
|
||||
Stay tuned for future updates.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <type_traits>
|
||||
#include "../config/config.h"
|
||||
#include "../core/family.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "sigh.hpp"
|
||||
|
||||
|
||||
@@ -75,19 +76,51 @@ class dispatcher {
|
||||
int current{};
|
||||
};
|
||||
|
||||
struct wrapper_data {
|
||||
std::unique_ptr<base_wrapper> wrapper;
|
||||
ENTT_ID_TYPE runtime_type;
|
||||
};
|
||||
|
||||
template<typename Event>
|
||||
static auto type() ENTT_NOEXCEPT {
|
||||
if constexpr(is_shared_v<Event>) {
|
||||
return shared_traits<Event>::value;
|
||||
} else {
|
||||
return event_family::type<Event>;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Event>
|
||||
signal_wrapper<Event> & wrapper() {
|
||||
const auto type = event_family::type<Event>;
|
||||
const auto wtype = type<Event>();
|
||||
wrapper_data *wdata = nullptr;
|
||||
|
||||
if(!(type < wrappers.size())) {
|
||||
wrappers.resize(type + 1);
|
||||
if constexpr(is_shared_v<Event>) {
|
||||
const auto it = std::find_if(wrappers.begin(), wrappers.end(), [wtype](const auto &wdata) {
|
||||
return wdata.wrapper && wdata.runtime_type == wtype;
|
||||
});
|
||||
|
||||
wdata = (it == wrappers.cend() ? &wrappers.emplace_back() : &(*it));
|
||||
} else {
|
||||
if(!(wtype < wrappers.size())) {
|
||||
wrappers.resize(wtype+1);
|
||||
}
|
||||
|
||||
wdata = &wrappers[wtype];
|
||||
|
||||
if(wdata->wrapper && wdata->runtime_type != wtype) {
|
||||
wrappers.emplace_back();
|
||||
std::swap(wrappers[wtype], wrappers.back());
|
||||
wdata = &wrappers[wtype];
|
||||
}
|
||||
}
|
||||
|
||||
if(!wrappers[type]) {
|
||||
wrappers[type] = std::make_unique<signal_wrapper<Event>>();
|
||||
if(!wdata->wrapper) {
|
||||
wdata->wrapper = std::make_unique<signal_wrapper<Event>>();
|
||||
wdata->runtime_type = wtype;
|
||||
}
|
||||
|
||||
return static_cast<signal_wrapper<Event> &>(*wrappers[type]);
|
||||
return static_cast<signal_wrapper<Event> &>(*wdata->wrapper);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -201,16 +234,16 @@ public:
|
||||
*/
|
||||
inline void update(Args... args) const {
|
||||
for(auto pos = wrappers.size(); pos; --pos) {
|
||||
auto &wrapper = wrappers[pos-1];
|
||||
auto &wdata = wrappers[pos-1];
|
||||
|
||||
if(wrapper) {
|
||||
wrapper->publish(args...);
|
||||
if(wdata.wrapper) {
|
||||
wdata.wrapper->publish(args...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<base_wrapper>> wrappers;
|
||||
std::vector<wrapper_data> wrappers;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#include <memory>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/entity/entt_traits.hpp>
|
||||
#include <entt/signal/dispatcher.hpp>
|
||||
|
||||
struct an_event {};
|
||||
struct another_event {};
|
||||
struct one_more_event {};
|
||||
|
||||
ENTT_SHARED_TYPE(an_event)
|
||||
|
||||
struct receiver {
|
||||
void receive(const an_event &, int value) { cnt += value; }
|
||||
@@ -15,9 +19,14 @@ TEST(Dispatcher, Functionalities) {
|
||||
entt::dispatcher<int> dispatcher;
|
||||
receiver receiver;
|
||||
|
||||
dispatcher.trigger<one_more_event>(1);
|
||||
dispatcher.enqueue<one_more_event>();
|
||||
dispatcher.update<one_more_event>(1);
|
||||
|
||||
dispatcher.sink<an_event>().connect<&receiver::receive>(&receiver);
|
||||
dispatcher.trigger<an_event>(1);
|
||||
dispatcher.enqueue<an_event>();
|
||||
|
||||
dispatcher.enqueue<another_event>();
|
||||
dispatcher.update<another_event>(1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user