Пример #1
0
        private void MoveToTransientPackage(IntPtr obj)
        {
            // Copy of UObjectBase.cpp UClassCompiledInDefer

            // Check if rooted?
            Native_UObjectBaseUtility.RemoveFromRoot(obj);
            Native_UObjectBaseUtility.ClearFlags(obj, EObjectFlags.Standalone | EObjectFlags.Public);

            IntPtr defaultObject = Native_UClass.GetDefaultObject(obj, false);

            if (defaultObject != IntPtr.Zero)
            {
                // Check if rooted?
                Native_UObjectBaseUtility.RemoveFromRoot(defaultObject);
                Native_UObjectBaseUtility.ClearFlags(defaultObject, EObjectFlags.Standalone | EObjectFlags.Public);
            }

            FName oldClassRename = NativeReflection.MakeUniqueObjectName(NativeReflection.GetTransientPackage(),
                                                                         Native_UObjectBase.GetClass(obj), new FName("USharpHotReload_" + Native_UObjectBase.GetFName(obj)));

            using (FStringUnsafe oldClassRenameUnsafe = new FStringUnsafe(oldClassRename.ToString()))
            {
                Native_UObject.Rename(obj, ref oldClassRenameUnsafe.Array, NativeReflection.GetTransientPackage(), ERenameFlags.None);
            }

            Native_UObjectBaseUtility.SetFlags(obj, EObjectFlags.Transient);
            Native_UObjectBaseUtility.AddToRoot(obj);
        }
Пример #2
0
        private static Invoker StartInvoker(object obj, InvokerHandlerType handlerType, Delegate handler, InvokerType type,
                                            ulong value, ulong repeatValue, CoroutineGroup group = CoroutineGroup.Tick, bool pool = PoolByDefault)
        {
            IntPtr  world    = IntPtr.Zero;
            UObject ownerObj = obj as UObject;

            if (ownerObj != null)
            {
                world = Native_UObject.GetWorld(ownerObj.Address);
                Debug.Assert(world != IntPtr.Zero, "UObject invokers must be objects with a UWorld reference (e.g. AActor) - " +
                             "this is so that the invoker can be stopped when the world is destroyed.");
            }

            Invoker invoker = pool ? InvokerPool.GetObject() : new Invoker();

            invoker.OwnerWorld = world;
            invoker.Owner      = obj;
            invoker.SetHandler(handlerType, handler);
            switch (type)
            {
            case InvokerType.Delay:
                TimeSpan time       = TimeSpan.FromTicks((long)value);
                TimeSpan repeatTime = TimeSpan.FromTicks((long)repeatValue);
                if (repeatTime != default(TimeSpan))
                {
                    invoker.SetTime(time, repeatTime);
                }
                else
                {
                    invoker.SetTime(time);
                }
                break;

            case InvokerType.Ticks:
                if (repeatValue != default(ulong))
                {
                    invoker.SetTicks(value, repeatValue);
                }
                else
                {
                    invoker.SetTicks(value);
                }
                break;

            case InvokerType.Frames:
                if (repeatValue != default(ulong))
                {
                    invoker.SetFrames(value, repeatValue);
                }
                else
                {
                    invoker.SetFrames(value);
                }
                break;
            }
            invoker.SetGroup(group);
            invoker.Start();
            return(invoker);
        }
Пример #3
0
        private IntPtr GetDefaultWorld()
        {
#if WITH_EDITORONLY_DATA
            FWorldContext worldContext = new FWorldContext(Native_UEditorEngine.GetPIEWorldContext(FGlobals.GEditor));
            return(worldContext.IsNull ? IntPtr.Zero : worldContext.CurrentWorld);
#else
            return(Native_UObject.GetWorld(FGlobals.GEngine));
#endif
        }
Пример #4
0
        public IntPtr GetFunctionAddress()
        {
            if (FunctionName == FName.None)
            {
                return(IntPtr.Zero);
            }
            IntPtr obj = Object.GetPtr();

            return(obj == IntPtr.Zero ? IntPtr.Zero : Native_UObject.FindFunction(obj, ref FunctionName));
        }
Пример #5
0
 private static bool ValidateFunction(UObject obj, FName functionName)
 {
     // Same validation that is in UKismetSystemLibrary::K2_SetTimer
     if (obj != null && functionName != FName.None)
     {
         IntPtr functionAddress = Native_UObject.FindFunction(obj.Address, ref functionName);
         if (functionAddress != IntPtr.Zero && Native_UFunction.Get_ParmsSize(functionAddress) > 0)
         {
             // User passed in a valid function, but one that takes parameters
             // FTimerDynamicDelegate expects zero parameters and will choke on execution if it tries
             // to execute a mismatched function
             FMessage.Log(ELogVerbosity.Warning, "SetTimer passed a function (" +
                          NativeReflection.GetPathName(functionAddress) + ") that expects parameters.");
             return(false);
         }
     }
     return(true);
 }
Пример #6
0
        public ManagedUnrealClass(Type type, string packageName, string className, IntPtr parentClass)
        {
            Type                        = type;
            PackageName                 = packageName;
            ClassName                   = className;
            ParentClass                 = parentClass;
            ClassConstructor            = Constructor;
            ClassVTableHelperCtorCaller = VTableHelperCtorCaller;
            ClassAddReferencedObjects   = AddReferencedObjects;

            // This is what FKismetCompilerContext::CleanAndSanitizeClass uses
            IntPtr parentClassWithin = Native_UClass.Get_ClassWithin(ParentClass);

            WithinClass = parentClassWithin != IntPtr.Zero ? parentClassWithin : Native_UObject.StaticClass();

            NonUSharpClassParentClass = FindFirstNonUSharpClassParentClass(ParentClass);
            NativeParentClass         = FindFirstNativeParentClass(ParentClass);
        }
Пример #7
0
        private static void OnPostWorldCleanup(IntPtr world, bool sessionEnded, bool cleanupResources)
        {
            List <UObject> objectsToRemove = new List <UObject>();

            foreach (KeyValuePair <UObject, List <Invoker> > obj in invokersByUObject)
            {
                if (obj.Key.Address != IntPtr.Zero)
                {
                    IntPtr objWorld = Native_UObject.GetWorld(obj.Key.Address);
                    if (objWorld == world)
                    {
                        objectsToRemove.Add(obj.Key);
                    }
                }
                else
                {
                    objectsToRemove.Add(obj.Key);
                }
            }
            foreach (UObject obj in objectsToRemove)
            {
                StopAllInvokers(obj, true);
            }
        }