public static void RegGlobalCsFunction(IntPtr ctx, string func_name, cs_function funcs, int nargs = 0) { string[] paths = func_name.Split('.'); if (paths.Length == 1) { Native.duk_push_global_object(ctx); Native.duk_push_cs_function(ctx, funcs, nargs); Native.duk_put_prop_string(ctx, -2, func_name); Native.duk_pop(ctx); } else { for (int i = 0; i < paths.Length - 1; i++) // walk to modules tail like: xxx.xxx { string module = paths[i]; RegModuleBegin(ctx, module); } string name = paths[paths.Length - 1]; RegCsFunction(ctx, name, funcs, nargs); for (int i = 0; i < paths.Length - 1; i++) // pop modules stack { RegModuleEnd(ctx); } } }
private static void RegClassType(IntPtr ctx, string name, string baseName, cs_function ctor, int nargs) { Native.duk_get_prop_string(ctx, -1, name); // stack: parentmodule, classtype/undefined if (Native.duk_is_undefined(ctx, -1) == 1) { Native.duk_pop(ctx); // pop undefined value, stack: parentmodule // create class type object {...} Native.duk_push_cs_function(ctx, (ctor != null) ? ctor : BindObjectsMgr.ctor, nargs); // stack: parentmodule, class type // create proto Native.duk_push_object(ctx); // stack: parentmodule, class type, proto object Native.duk_push_cs_function(ctx, BindObjectsMgr.dtor, 1 /*nargs*/); // stack: parentmodule, class type, proto object, finalizer fun Native.duk_set_finalizer(ctx, -2); // stack: parentmodule, class type, proto object Native.duk_get_prototype(ctx, -2); // stack: parentmodule, class type, proto object, class type default proto object Native.duk_get_prop_string(ctx, -1, "call"); // stack: parentmodule, class type, proto object, class type default proto object, call fun Native.duk_put_prop_string(ctx, -3, "call"); // stack: parentmodule, class type, proto object, class type default proto object Native.duk_get_prop_string(ctx, -1, "apply"); // stack: parentmodule, class type, proto object, class type default proto object, call fun Native.duk_put_prop_string(ctx, -3, "apply"); // stack: parentmodule, class type, proto object, class type default proto object Native.duk_pop(ctx); // stack: parentmodule, class type, proto object // attach base proto object to current class proto object // stack: parentmodule, class type, proto object if (baseName != "") { Native.duk_get_prop_string(ctx, -3, baseName); if (Native.duk_is_object(ctx, -1) == 0) // stack: stack: parentmodule, class type, proto object, base type/undefine { Native.duk_pop(ctx); // stack: stack: parentmodule, class type, proto object PushProtoType(ctx, baseName); // stack: stack: parentmodule, class type, proto object, base type/undefine if (Native.duk_is_object(ctx, -1) == 0) { Native.duk_pop_n(ctx, 4);// pop undefined value, proto object, class object, parentmodule object throw new Exception("Error: regist class " + name + " failed! Not find base class " + baseName + "."); } } // stack: stack: parentmodule, class type, proto object, base type Native.duk_get_prototype(ctx, -1); // stack: stack: parentmodule, class type, proto object, base type, base proto object Native.duk_set_prototype(ctx, -3); // stack: stack: parentmodule, class type, proto object, base type // proto object -> proto = base proto object Native.duk_pop(ctx); // stack: stack: parentmodule, class type, proto object } } else { Native.duk_get_prototype(ctx, -1); // stack: stack: parentmodule, class type, proto object } }
public static int duk_push_cs_function(IntPtr ctx, cs_function funcs, int nargs) { IntPtr funcs_ptr = Marshal.GetFunctionPointerForDelegate(funcs); return(duk_push_c_function(ctx, funcs_ptr, nargs)); }
public static void RegClassStart(IntPtr ctx, string name, string baseName = "", cs_function ctor = null, int nargs = 0) { _className = name; if (_moduleStack.Count == 0) { Native.duk_push_global_object(ctx); } RegClassType(ctx, name, baseName, ctor, nargs); }
public static void RegStaticCsFunction(IntPtr ctx, string func_name, cs_function funcs, int nargs = 0) { Native.duk_push_cs_function(ctx, funcs, nargs); Native.duk_put_prop_string(ctx, -3, func_name); }