public void ReturnObject(UObjectRef obj) { obj.Reset(); // TODO: Limit the pool size? pool.Push(obj); }
public IntPtr Set(T value) { UObjectRef newObjRef = value == null ? null : value.objRef; if (newObjRef != objRef || Value.objRef != objRef) { if (newObjRef != null) { objRef = newObjRef; Value = objRef.Managed as T; if (Value == null || Value.objRef != objRef) { objRef = null; Value = null; return(IntPtr.Zero); } return(objRef.Native); } else { objRef = null; Value = null; return(IntPtr.Zero); } } else { return(objRef == null ? IntPtr.Zero : objRef.Native); } }
private static void OnAddExisting(IntPtr native, IntPtr gcHandlePtr) { if (!References.ContainsKey(native)) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); UObjectRef objRef = (UObjectRef)gcHandle.Target; References.Add(native, objRef); } }
public UObjectRef New(IntPtr native, Type type, bool isKnownType, int internalIndex) { UObjectRef result = null; if (pool.Count > 0) { result = pool.Pop(); } else { result = new UObjectRef(); } result.Initialize(native, type, isKnownType, internalIndex); return(result); }
private static void OnRemove(IntPtr gcHandlePtr) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); UObjectRef objRef = (UObjectRef)gcHandle.Target; FMessage.Log("GC " + (objRef.Managed == null ? "null" : objRef.Managed.GetType().ToString()) + " (" + gcHandlePtr.ToString("X16") + ")"); objRef.Managed.ReleaseInjectedInterfaces(); objRef.Managed.objRef = null; // This will make UObject.IsDestroyed true objRef.Managed.Address = IntPtr.Zero; // Reset the address References.Remove(objRef.Native); gcHandle.Free(); // Return the objRef to the pool (this will also reset the objRef state back to empty) objRefPool.ReturnObject(objRef); }
private static void OnRemove(IntPtr gcHandlePtr) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); UObjectRef objRef = (UObjectRef)gcHandle.Target; //FMessage.Log("GC " + (objRef.Managed == null ? "null" : objRef.Managed.GetType().ToString()) + " (GCHandle: " + gcHandlePtr.ToString("X16") + " ptr: " + objRef.Native.ToString("X16") + ")"); Coroutine.RemoveObjectByGC(objRef.Managed); Invoker.RemoveObjectByGC(objRef.Managed); objRef.Managed.ReleaseInjectedInterfaces(); objRef.Managed.objRef = null; // This will make UObject.IsDestroyed true objRef.Managed.Address = IntPtr.Zero; // Reset the address #if ARRAY_GC References[objRef.InternalIndex] = null; #else References.Remove(objRef.Native); #endif gcHandle.Free(); // Return the objRef to the pool (this will also reset the objRef state back to empty) objRefPool.ReturnObject(objRef); }
public T Update(IntPtr address) { if (objRef != null) { if (address == objRef.Native && Value.objRef == objRef) { return(Value); } Value = null; } objRef = GCHelper.FindRef(address); if (objRef != null) { Value = objRef.Managed as T; if (Value == null || Value.objRef != objRef) { objRef = null; Value = null; } } return(Value); }
public static unsafe UObjectRef FindRef(IntPtr native) { CheckAvailable(); if (native == IntPtr.Zero) { return(null); } #if ARRAY_GC int objectInternalIndex = *(int *)(native + objectInternalIndexOffset); UObjectRef objRef = References.Count > objectInternalIndex ? References[objectInternalIndex] : null; if (objRef == null) { IntPtr gcHandlePtr = Add(native); if (gcHandlePtr != IntPtr.Zero) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); objRef = (UObjectRef)gcHandle.Target; } } return(objRef); #else UObjectRef objRef; if (!References.TryGetValue(native, out objRef)) { IntPtr gcHandlePtr = Add(native); if (gcHandlePtr != IntPtr.Zero) { GCHandle gcHandle = GCHandle.FromIntPtr(gcHandlePtr); objRef = (UObjectRef)gcHandle.Target; } } return(objRef); #endif }
public static IInterface New(Type type, UObjectRef objRef) { Type implType; Stack <IInterfaceImpl> pool; if (interfaceTypes.TryGetValue(type, out implType) && pools.TryGetValue(implType, out pool)) { if (pool.Count > 0) { IInterfaceImpl instance = pool.Pop(); instance.SetObj(objRef); return(instance); } else { // TODO: Use a faster way of constructing an instance IInterfaceImpl instance = (IInterfaceImpl)Activator.CreateInstance(implType); instance.SetObj(objRef); return(instance); } } return(null); }
public static UObject Find(IntPtr native) { UObjectRef objRef = FindRef(native); return(objRef == null ? null : objRef.Managed); }
private static unsafe IntPtr OnAdd(IntPtr native) { UObjectRef objRef = null; int objectInternalIndex = *(int *)(native + objectInternalIndexOffset); #if ARRAY_GC while (References.Count <= objectInternalIndex) { References.Add(null); } if (References[objectInternalIndex] == null) #else if (!References.TryGetValue(native, out objRef)) #endif { bool isKnownType; Type type = UClass.GetFirstKnownType(native, out isKnownType, false); if (type == null) { // This probably means the given address is not valid (check IsValid/IsValidLowLevel/IsValidLowLevelFast ?) string className = string.Empty; string fullName = string.Empty; try { using (FStringUnsafe classNameUnsafe = new FStringUnsafe()) { Native_UObjectBaseUtility.GetName(Native_UObjectBase.GetClass(native), ref classNameUnsafe.Array); className = classNameUnsafe.Value; } } catch { } try { using (FStringUnsafe fullNameUnsafe = new FStringUnsafe()) { Native_UObjectBaseUtility.GetFullName(native, IntPtr.Zero, ref fullNameUnsafe.Array); fullName = fullNameUnsafe.Value; } } catch { } // Get a smaller stack snippet StackTrace stack = null; try { stack = new StackTrace(4); } catch { } string error = string.Format("[GCHelper-Error] Couldn't find type for requested UObject. Address: {0} (0x{1}) Name: \"{2}\" FullName: \"{3}\" Stack:\r\n{4}", native.ToInt32(), native.ToInt32().ToString("X8"), className, fullName, stack); FMessage.Log(ELogVerbosity.Error, error); Debug.Assert(false, error); return(IntPtr.Zero); } if (type.IsInterface) { // Validate that we are getting a UInterface and we aren't doing something very wrong. Debug.Assert(Native_UObjectBaseUtility.IsA(native, UClass.GetClassAddress(type))); // This should be a UInterface instance. We might want to do something more complex here // where interfaces inherit from other interfaces. type = typeof(UInterface); } objRef = objRefPool.New(native, type, isKnownType, objectInternalIndex); #if ARRAY_GC References[objectInternalIndex] = objRef; #else References.Add(native, objRef); #endif return(GCHandle.ToIntPtr(objRef.ManagedHandle)); } return(GCHandle.ToIntPtr(objRef.ManagedHandle)); }
internal void SetObj(UObjectRef objRef) { cachedObj.Set(objRef); }