Example #1
0
        public static T LookupObject <T>(IntPtr ptr, bool createIfNotFound = true) where T : UrhoObject
        {
            if (ptr == IntPtr.Zero)
            {
                return(null);
            }

            var referenceHolder = RefCountedCache.Get(ptr);
            var reference       = referenceHolder?.Reference;

            if (reference is T)             //possible collisions
            {
                return((T)reference);
            }

            if (!createIfNotFound)
            {
                return(null);
            }

            var name     = Marshal.PtrToStringAnsi(UrhoObject.UrhoObject_GetTypeName(ptr));
            var type     = FindTypeByName(name);
            var typeInfo = type.GetTypeInfo();

            if (typeInfo.IsSubclassOf(typeof(Component)) || type == typeof(Component))
            {
                //TODO: special case, handle managed subclasses
            }

            var urhoObject = (T)Activator.CreateInstance(type, ptr);

            return(urhoObject);
        }
Example #2
0
 internal static void Cleanup()
 {
     IsClosing = true;
     RefCountedCache.Clean();
     GC.Collect();
     GC.WaitForPendingFinalizers();
     GC.Collect();
 }
Example #3
0
 internal static void Cleanup(bool disposeContext = true)
 {
     IsClosing = true;
     RefCountedCache.Clean(disposeContext);
     GC.Collect();
     GC.WaitForPendingFinalizers();
     GC.Collect();
 }
Example #4
0
        public static T LookupRefCounted <T> (IntPtr ptr, bool createIfNotFound = true) where T : RefCounted
        {
            if (ptr == IntPtr.Zero)
            {
                return(null);
            }

            var reference = RefCountedCache.Get(ptr)?.Reference;

            if (reference is T)
            {
                return((T)reference);
            }

            if (!createIfNotFound)
            {
                return(null);
            }

            var refCounted = (T)Activator.CreateInstance(typeof(T), ptr);

            return(refCounted);
        }
Example #5
0
        static void OnNativeCallback(CallbackType type, IntPtr target, IntPtr param1, int param2, string param3)
        {
            const string typeNameKey = "SharpTypeName";

            // while app is not started - accept only Log callbacks
            if (!isStarted && type != CallbackType.Log_Write)
            {
                return;
            }

            switch (type)
            {
            //Component:
            case CallbackType.Component_OnSceneSet:
            {
                var component = LookupObject <Component>(target, false);
                component?.OnSceneSet(LookupObject <Scene>(param1, false));
            }
            break;

            case CallbackType.Component_SaveXml:
            {
                var component = LookupObject <Component>(target, false);
                if (component != null && component.TypeName != component.GetType().Name)
                {
                    var xmlElement = new XmlElement(param1);
                    xmlElement.SetString(typeNameKey, component.GetType().AssemblyQualifiedName);
                    component.OnSerialize(new XmlComponentSerializer(xmlElement));
                }
            }
            break;

            case CallbackType.Component_LoadXml:
            {
                var xmlElement = new XmlElement(param1);
                var name       = xmlElement.GetAttribute(typeNameKey);
                if (!string.IsNullOrEmpty(name))
                {
                    Component component;
                    try
                    {
                        var typeObj = Type.GetType(name);
                        if (typeObj == null)
                        {
                            Log.Write(LogLevel.Warning, $"{name} doesn't exist. Probably was removed by Linker. Add it to a some LinkerPleaseInclude.cs in case if you need it.");
                            return;
                        }
                        component = (Component)Activator.CreateInstance(typeObj, target);
                    }
                    catch (Exception exc)
                    {
                        throw new InvalidOperationException($"{name} doesn't override constructor Component(IntPtr handle).", exc);
                    }
                    component.OnDeserialize(new XmlComponentSerializer(xmlElement));
                    if (component.Node != null)
                    {
                        component.AttachedToNode(component.Node);
                    }
                }
            }
            break;

            case CallbackType.Component_AttachedToNode:
            {
                var component = LookupObject <Component>(target, false);
                component?.AttachedToNode(component.Node);
            }
            break;

            case CallbackType.Component_OnNodeSetEnabled:
            {
                var component = LookupObject <Component>(target, false);
                component?.OnNodeSetEnabled();
            }
            break;


            //RefCounted:

            case CallbackType.RefCounted_AddRef:
            {
                //if we have an object with this handle and it's reference is weak - then change it to strong.
                var referenceHolder = RefCountedCache.Get(target);
                referenceHolder?.MakeStrong();
            }
            break;

            case CallbackType.RefCounted_Delete:
            {
                var referenceHolder = RefCountedCache.Get(target);
                if (referenceHolder == null)
                {
                    return;                                     //we don't have this object in the cache so let's just skip it
                }
                var reference = referenceHolder.Reference;
                if (reference == null)
                {
                    // seems like the reference was Weak and GC has removed it - remove item from the dictionary
                    RefCountedCache.Remove(target);
                }
                else
                {
                    reference.HandleNativeDelete();
                }
            }
            break;

            case CallbackType.Log_Write:
                Urho.Application.ThrowUnhandledException(
                    new Exception(param3 + ". You can omit this exception by subscribing to Urho.Application.UnhandledException event and set Handled property to True.\nApplicationOptions: " + Application.CurrentOptions));
                break;
            }
        }
Example #6
0
 public static void RegisterObject(RefCounted refCounted)
 {
     RefCountedCache.Add(refCounted);
 }
Example #7
0
 public static void UnregisterObject(IntPtr handle)
 {
     RefCountedCache.Remove(handle);
 }
Example #8
0
        static void OnNativeCallback(CallbackType type, IntPtr target, IntPtr param1, IntPtr param2, IntPtr param3, IntPtr param4)
        {
            const string typeNameKey = "SharpTypeName";

            switch (type)
            {
            //Component:
            case CallbackType.Component_OnSceneSet:
            {
                var component = LookupObject <Component>(target, false);
                component?.OnSceneSet(LookupObject <Scene>(param1, false));
            }
            break;

            case CallbackType.Component_SaveXml:
            {
                var component = LookupObject <Component>(target, false);
                if (component != null && component.TypeName != component.GetType().Name)
                {
                    var xmlElement = new XmlElement(param1);
                    xmlElement.SetString(typeNameKey, component.GetType().AssemblyQualifiedName);
                    component.OnSerialize(new XmlComponentSerializer(xmlElement));
                }
            }
            break;

            case CallbackType.Component_LoadXml:
            {
                var xmlElement = new XmlElement(param1);
                var name       = xmlElement.GetAttribute(typeNameKey);
                if (!string.IsNullOrEmpty(name))
                {
                    Component component;
                    try
                    {
                        component = (Component)Activator.CreateInstance(Type.GetType(name), target);
                    }
                    catch (Exception exc)
                    {
                        throw new InvalidOperationException($"{name} doesn't override constructor Component(IntPtr handle).", exc);
                    }
                    component.OnDeserialize(new XmlComponentSerializer(xmlElement));
                    if (component.Node != null)
                    {
                        component.AttachedToNode(component.Node);
                    }
                }
            }
            break;

            case CallbackType.Component_AttachedToNode:
            {
                var component = LookupObject <Component>(target, false);
                component?.AttachedToNode(component.Node);
            }
            break;

            case CallbackType.Component_OnNodeSetEnabled:
            {
                var component = LookupObject <Component>(target, false);
                component?.OnNodeSetEnabled();
            }
            break;


            //RefCounted:

            case CallbackType.RefCounted_AddRef:
            {
                //if we have an object with this handle and it's reference is weak - then change it to strong.
                var referenceHolder = RefCountedCache.Get(target);
                referenceHolder?.MakeStrong();
            }
            break;

            case CallbackType.RefCounted_Delete:
            {
                var referenceHolder = RefCountedCache.Get(target);
                if (referenceHolder == null)
                {
                    return;                                     //we don't have this object in the cache so let's just skip it
                }
                var reference = referenceHolder.Reference;
                if (reference == null)
                {
                    // seems like the reference was Weak and GC has removed it - remove item from the dictionary
                    RefCountedCache.Remove(target);
                }
                else
                {
                    reference.HandleNativeDelete();
                }
            }
            break;
            }
        }