diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a43128..82443f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,7 @@ set(BUILDAT_CORE_SRCS src/impl/compress.cpp src/impl/thread_pool.cpp src/impl/thread.cpp + src/impl/magic_event_handler.cpp ) if(WIN32) set(BUILDAT_CORE_SRCS ${BUILDAT_CORE_SRCS} src/boot/windows/cmem.c) diff --git a/src/impl/magic_event_handler.cpp b/src/impl/magic_event_handler.cpp new file mode 100644 index 0000000..3869137 --- /dev/null +++ b/src/impl/magic_event_handler.cpp @@ -0,0 +1,80 @@ +// http://www.apache.org/licenses/LICENSE-2.0 +// Copyright 2014 Perttu Ahola +#include "interface/magic_event_handler.h" +#include "core/log.h" +#include +#include +#include +#include +#include +#include + +#define ERASE_FIELD(name){\ + event_data.Erase(#name);\ +} + +#define POINTER_TO_ID(type, name){\ + type *pointer = static_cast(event_data[#name].GetVoidPtr());\ + event_data[#name "ID"] = pointer->GetID();\ + event_data.Erase(#name);\ +} + +namespace interface { + +using namespace Urho3D; + +void MagicEventHandler::on_event(StringHash event_type, VariantMap &event_data) +{ + auto *evreg = interface::getGlobalEventRegistry(); + if(log_get_max_level() >= CORE_DEBUG){ + log_d(MODULE, "MagicEventHandler::on_event(): %s (%zu)", + cs(evreg->name(m_buildat_event_type)), m_buildat_event_type); + } + + // Convert pointers to IDs because the event will be queued for later + // handling and pointers may become invalid. This operates like a + // whitelist because passing the pointers around is so unsafe it's + // going to cause way too much trouble. + + if(event_type == E_LOGMESSAGE){ + emit_event(event_type, event_data); + return; + } + if(event_type == E_NODEADDED || event_type == E_NODEREMOVED){ + POINTER_TO_ID(Node, Parent); + POINTER_TO_ID(Node, Node); + emit_event(event_type, event_data); + return; + } + if(event_type == E_COMPONENTADDED || event_type == E_COMPONENTREMOVED){ + POINTER_TO_ID(Node, Node); + POINTER_TO_ID(Component, Component); + emit_event(event_type, event_data); + return; + } + if(event_type == E_PHYSICSCOLLISIONSTART){ + ERASE_FIELD(World); + POINTER_TO_ID(Node, NodeA); + POINTER_TO_ID(Node, NodeB); + POINTER_TO_ID(RigidBody, BodyA); + POINTER_TO_ID(RigidBody, BodyB); + emit_event(event_type, event_data); + return; + } + if(event_type == E_PHYSICSCOLLISION){ + ERASE_FIELD(World); + POINTER_TO_ID(Node, NodeA); + POINTER_TO_ID(Node, NodeB); + POINTER_TO_ID(RigidBody, BodyA); + POINTER_TO_ID(RigidBody, BodyB); + emit_event(event_type, event_data); + return; + } + + throw Exception(ss_()+"MagicEventHandler::on_event(): Urho3D event " + "not whitelisted: "+cs(evreg->name(m_buildat_event_type))); +} + + +} +// vim: set noet ts=4 sw=4: diff --git a/src/interface/magic_event_handler.h b/src/interface/magic_event_handler.h index d66917e..f36528c 100644 --- a/src/interface/magic_event_handler.h +++ b/src/interface/magic_event_handler.h @@ -5,9 +5,6 @@ #include "interface/server.h" #include "interface/magic_event.h" #include -#include -#include -#include namespace interface { @@ -34,40 +31,13 @@ namespace interface SubscribeToEvent(event_type, HANDLER(MagicEventHandler, on_event)); } - void on_event(magic::StringHash event_type, magic::VariantMap &event_data) + void emit_event(magic::StringHash event_type, magic::VariantMap &event_data) { - auto *evreg = interface::getGlobalEventRegistry(); - if(log_get_max_level() >= CORE_DEBUG){ - log_d(MODULE, "MagicEventHandler::on_event(): %s (%zu)", - cs(evreg->name(m_buildat_event_type)), m_buildat_event_type); - } - // Convert pointers to IDs because the event will be queued for later - // handling and pointers may become invalid - if(event_type == magic::E_NODEADDED || - event_type == magic::E_NODEREMOVED){ - magic::Node *parent = static_cast( - event_data["Parent"].GetVoidPtr()); - event_data["ParentID"] = parent->GetID(); - event_data.Erase("Parent"); - magic::Node *node = static_cast( - event_data["Node"].GetVoidPtr()); - event_data["NodeID"] = node->GetID(); - event_data.Erase("Node"); - } - if(event_type == magic::E_COMPONENTADDED || - event_type == magic::E_COMPONENTREMOVED){ - magic::Node *node = static_cast( - event_data["Node"].GetVoidPtr()); - event_data["NodeID"] = node->GetID(); - event_data.Erase("Node"); - magic::Component *c = static_cast( - event_data["Component"].GetVoidPtr()); - event_data["ComponentID"] = c->GetID(); - event_data.Erase("Component"); - } m_server->emit_event(m_buildat_event_type, new interface::MagicEvent( event_type, event_data)); } + + void on_event(magic::StringHash event_type, magic::VariantMap &event_data); }; } // vim: set noet ts=4 sw=4: