예제 #1
0
        public static JavaScriptValue CreateExternalWithPrototype <T>(T obj, JavaScriptValue prototype, Action onFree = null)
        {
            if (((System.Object)obj) == null || ((System.Object)obj).Equals(null))
            {
                return(JavaScriptValue.Null);
            }
            // Unity likes to create "null" objects where their ToString() == "null" but it's not technically the C# value null
            // so we use Object which UnityEntity.Object extends Equals on
            // This will also handle Nullable<T> "nullOrValue?" values

            // TODO things that pass in Nullable<T> should be casted to T since Nullable<> is redundant from us removing null ^

            Type     type = obj.GetType(); // this has to be GetType and not typeof(T) because T will be System.Object sometimes
            GCHandle handle;

            if (type.IsValueType && !type.IsEnum) // if a struct
            {
                handle = GCHandle.Alloc(new Bridge.Box <T>(obj));
            }
            else
            {
                handle = GCHandle.Alloc(obj);
            }

            IntPtr ptr = GCHandle.ToIntPtr(handle);

            if (onFree != null)
            {
                freeCallbacks[ptr] = onFree;
            }

            return(JavaScriptValue.CreateExternalObjectWithPrototype(
                       ptr,
                       (intPtr) => {
                try {
                    if (freeCallbacks.ContainsKey(intPtr))
                    {
                        Action onFreeForPtr = freeCallbacks[intPtr];
                        freeCallbacks.Remove(intPtr);
                        onFreeForPtr();
                    }
                } finally {
                    if (freeCallbacks.ContainsKey(intPtr))
                    {
                        freeCallbacks.Remove(intPtr);
                    }
                    GCHandle.FromIntPtr(intPtr).Free();
                }
            },
                       prototype
                       ));
        }