public static bool duk_get_primitive(IntPtr ctx, int idx, out sbyte o) { o = (sbyte)DuktapeDLL.duk_get_int(ctx, idx); // no check return(true); }
protected static bool duk_match_type(IntPtr ctx, int idx, Type type) { if (type == null) { return(true); } if (type == typeof(object)) { return(true); } if (type == typeof(Type)) { Type otype; return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type // return otype == type; } var jstype = DuktapeDLL.duk_get_type(ctx, idx); switch (jstype) { // case duk_type_t.DUK_TYPE_NONE: case duk_type_t.DUK_TYPE_OBJECT: // objects, arrays, functions, threads if (DuktapeDLL.duk_is_array(ctx, idx)) { if (!type.IsArray && !_assignableFromArray.Contains(type)) { return(false); } } else if (DuktapeDLL.duk_is_function(ctx, idx)) { //TODO: 完善处理 delegate return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate)); } else if (DuktapeDLL.duk_is_thread(ctx, idx)) { return(false); } int refid; //TODO: 根据记录在jsobject 上的 分类标记 做进一步分支 (类型, 实例, 或特定优化类型) if (duk_get_native_refid(ctx, idx, out refid)) { var cache = DuktapeVM.GetObjectCache(ctx); return(cache.MatchObjectType(refid, type)); } return(true); case duk_type_t.DUK_TYPE_NUMBER: return(type.IsPrimitive || type.IsEnum); case duk_type_t.DUK_TYPE_STRING: return(type == typeof(string)); case duk_type_t.DUK_TYPE_UNDEFINED: case duk_type_t.DUK_TYPE_NULL: return(!type.IsValueType && !type.IsPrimitive); case duk_type_t.DUK_TYPE_BOOLEAN: return(type == typeof(bool)); case duk_type_t.DUK_TYPE_BUFFER: return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */); case duk_type_t.DUK_TYPE_POINTER: // return type == typeof(DuktapePointer); case duk_type_t.DUK_TYPE_LIGHTFUNC: default: return(false); } }
protected static bool duk_match_type(IntPtr ctx, int idx, Type type) { if (type == null) { return(true); } if (type == typeof(object)) { return(true); } if (type == typeof(Type)) { Type otype; return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type // return otype == type; } var jstype = DuktapeDLL.duk_get_type(ctx, idx); switch (jstype) { // case duk_type_t.DUK_TYPE_NONE: case duk_type_t.DUK_TYPE_OBJECT: // objects, arrays, functions, threads if (DuktapeDLL.duk_is_array(ctx, idx)) { if (!type.IsArray && !_assignableFromArray.Contains(type)) { return(false); } } else if (DuktapeDLL.duk_is_function(ctx, idx)) { //TODO: 完善处理 delegate return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate)); } else if (DuktapeDLL.duk_is_thread(ctx, idx)) { return(false); } int refid; if (duk_get_native_refid(ctx, idx, out refid)) { var cache = DuktapeVM.GetObjectCache(ctx); return(cache.MatchObjectType(refid, type)); } int typeid; if (DuktapeDLL.duk_unity_get_type_refid(ctx, idx, out typeid)) { var vm = DuktapeVM.GetVM(ctx); var eType = vm.GetExportedType(typeid); if (eType != null) { // Debug.LogFormat("match type? {0} {1} {2}", eType, type, typeid); return(eType == type); } // Debug.LogFormat("match type {0} with typeid {1}", type, typeid); } return(type.IsSubclassOf(typeof(DuktapeValue))); case duk_type_t.DUK_TYPE_NUMBER: return(type.IsPrimitive || type.IsEnum); case duk_type_t.DUK_TYPE_STRING: return(type == typeof(string)); case duk_type_t.DUK_TYPE_UNDEFINED: case duk_type_t.DUK_TYPE_NULL: return(!type.IsValueType && !type.IsPrimitive); case duk_type_t.DUK_TYPE_BOOLEAN: return(type == typeof(bool)); case duk_type_t.DUK_TYPE_BUFFER: return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */); case duk_type_t.DUK_TYPE_POINTER: // return type == typeof(DuktapePointer); case duk_type_t.DUK_TYPE_LIGHTFUNC: default: return(false); } }
protected static void duk_end_class(IntPtr ctx) { DuktapeDLL.duk_pop_2(ctx); // remove [ctor, prototype] // Debug.LogFormat("end class {0}", DuktapeDLL.duk_get_top(ctx)); }
protected static int object_private_ctor(IntPtr ctx) { return(DuktapeDLL.duk_generic_error(ctx, "cant call constructor on this type")); }
public static void duk_end_namespace(IntPtr ctx) { DuktapeDLL.duk_pop(ctx); // Debug.LogFormat("end namespace {0}", DuktapeDLL.duk_get_top(ctx)); }
protected static void duk_end_special(IntPtr ctx) { DuktapeDLL.duk_pop_2(ctx); // remove [ctor, prototype] }
private IEnumerator _InitializeStep(IDuktapeListener listener, int step) { DuktapeDLL.duk_push_global_object(ctx); DuktapeJSBuiltins.reg(ctx); listener?.OnTypesBinding(this); var ctxAsArgs = new object[] { ctx }; var bindingTypes = new List <Type>(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int assemblyIndex = 0, assemblyCount = assemblies.Length; assemblyIndex < assemblyCount; assemblyIndex++) { var assembly = assemblies[assemblyIndex]; try { if (assembly.IsDynamic) { continue; } var exportedTypes = assembly.GetExportedTypes(); for (int i = 0, size = exportedTypes.Length; i < size; i++) { var type = exportedTypes[i]; #if UNITY_EDITOR if (type.IsDefined(typeof(JSAutoRunAttribute), false)) { try { var run = type.GetMethod("Run", BindingFlags.Static | BindingFlags.Public); if (run != null) { run.Invoke(null, null); } } catch (Exception exception) { Debug.LogWarning($"JSAutoRun failed: {exception}"); } continue; } #endif var attributes = type.GetCustomAttributes(typeof(JSBindingAttribute), false); if (attributes.Length == 1) { var jsBinding = attributes[0] as JSBindingAttribute; if (jsBinding.Version == 0 || jsBinding.Version == VERSION) { bindingTypes.Add(type); } else { if (listener != null) { listener.OnBindingError(this, type); } } } } } catch (Exception e) { Debug.LogErrorFormat("assembly: {0}, {1}", assembly, e); } } var numRegInvoked = bindingTypes.Count; for (var i = 0; i < numRegInvoked; ++i) { var type = bindingTypes[i]; var reg = type.GetMethod("reg"); if (reg != null) { reg.Invoke(null, ctxAsArgs); if (listener != null) { listener.OnProgress(this, i, numRegInvoked); } if (i % step == 0) { yield return(null); } } } if (listener != null) { listener.OnBinded(this, numRegInvoked); } // Debug.LogFormat("exported {0} classes", _exported.Count); // 设置导出类的继承链 foreach (var kv in _exported) { var type = kv.Key; var baseType = type.BaseType; if (baseType == null) { // Debug.Log($"baseType is null, for {type}"); continue; } var fn = kv.Value; fn.PushPrototype(ctx); if (PushChainedPrototypeOf(ctx, baseType)) { // Debug.LogFormat($"set {type} super {baseType}"); DuktapeDLL.duk_set_prototype(ctx, -2); } else { Debug.LogWarning($"fail to push prototype, for {type}: {baseType}"); } DuktapeDLL.duk_pop(ctx); } DuktapeJSBuiltins.postreg(ctx); DuktapeDLL.duk_pop(ctx); // pop global _updateTimer = DuktapeRunner.SetInterval(this.OnUpdate, 100); if (listener != null) { listener.OnLoaded(this); } }
public static void duk_push_structvalue(IntPtr ctx, Quaternion o) { DuktapeDLL.duk_unity_push_quaternion(ctx, o.x, o.y, o.z, o.w); }
public void PushProperty(IntPtr ctx, string property) { this.Push(ctx); // push this DuktapeDLL.duk_get_prop_string(ctx, -1, property); DuktapeDLL.duk_remove(ctx, -2); // remove this }
public void GetMemoryState(out uint count, out uint size, out uint poolSize) { poolSize = _memAllocPoolSize; DuktapeDLL.duk_unity_get_memory_state(ctx, out count, out size); }
private static void duk_unity_unref(IntPtr ctx, uint refid, object target) { DuktapeDLL.duk_unity_unref(ctx, refid); }
public void PushProperty(IntPtr ctx, uint index) { this.Push(ctx); // push this DuktapeDLL.duk_get_prop_index(ctx, -1, index); DuktapeDLL.duk_remove(ctx, -2); // remove this }
public static bool duk_get_var(IntPtr ctx, int idx, out object o) { var jstype = DuktapeDLL.duk_get_type(ctx, idx); switch (jstype) { case duk_type_t.DUK_TYPE_BOOLEAN: /* ECMAScript boolean: 0 or 1 */ { o = DuktapeDLL.duk_get_boolean(ctx, idx); return(true); } case duk_type_t.DUK_TYPE_NUMBER: /* ECMAScript number: double */ { o = DuktapeDLL.duk_get_number(ctx, idx); return(true); } case duk_type_t.DUK_TYPE_STRING: /* ECMAScript string: CESU-8 / extended UTF-8 encoded */ { o = DuktapeDLL.duk_get_string(ctx, idx); return(true); } case duk_type_t.DUK_TYPE_OBJECT: /* ECMAScript object: includes objects, arrays, functions, threads */ { if (DuktapeDLL.duk_is_function(ctx, idx)) { DuktapeFunction func; var r = duk_get_classvalue(ctx, idx, out func); o = func; return(r); } if (duk_get_cached_object(ctx, idx, out o)) { return(true); } else { DuktapeObject val; var r = duk_get_classvalue(ctx, idx, out val); o = val; return(r); } } case duk_type_t.DUK_TYPE_BUFFER: /* fixed or dynamic, garbage collected byte buffer */ { uint length; var pointer = DuktapeDLL.duk_unity_get_buffer_data(ctx, idx, out length); var buffer = new byte[length]; o = buffer; Marshal.Copy(pointer, buffer, 0, (int)length); return(true); } case duk_type_t.DUK_TYPE_POINTER: /* raw void pointer */ case duk_type_t.DUK_TYPE_LIGHTFUNC: /* lightweight function pointer */ throw new NotImplementedException(); case duk_type_t.DUK_TYPE_NONE: /* no value, e.g. invalid index */ o = null; return(false); case duk_type_t.DUK_TYPE_UNDEFINED: /* ECMAScript undefined */ case duk_type_t.DUK_TYPE_NULL: /* ECMAScript null */ o = null; return(true); } o = null; return(false); }
private static void duk_unity_unref(IntPtr ctx, uint refid, object target) { DuktapeVM.GetObjectCache(ctx).RemoveJSValue(target); DuktapeDLL.duk_unity_unref(ctx, refid); }
public static void duk_push_primitive(IntPtr ctx, bool o) { DuktapeDLL.duk_push_boolean(ctx, o); }
public static void duk_begin_namespace(IntPtr ctx, string el1, string el2) // [parent] { duk_begin_namespace(ctx, el1); // [parent, el1] duk_begin_namespace(ctx, el2); // [parent, el1, el2] DuktapeDLL.duk_remove(ctx, -2); // [parent, el2] }
public static void duk_push_primitive(IntPtr ctx, string o) { DuktapeDLL.duk_push_string(ctx, o); }
protected static void duk_end_object(IntPtr ctx) { DuktapeDLL.duk_pop(ctx); }
public static void duk_push_primitive(IntPtr ctx, uint o) { DuktapeDLL.duk_push_uint(ctx, o); }
protected static void duk_begin_class(IntPtr ctx, string typename, Type type, DuktapeDLL.duk_c_function ctor) { // Debug.LogFormat("begin class {0}", DuktapeDLL.duk_get_top(ctx)); DuktapeDLL.duk_push_c_function(ctx, ctor, DuktapeDLL.DUK_VARARGS); // [ctor] DuktapeDLL.duk_dup(ctx, -1); // Debug.LogFormat("begin check {0}", DuktapeDLL.duk_get_top(ctx)); DuktapeDLL.duk_dup(ctx, -1); var refid = DuktapeVM.GetVM(ctx).AddExported(type, new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx))); // DuktapeDLL.duk_push_uint(ctx, refid); DuktapeDLL.duk_unity_set_type_refid(ctx, -2, refid); // DuktapeDLL.duk_put_prop_string(ctx, -3, DuktapeVM.OBJ_PROP_EXPORTED_REFID); // Debug.LogFormat("end check {0}", DuktapeDLL.duk_get_top(ctx)); DuktapeDLL.duk_put_prop_string(ctx, -3, typename); DuktapeDLL.duk_push_object(ctx); // [ctor, prototype] DuktapeDLL.duk_dup_top(ctx); // [ctor, prototype, prototype] DuktapeDLL.duk_push_c_function(ctx, object_dtor, 1); DuktapeDLL.duk_set_finalizer(ctx, -3); // set prototype finalizer DuktapeDLL.duk_put_prop_string(ctx, -3, "prototype"); // [ctor, prototype] }
public static void duk_push_primitive(IntPtr ctx, double o) { DuktapeDLL.duk_push_number(ctx, o); }
protected static void duk_add_method(IntPtr ctx, string name, DuktapeDLL.duk_c_function func, int idx) { idx = DuktapeDLL.duk_normalize_index(ctx, idx); DuktapeDLL.duk_push_c_function(ctx, func, DuktapeDLL.DUK_VARARGS); DuktapeDLL.duk_put_prop_string(ctx, idx, name); }
public static void duk_push_structvalue(IntPtr ctx, LayerMask o) { DuktapeDLL.duk_push_int(ctx, (int)o); }
// 无命名空间, 直接外围对象作为容器 (通常是global) public static void duk_begin_namespace(IntPtr ctx) // [parent] { // Debug.LogFormat("begin namespace {0}", DuktapeDLL.duk_get_top(ctx)); DuktapeDLL.duk_dup_top(ctx); // [parent, parent] }
public static void duk_push_structvalue(IntPtr ctx, Color32 o) { DuktapeDLL.duk_unity_push_color32(ctx, o.r, o.g, o.b, o.a); }
public static int duk_enableStacktrace(IntPtr ctx) { printStacktrace = DuktapeDLL.duk_require_boolean(ctx, 0); return(0); }
public static void duk_push_structvalue(IntPtr ctx, Vector2 o) { DuktapeDLL.duk_unity_push_vector2(ctx, o.x, o.y); }
public static bool duk_get_primitive(IntPtr ctx, int idx, out uint o) { o = DuktapeDLL.duk_get_uint(ctx, idx); // no check return(true); }
public static bool duk_get_structvalue(IntPtr ctx, int idx, out LayerMask o) { o = (LayerMask)DuktapeDLL.duk_get_int(ctx, idx); return(true); }