emitter: make it run smoothly across boundaries
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "../config/config.h"
|
||||
#include "../container/dense_hash_map.hpp"
|
||||
#include "../core/fwd.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
|
||||
@@ -120,23 +120,19 @@ class emitter {
|
||||
|
||||
template<typename Event>
|
||||
[[nodiscard]] pool_handler<Event> *assure() {
|
||||
const auto index = type_index<Event>::value();
|
||||
|
||||
if(!(index < pools.size())) {
|
||||
pools.resize(std::size_t(index) + 1u);
|
||||
if(auto &&ptr = pools[type_id<Event>().hash()]; !ptr) {
|
||||
auto *cpool = new pool_handler<Event>{};
|
||||
ptr.reset(cpool);
|
||||
return cpool;
|
||||
} else {
|
||||
return static_cast<pool_handler<Event> *>(ptr.get());
|
||||
}
|
||||
|
||||
if(!pools[index]) {
|
||||
pools[index].reset(new pool_handler<Event>{});
|
||||
}
|
||||
|
||||
return static_cast<pool_handler<Event> *>(pools[index].get());
|
||||
}
|
||||
|
||||
template<typename Event>
|
||||
[[nodiscard]] const pool_handler<Event> *assure() const {
|
||||
const auto index = type_index<Event>::value();
|
||||
return (!(index < pools.size()) || !pools[index]) ? nullptr : static_cast<const pool_handler<Event> *>(pools[index].get());
|
||||
const auto it = pools.find(type_id<Event>().hash());
|
||||
return (it == pools.cend()) ? nullptr : static_cast<const pool_handler<Event> *>(it->second.get());
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -285,9 +281,7 @@ public:
|
||||
*/
|
||||
void clear() ENTT_NOEXCEPT {
|
||||
for(auto &&cpool: pools) {
|
||||
if(cpool) {
|
||||
cpool->clear();
|
||||
}
|
||||
cpool.second->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,12 +302,12 @@ public:
|
||||
*/
|
||||
[[nodiscard]] bool empty() const ENTT_NOEXCEPT {
|
||||
return std::all_of(pools.cbegin(), pools.cend(), [](auto &&cpool) {
|
||||
return !cpool || cpool->empty();
|
||||
return cpool.second->empty();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<basic_pool>> pools{};
|
||||
dense_hash_map<id_type, std::unique_ptr<basic_pool>> pools{};
|
||||
};
|
||||
|
||||
} // namespace entt
|
||||
|
||||
@@ -2,19 +2,9 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cr.h>
|
||||
#include <entt/core/type_info.hpp>
|
||||
#include <entt/signal/emitter.hpp>
|
||||
#include "type_context.h"
|
||||
#include "types.h"
|
||||
|
||||
template<typename Type>
|
||||
struct entt::type_index<Type> {
|
||||
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
|
||||
static const entt::id_type value = type_context::instance()->value(entt::type_hash<Type>::value());
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Lib, Emitter) {
|
||||
test_emitter emitter;
|
||||
int value{};
|
||||
@@ -26,9 +16,6 @@ TEST(Lib, Emitter) {
|
||||
cr_plugin ctx;
|
||||
cr_plugin_load(ctx, PLUGIN);
|
||||
|
||||
ctx.userdata = type_context::instance();
|
||||
cr_plugin_update(ctx);
|
||||
|
||||
ctx.userdata = &emitter;
|
||||
cr_plugin_update(ctx);
|
||||
|
||||
|
||||
@@ -1,31 +1,13 @@
|
||||
#include <cr.h>
|
||||
#include <entt/core/type_info.hpp>
|
||||
#include <entt/signal/emitter.hpp>
|
||||
#include "type_context.h"
|
||||
#include "types.h"
|
||||
|
||||
struct ctx {
|
||||
inline static type_context *ref;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct entt::type_index<Type> {
|
||||
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
|
||||
static const entt::id_type value = ctx::ref->value(entt::type_hash<Type>::value());
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
|
||||
switch(operation) {
|
||||
case CR_STEP:
|
||||
if(!ctx::ref) {
|
||||
ctx::ref = static_cast<type_context *>(ctx->userdata);
|
||||
} else {
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<event>();
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<message>(42);
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<message>(3);
|
||||
}
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<event>();
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<message>(42);
|
||||
static_cast<test_emitter *>(ctx->userdata)->publish<message>(3);
|
||||
break;
|
||||
case CR_CLOSE:
|
||||
case CR_LOAD:
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef ENTT_LIB_EMITTER_PLUGIN_TYPE_CONTEXT_H
|
||||
#define ENTT_LIB_EMITTER_PLUGIN_TYPE_CONTEXT_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <entt/core/fwd.hpp>
|
||||
|
||||
class type_context {
|
||||
type_context() = default;
|
||||
|
||||
public:
|
||||
inline entt::id_type value(const entt::id_type name) {
|
||||
if(name_to_index.find(name) == name_to_index.cend()) {
|
||||
name_to_index[name] = entt::id_type(name_to_index.size());
|
||||
}
|
||||
|
||||
return name_to_index[name];
|
||||
}
|
||||
|
||||
static type_context *instance() {
|
||||
static type_context self{};
|
||||
return &self;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<entt::id_type, entt::id_type> name_to_index{};
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user