From f36bd6f8e093a779764fee04acfb3bffed83cbc6 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Fri, 18 Jan 2019 22:45:11 -0800 Subject: [PATCH] Added native Timeout helper --- microscript/ILibDuktape_Helpers.c | 49 +++++++++++++++++++++++++++++++ microscript/ILibDuktape_Helpers.h | 2 ++ 2 files changed, 51 insertions(+) diff --git a/microscript/ILibDuktape_Helpers.c b/microscript/ILibDuktape_Helpers.c index e34a372..ad64b78 100644 --- a/microscript/ILibDuktape_Helpers.c +++ b/microscript/ILibDuktape_Helpers.c @@ -645,7 +645,56 @@ void *ILibDuktape_Memory_AllocEx(duk_context *ctx, duk_idx_t index, duk_size_t s duk_pop_2(ctx); // ... return(retVal); } +duk_ret_t ILibDuktape_Timeout_Sink(duk_context *ctx) +{ + ILibDuktape_TimeoutHandler userCallback = (ILibDuktape_TimeoutHandler)duk_get_pointer(ctx, 0); + void **args = NULL; + int argsLen, i; + duk_push_this(ctx); // [timeout] + duk_dup(ctx, 1); // [timeout][array] + if ((argsLen = (int)duk_get_length(ctx, -1)) > 0) + { + args = ILibMemory_AllocateA(sizeof(void*)*argsLen); + for (i = 0; i < argsLen; ++i) + { + duk_get_prop_index(ctx, -1, i); // [timeout][array][arg] + args[i] = duk_get_pointer(ctx, -1); + duk_pop(ctx); // [timeout][array] + } + } + + if (userCallback != NULL) { userCallback(ctx, args, argsLen); } + return(0); +} +void* ILibDuktape_Timeout(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_TimeoutHandler callback) +{ + void *retval = NULL; + int i = 0; + duk_push_global_object(ctx); // [g] + duk_get_prop_string(ctx, -1, "setTimeout"); // [g][setTimeout] + duk_swap_top(ctx, -2); // [setTimeout][this] + duk_push_c_function(ctx, ILibDuktape_Timeout_Sink, DUK_VARARGS); // [setTimeout][this][func] + duk_push_int(ctx, delay); // [setTimeout][this][func][delay] + duk_push_pointer(ctx, callback); // [setTimeout][this][func][delay][userFunc] + duk_push_array(ctx); // [setTimeout][this][func][delay][userFunc][array] + + while (args[i] != NULL && i < argsLen) + { + duk_get_prop_string(ctx, -1, "push"); // [setInterval][this][func][delay][userFunc][array][push] + duk_dup(ctx, -2); // [setInterval][this][func][delay][userFunc][array][push][this] + duk_push_pointer(ctx, args[i]); // [setInterval][this][func][delay][userFunc][array][push][this][val] + if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Timeout => Array.push(): "); } + duk_pop(ctx); // [setInterval][this][func][delay][userFunc][array] + ++i; + } + + if (duk_pcall_method(ctx, 4) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Timeout => timeout(): "); duk_pop(ctx); return(NULL); } + + + retval = duk_get_heapptr(ctx, -1); // [timeout] + return(retval); +} duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx) { ILibDuktape_ImmediateHandler userCallback = (ILibDuktape_ImmediateHandler)duk_get_pointer(ctx, 0); diff --git a/microscript/ILibDuktape_Helpers.h b/microscript/ILibDuktape_Helpers.h index 4a7f3b3..884a8bb 100644 --- a/microscript/ILibDuktape_Helpers.h +++ b/microscript/ILibDuktape_Helpers.h @@ -114,9 +114,11 @@ void ILibDuktape_Push_ObjectStash(duk_context *ctx); typedef void(*ILibDuktape_ImmediateHandler)(duk_context *ctx, void ** args, int argsLen); typedef ILibDuktape_ImmediateHandler ILibDuktape_IntervalHandler; +typedef ILibDuktape_ImmediateHandler ILibDuktape_TimeoutHandler; void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback); void* ILibDuktape_Interval(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_IntervalHandler callback); +void* ILibDuktape_Timeout(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_TimeoutHandler callback); int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i); #define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)