mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-02-24 16:42:56 +00:00
Added new reference mode for EventEmitter
This commit is contained in:
@@ -109,6 +109,7 @@ int ILibDuktape_HECI_Debug = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int gEventEmitterReferenceHold;
|
||||
extern int ILibDuktape_ModSearch_ShowNames;
|
||||
char* MeshAgentHost_BatteryInfo_STRINGS[] = { "UNKNOWN", "HIGH_CHARGE", "LOW_CHARGE", "NO_BATTERY", "CRITICAL_CHARGE", "", "", "", "CHARGING" };
|
||||
JS_ENGINE_CONTEXT MeshAgent_JavaCore_ContextGuid = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
|
||||
@@ -5095,7 +5096,14 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
{
|
||||
duk_eval_string_noresult(agentHost->meshCoreCtx, "process.coreDumpLocation = process.platform=='win32'?(process.execPath.replace('.exe', '.dmp')):(process.execPath + '.dmp');");
|
||||
}
|
||||
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "eventemitter-refhold", ILibScratchPad, sizeof(ILibScratchPad)) != 0)
|
||||
{
|
||||
gEventEmitterReferenceHold = atoi(ILibScratchPad);
|
||||
}
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "finalizer-messages", ILibScratchPad, sizeof(ILibScratchPad)) != 0)
|
||||
{
|
||||
g_displayFinalizerMessages = atoi(ILibScratchPad);
|
||||
}
|
||||
if (CoreModuleLen > 4)
|
||||
{
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "noUpdateCoreModule", NULL, 0) != 0)
|
||||
@@ -5518,6 +5526,14 @@ void MeshAgent_ScriptMode(MeshAgentHostContainer *agentHost, int argc, char **ar
|
||||
agentHost->masterDb = ILibSimpleDataStore_Create(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".db"));
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[i], "--eventemitter-refhold=", 23) == 0)
|
||||
{
|
||||
char *tmp = strstr(argv[i], "=");
|
||||
if (tmp != NULL)
|
||||
{
|
||||
gEventEmitterReferenceHold = atoi(tmp + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unhandled arguments, passed to JavaScript
|
||||
|
||||
@@ -21,6 +21,8 @@ limitations under the License.
|
||||
#include "microstack/ILibParsers.h"
|
||||
|
||||
#define ILibDuktape_EventEmitter_FinalizerDebugMessage "\xFF_FinalizerDebugMessage"
|
||||
#define ILibDuktape_EventEmitter_InfrastructureEvent "\xFF_EventEmitter_InfrastructureEvent"
|
||||
|
||||
|
||||
typedef enum ILibDuktape_EventEmitter_Types
|
||||
{
|
||||
@@ -36,7 +38,6 @@ typedef struct ILibDuktape_EventEmitter
|
||||
void *table;
|
||||
void *retValTable;
|
||||
void *lastReturnValue;
|
||||
unsigned int *totalListeners;
|
||||
const char *listenerCountTable;
|
||||
size_t listenerCountTableLength;
|
||||
ILibSpinLock listenerCountTableLock;
|
||||
@@ -71,6 +72,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
|
||||
|
||||
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
|
||||
#define ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, idx, eventName, func) duk_prepare_method_call(ctx, idx, "on");duk_push_string(ctx, eventName);duk_push_c_function(ctx, func, DUK_VARARGS);duk_push_true(ctx);duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);duk_pcall_method(ctx, 2);duk_pop(ctx);
|
||||
|
||||
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);
|
||||
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName);
|
||||
|
||||
@@ -907,7 +907,7 @@ void ILibDuktape_CreateProperty_InstanceMethod(duk_context *ctx, char *methodNam
|
||||
duk_push_c_function(ctx, ILibDuktape_CreateProperty_InstanceMethod_Sink, 1); // [obj][prop][getFunc]
|
||||
duk_push_c_function(ctx, impl, argCount); // [obj][prop][getFunc][func]
|
||||
duk_put_prop_string(ctx, -2, "actualFunc"); // [obj][prop][getFunc]
|
||||
duk_def_prop(ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_GETTER); // [obj]
|
||||
duk_def_prop(ctx, -3, DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_GETTER); // [obj]
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ReadonlyProperty_Get(duk_context *ctx)
|
||||
|
||||
@@ -203,6 +203,7 @@ duk_idx_t duk_push_int_ex(duk_context *ctx, duk_int_t val);
|
||||
|
||||
void ILibDuktape_CreateProperty_InstanceMethod(duk_context *ctx, char *methodName, duk_c_function impl, duk_idx_t argCount);
|
||||
void ILibDuktape_CreateProperty_InstanceMethodEx(duk_context *ctx, char *methodName, void *funcHeapPtr);
|
||||
#define ILibDuktape_DeleteReadOnlyProperty(ctx, i, propName) duk_dup(ctx,i);duk_push_string(ctx,propName);duk_def_prop(ctx,-2,DUK_DEFPROP_FORCE|DUK_DEFPROP_SET_CONFIGURABLE);duk_pop(ctx);duk_del_prop_string(ctx,i,propName);
|
||||
#define ILibDuktape_CreateReadonlyProperty(ctx, propName) ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, propName, 0)
|
||||
void ILibDuktape_CreateReadonlyProperty_SetEnumerable(duk_context *ctx, char *propName, int enumerable);
|
||||
#define ILibDuktape_CreateReadonlyProperty_int(ctx, propName, propValue) duk_push_int(ctx, propValue);ILibDuktape_CreateReadonlyProperty_SetEnumerable(ctx, propName, 1)
|
||||
|
||||
@@ -339,8 +339,7 @@ ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, IL
|
||||
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "write", ILibDuktape_WritableStream_Write, DUK_VARARGS);
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "end", ILibDuktape_WritableStream_End_Getter);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_WritableStream_PipeSink);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "unpipe", ILibDuktape_WritableStream_UnPipeSink);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "pipe", ILibDuktape_WritableStream_PipeSink);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "unpipe", ILibDuktape_WritableStream_UnPipeSink);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,13 @@ limitations under the License.
|
||||
#define ILibDuktape_EventEmitter_ForwardTable "\xFF_EventEmitter_ForwardTable"
|
||||
#define ILibDuktape_EventEmitter_EventTable "\xFF_EventEmitter_EventTable"
|
||||
#define ILibDuktape_EventEmitter_CountTable "\xFF_EventEmitter_CountTable"
|
||||
#define ILibDuktape_EventEmitter_References "\xFF_EventReferences"
|
||||
|
||||
#ifdef ILIBEVENTEMITTER_REFHOLD
|
||||
int gEventEmitterReferenceHold = ILIBEVENTEMITTER_REFHOLD;
|
||||
#else
|
||||
int gEventEmitterReferenceHold = 0;
|
||||
#endif
|
||||
|
||||
typedef struct ILibDuktape_EventEmitter_EmitStruct
|
||||
{
|
||||
@@ -418,6 +425,27 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
duk_array_push(ctx, -2); // [object][table][array]
|
||||
}
|
||||
|
||||
if (gEventEmitterReferenceHold != 0)
|
||||
{
|
||||
duk_prepare_method_call(ctx, -3, "eventNames"); // [object][table][array][eventNames][this]
|
||||
duk_call_method(ctx, 0); // [object][table][array][names]
|
||||
|
||||
if (duk_get_length(ctx, -1) > 0)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [object][table][array][names][stash]
|
||||
if (!duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_References))
|
||||
{
|
||||
duk_push_object(ctx); // [object][table][array][names][stash][refs]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_References); // [object][table][array][names][stash]
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_References); // [object][table][array][names][stash][refs]
|
||||
duk_push_this(ctx); // [object][table][array][names][stash][refs][this]
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1))); //ect][table][array][names][stash][refs]
|
||||
duk_pop_2(ctx); // [object][table][array][names]
|
||||
}
|
||||
duk_pop(ctx); // [object][table][array]
|
||||
}
|
||||
|
||||
if (!(propNameLen == 11 && strncmp(propName, "newListener", 11) == 0) && !(propNameLen == 12 && strncmp(propName, "newListener2", 12) == 0))
|
||||
{
|
||||
// Only emit 'newListener2' when the event itself isn't 'newListener' or 'newListener2'
|
||||
@@ -600,13 +628,38 @@ duk_ret_t ILibDuktape_EventEmitter_listenerCount(duk_context *ctx)
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_eventNames(duk_context *ctx)
|
||||
{
|
||||
duk_size_t len;
|
||||
duk_uarridx_t i;
|
||||
duk_size_t count;
|
||||
|
||||
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
|
||||
duk_push_array(ctx); // [array]
|
||||
duk_push_heapptr(ctx, emitter->table); // [array][table]
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);// [array][table][enumerator]
|
||||
while (duk_next(ctx, -1, 0)) // [array][table][enumerator][key]
|
||||
while (duk_next(ctx, -1, 1)) // [array][table][enumerator][key][value]
|
||||
{
|
||||
duk_array_push(ctx, -4); // [array][table][enumerator]
|
||||
count = 0;
|
||||
if (strcmp(duk_get_string(ctx, -2), "~") != 0)
|
||||
{
|
||||
// We will only look at events that aren't the finalizer event
|
||||
len = duk_get_length(ctx, -1);
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [array][table][enumerator][key][value][obj]
|
||||
duk_get_prop_string(ctx, -1, "func"); // [array][table][enumerator][key][value][obj][func]
|
||||
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_EventEmitter_InfrastructureEvent, 0) == 0) { ++count; }
|
||||
duk_pop_2(ctx); // [array][table][enumerator][key][value]
|
||||
}
|
||||
}
|
||||
duk_pop(ctx); // [array][table][enumerator][key]
|
||||
if (count > 0)
|
||||
{
|
||||
duk_array_push(ctx, -4); // [array][table][enumerator]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_pop(ctx); // [array][table][enumerator]
|
||||
}
|
||||
}
|
||||
duk_pop_2(ctx); // [array]
|
||||
return(1);
|
||||
@@ -657,9 +710,26 @@ duk_ret_t ILibDuktape_EventEmitter_listeners_tableinit(duk_context *ctx)
|
||||
int isAdd = Duktape_GetIntPropertyValue(ctx, -1, "add", 0);
|
||||
const char *eventName = duk_require_string(ctx, 0);
|
||||
|
||||
duk_push_this(ctx);
|
||||
duk_push_this(ctx); // [obj]
|
||||
ILibDuktape_EventEmitter *emitter = (ILibDuktape_EventEmitter*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_EventEmitter_Data);
|
||||
|
||||
if (isAdd == 0 && gEventEmitterReferenceHold != 0)
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "eventNames"); // [obj][eventNames][this]
|
||||
duk_call_method(ctx, 0); // [obj][names]
|
||||
if (duk_get_length(ctx, -1) == 0)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [obj][names][stash]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_References); // [obj][names][stash][refs]
|
||||
if (!duk_is_null_or_undefined(ctx, -1))
|
||||
{
|
||||
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(duk_get_heapptr(ctx, -4)));
|
||||
}
|
||||
duk_pop_2(ctx); // [obj][names]
|
||||
}
|
||||
duk_pop(ctx); // [obj]
|
||||
}
|
||||
|
||||
ILibSpinLock_Lock(&(emitter->listenerCountTableLock));
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "JSON"); // [g][JSON]
|
||||
@@ -764,22 +834,6 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "emit", ILibDuktape_EventEmitter_emit, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "emit_returnValue", ILibDuktape_EventEmitter_emitReturnValue, DUK_VARARGS);
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_GlobalListenerCount))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_GlobalListenerCount);
|
||||
retVal->totalListeners = (unsigned int *)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
Duktape_PushBuffer(ctx, sizeof(unsigned int));
|
||||
retVal->totalListeners = (unsigned int *)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_GlobalListenerCount);
|
||||
*(retVal->totalListeners) = 0;
|
||||
}
|
||||
duk_pop(ctx);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(retVal, "~");
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_EmbeddedFinalizer, 1);
|
||||
duk_set_finalizer(ctx, -2);
|
||||
@@ -789,10 +843,12 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
|
||||
duk_events_setup_on(ctx, -1, "newListener2", ILibDuktape_EventEmitter_listeners_tableinit); // [on][this][newListener][func]
|
||||
duk_push_int(ctx, 1); duk_put_prop_string(ctx, -2, "add");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx); // ...
|
||||
|
||||
duk_events_setup_on(ctx, -1, "removeListener", ILibDuktape_EventEmitter_listeners_tableinit); // [on][this][removeListener][func]
|
||||
duk_push_int(ctx, 0); duk_put_prop_string(ctx, -2, "add");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx); // ...
|
||||
|
||||
return retVal;
|
||||
@@ -936,7 +992,7 @@ void ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter *emitter, c
|
||||
duk_push_string(emitter->ctx, eventName); // [obj][prop][setFunc][name]
|
||||
duk_put_prop_string(emitter->ctx, -2, "eventName"); // [obj][prop][setFunc]
|
||||
|
||||
duk_def_prop(emitter->ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
|
||||
duk_def_prop(emitter->ctx, -3, DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
|
||||
duk_pop(emitter->ctx); // ...
|
||||
}
|
||||
else
|
||||
@@ -1077,12 +1133,30 @@ duk_ret_t ILibDuktape_EventEmitter_moderated(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, "interval"); // [func]
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_allProperties(duk_context *ctx)
|
||||
{
|
||||
const char *tmp;
|
||||
duk_push_array(ctx); // [arr]
|
||||
duk_dup(ctx, 0); // [arr][obj]
|
||||
duk_enum(ctx, -1, DUK_ENUM_INCLUDE_NONENUMERABLE | DUK_ENUM_INCLUDE_HIDDEN );
|
||||
while (duk_next(ctx, -1, 0)) // [arr][obj][enum][key]
|
||||
{
|
||||
tmp = duk_get_string(ctx, -1);
|
||||
duk_push_string(ctx, tmp); // [arr][obj][enum][key][string]
|
||||
duk_array_push(ctx, -5); // [arr][obj][enum][key]
|
||||
duk_pop(ctx); // [arr][obj][enum]
|
||||
}
|
||||
duk_pop_2(ctx); // [arr]
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [emitter]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "inherits", ILibDuktape_EventEmitter_Inherits, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "EventEmitter", ILibDuktape_EventEmitter_EventEmitter, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "moderated", ILibDuktape_EventEmitter_moderated, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "allProperties", ILibDuktape_EventEmitter_allProperties, 1);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_Init(duk_context *ctx)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user