static void OnRefCountedEvent(IntPtr ptr, RefCountedEvent rcEvent) { if (rcEvent == RefCountedEvent.Delete) { var referenceHolder = RefCountedCache.Get(ptr); 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(ptr); } else { reference.HandleNativeDelete(); } } else if (rcEvent == RefCountedEvent.Addref) { //if we have an object with this handle and it's reference is weak - then change it to strong. var referenceHolder = RefCountedCache.Get(ptr); referenceHolder?.MakeStrong(); } }
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; } }
public static void UnregisterObject(IntPtr handle) { RefCountedCache.Remove(handle); }
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; } }