interface/magic_event_handler: Operate in a whitelist-like fashion and add collision events to whitelist

master
Perttu Ahola 2014-11-03 21:07:16 +02:00
parent d3a74d7826
commit 6e8202c6d5
3 changed files with 84 additions and 33 deletions

View File

@ -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)

View File

@ -0,0 +1,80 @@
// http://www.apache.org/licenses/LICENSE-2.0
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
#include "interface/magic_event_handler.h"
#include "core/log.h"
#include <SceneEvents.h>
#include <PhysicsEvents.h>
#include <IOEvents.h>
#include <Node.h>
#include <Component.h>
#include <RigidBody.h>
#define ERASE_FIELD(name){\
event_data.Erase(#name);\
}
#define POINTER_TO_ID(type, name){\
type *pointer = static_cast<type*>(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:

View File

@ -5,9 +5,6 @@
#include "interface/server.h"
#include "interface/magic_event.h"
#include <Object.h>
#include <SceneEvents.h>
#include <Node.h>
#include <Component.h>
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<magic::Node*>(
event_data["Parent"].GetVoidPtr());
event_data["ParentID"] = parent->GetID();
event_data.Erase("Parent");
magic::Node *node = static_cast<magic::Node*>(
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<magic::Node*>(
event_data["Node"].GetVoidPtr());
event_data["NodeID"] = node->GetID();
event_data.Erase("Node");
magic::Component *c = static_cast<magic::Component*>(
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: