From 27f6f37b336c3fcdc73e307ffc7e843a50142ef7 Mon Sep 17 00:00:00 2001 From: Callum Carmicheal Date: Sat, 17 Aug 2019 04:18:05 +0100 Subject: [PATCH] Adding dukglue_register_function_property A helper function to allow the use of dukglue on Objects instead of the Global namespace. Example code usage: ```cpp int math_add(int x, int y) { printf("Example function called\n"); return x + y; } void CreateTheObject(duk_context *ctx) { // 1. Create a new object // 2. Register the function as a property on the object // 3. Store the object as global duk_push_object(ctx); dukglue_register_function_property(ctx, &math_add, "add"); duk_put_global_string(ctx, "Math"); } void CreateTheObjectWithIndex(duk_context *ctx) { // 1. Create a new object // 2. Register the function as a property on the object // 3. Store the object as global duk_idx_t mathObjectIdx = duk_push_object(ctx); // lets say for what ever reason there are more values on the stack for(int x = 0; x < 3; x++) duk_push_null(ctx); // We will now register the function to the original stack object's index (mathObjectIdx) dukglue_register_function_property(ctx, &math_add, mathObjectIdx, "add"); duk_put_global_string(ctx, "Math"); // Clean up the nulls (only in the example) for(int x = 0; x < 3; x++) duk_pop(ctx); } int PlayerOnHit(int currentHealth) { return currentHealth--; } void AppendToObject(duk_context *ctx) { // 1. Find the global object "Player" // 2. Register the function as a property // 3. Remove "Game" from the stack duk_get_global_string(ctx, "Game"); dukglue_register_function_property(ctx, &PlayerOnHit, "OnHit"); duk_pop(ctx); } ``` --- include/dukglue/register_function.h | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/dukglue/register_function.h b/include/dukglue/register_function.h index 77e83aa..fba9091 100644 --- a/include/dukglue/register_function.h +++ b/include/dukglue/register_function.h @@ -33,3 +33,35 @@ void dukglue_register_function(duk_context* ctx, RetType(*funcToCall)(Ts...), co duk_put_global_string(ctx, name); } + + +// Register a function as a property to a object. +// Simply does the same as the above but replaces duk_put_global_string with duk_put_prop_string +template +void dukglue_register_function_property(duk_context* ctx, RetType(*funcToCall)(Ts...), const char* name) +{ + duk_c_function evalFunc = dukglue::detail::FuncInfoHolder::FuncRuntime::call_native_function; + + duk_push_c_function(ctx, evalFunc, sizeof...(Ts)); + + static_assert(sizeof(RetType(*)(Ts...)) == sizeof(void*), "Function pointer and data pointer are different sizes"); + duk_push_pointer(ctx, reinterpret_cast(funcToCall)); + duk_put_prop_string(ctx, -2, "\xFF" "func_ptr"); + + duk_put_prop_string(ctx, -2, name); +} + +// Register a function as a property to a object using the objects index. +template +void dukglue_register_function_property(duk_context* ctx, RetType(*funcToCall)(Ts...), duk_idx_t objectIdx, const char* name) +{ + duk_c_function evalFunc = dukglue::detail::FuncInfoHolder::FuncRuntime::call_native_function; + + duk_push_c_function(ctx, evalFunc, sizeof...(Ts)); + + static_assert(sizeof(RetType(*)(Ts...)) == sizeof(void*), "Function pointer and data pointer are different sizes"); + duk_push_pointer(ctx, reinterpret_cast(funcToCall)); + duk_put_prop_string(ctx, -2, "\xFF" "func_ptr"); + + duk_put_prop_string(ctx, objectIdx, name); +}