예제 #1
0
        /// <summary>
        /// Register all native functions with managed code
        /// </summary>
        /// <param name="registerFunctionsAddr">The address of the RegisterFunctions method defined in native code</param>
        public static void RegisterFunctions(IntPtr registerFunctionsAddr)
        {
            if (!EntryPoint.Preloaded)
            {
                string namespaceName = typeof(NativeFunctions).Namespace;
                foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
                {
                    if (type.IsClass && type.IsAbstract && type.IsSealed && type.Name.StartsWith("Native_") && type.Namespace == namespaceName)
                    {
                        // Native_FName -> Export_FName_XXXXX
                        string nativeFunctionPrefix = "Export" + type.Name.Replace("Native", string.Empty) + "_";

                        foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                        {
                            if (field.IsStatic && field.FieldType.IsSubclassOf(typeof(Delegate)))
                            {
                                functions.Add(nativeFunctionPrefix + field.Name, field);
                            }
                        }
                    }
                }

                // Call the native RegisterFunctions method with our managed RegisterFunction as the callback
                Del_RegisterFunctions registerFunctions = (Del_RegisterFunctions)Marshal.GetDelegateForFunctionPointer(
                    registerFunctionsAddr, typeof(Del_RegisterFunctions));

                registerFunctions(Marshal.GetFunctionPointerForDelegate(registerFunction));

                // Highest (these may be called from a thread other than the game thread, don't access UObject methods)
                FBuild.OnNativeFunctionsRegistered();
                FGlobals.OnNativeFunctionsRegistered();
                Classes.OnNativeFunctionsRegistered();
                BoolMarshaler.OnNativeFunctionsRegistered();
                FStringMarshaler.OnNativeFunctionsRegistered();
                InputCore.FKey.OnNativeFunctionsRegistered();
                FFrame.OnNativeFunctionsRegistered();

                // Validate native struct sizes match the managed struct sizes before running any handlers
                // NOTE: This MUST come after FStringMarshaler.OnNativeFunctionsRegistered as this requires TCHAR size
                StructValidator.ValidateStructs();
            }

            if (!EntryPoint.Preloading)
            {
                Debug.Assert(FThreading.IsInGameThread(), "Load/hotreload should be on the game thread");

                // Highest = Used for initializing very important data required by other functions.
                // VeryHigh = Used for initializing data before UObject classes are loaded.
                // High = This is when UObject classes are loaded. Don't access UObjects at this or any higher priority.
                // Medium = UObject classes are loaded and available to use at this priority.

                // If GEngine is null we need to bind OnPostEngineInit to load anything which requires GEngine
                if (FGlobals.GEngine == IntPtr.Zero)
                {
                    FCoreDelegates.OnPostEngineInit.Bind(OnPostEngineInit);
                }

                // Highest
                GCHelper.OnNativeFunctionsRegistered();
                FMessage.OnNativeFunctionsRegistered();
                Engine.FTimerManagerCache.OnNativeFunctionsRegistered();
                WorldTimeHelper.OnNativeFunctionsRegistered();
                if (FGlobals.GEngine != IntPtr.Zero)
                {
                    // Needs GEngine for binding delegates
                    StaticVarManager.OnNativeFunctionsRegistered();
                    Coroutine.OnNativeFunctionsRegistered();
                }

                // VeryHigh
                NativeReflection.OnNativeFunctionsRegistered();// Requires Classes to be initialized

                // High
                OnNativeFunctionsRegistered();

                // Low
                EngineLoop.OnNativeFunctionsRegistered();

                // Lowest
                CodeGenerator.OnNativeFunctionsRegistered();
#if WITH_USHARP_TESTS
                Tests.Tests.OnNativeFunctionsRegistered();
#endif
            }
        }
예제 #2
0
 /// <summary>
 /// Callback where GEngine is initialized and is safe to use
 /// </summary>
 private static void OnPostEngineInit()
 {
     StaticVarManager.OnNativeFunctionsRegistered();
     Coroutine.OnNativeFunctionsRegistered();
 }