|
|
@@ -7,9 +7,67 @@
|
|
|
namespace Atomic
|
|
|
{
|
|
|
|
|
|
+
|
|
|
+JSEventDispatcher::JSEventDispatcher(Context* context) :
|
|
|
+ Object(context)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+JSEventDispatcher::~JSEventDispatcher()
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void JSEventDispatcher::BeginSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData)
|
|
|
+{
|
|
|
+ JSVM* vm = JSVM::GetJSVM(NULL);
|
|
|
+
|
|
|
+ if (!vm)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!jsEvents_.Contains(eventType))
|
|
|
+ return;
|
|
|
+
|
|
|
+ duk_context* ctx = vm->GetJSContext();
|
|
|
+
|
|
|
+ duk_push_global_stash(ctx);
|
|
|
+ duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);
|
|
|
+
|
|
|
+ duk_push_pointer(ctx, (void*) &eventData);
|
|
|
+ js_push_variantmap(ctx, eventData);
|
|
|
+ duk_put_prop(ctx, -3);
|
|
|
+
|
|
|
+ duk_pop_2(ctx);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void JSEventDispatcher::EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData)
|
|
|
+{
|
|
|
+ JSVM* vm = JSVM::GetJSVM(NULL);
|
|
|
+
|
|
|
+ if (!vm)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!jsEvents_.Contains(eventType))
|
|
|
+ return;
|
|
|
+
|
|
|
+ duk_context* ctx = vm->GetJSContext();
|
|
|
+
|
|
|
+ duk_push_global_stash(ctx);
|
|
|
+ duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);
|
|
|
+
|
|
|
+ duk_push_pointer(ctx, (void*) &eventData);
|
|
|
+ duk_push_undefined(ctx);
|
|
|
+ duk_put_prop(ctx, -3);
|
|
|
+
|
|
|
+ duk_pop_2(ctx);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
JSEventHelper::JSEventHelper(Context* context) :
|
|
|
Object(context)
|
|
|
{
|
|
|
+
|
|
|
}
|
|
|
|
|
|
JSEventHelper::~JSEventHelper()
|
|
|
@@ -19,11 +77,15 @@ JSEventHelper::~JSEventHelper()
|
|
|
|
|
|
void JSEventHelper::AddEventHandler(StringHash eventType)
|
|
|
{
|
|
|
+ GetSubsystem<JSEventDispatcher>()->RegisterJSEvent(eventType);
|
|
|
+
|
|
|
SubscribeToEvent(eventType, HANDLER(JSEventHelper, HandleEvent));
|
|
|
}
|
|
|
|
|
|
void JSEventHelper::AddEventHandler(Object* sender, StringHash eventType)
|
|
|
{
|
|
|
+ GetSubsystem<JSEventDispatcher>()->RegisterJSEvent(eventType);
|
|
|
+
|
|
|
SubscribeToEvent(sender, eventType, HANDLER(JSEventHelper, HandleEvent));
|
|
|
}
|
|
|
|
|
|
@@ -47,10 +109,19 @@ void JSEventHelper::HandleEvent(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
assert(duk_is_object(ctx, -1));
|
|
|
|
|
|
- //TODO: this is expensive, we should be caching these in VM
|
|
|
- // and reusing, instead of creating new variant map object
|
|
|
- // per event handler
|
|
|
- js_push_variantmap(ctx, eventData);
|
|
|
+ duk_push_global_stash(ctx);
|
|
|
+ duk_get_prop_index(ctx, -1, JS_GLOBALSTASH_VARIANTMAP_CACHE);
|
|
|
+ duk_push_pointer(ctx, (void*) &eventData);
|
|
|
+ duk_get_prop(ctx, -2);
|
|
|
+
|
|
|
+ duk_remove(ctx, -2); // vmap cache
|
|
|
+ duk_remove(ctx, -2); // global stash
|
|
|
+
|
|
|
+ if (!duk_is_object(ctx, -1))
|
|
|
+ {
|
|
|
+ duk_set_top(ctx, top);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
if (duk_pcall(ctx, 1) != 0)
|
|
|
{
|