diff --git a/Source/Engine/Scripting/Attributes/ModuleInitializerAttribute.cs b/Source/Engine/Scripting/Attributes/ModuleInitializerAttribute.cs new file mode 100644 index 000000000..119a2a6b7 --- /dev/null +++ b/Source/Engine/Scripting/Attributes/ModuleInitializerAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. + +using System; + +namespace FlaxEngine +{ + /// + /// Indicates that a static class initializes the code module. All static, void and parameterless methods within the class will be invoked upon module loading. + /// + [AttributeUsage(AttributeTargets.Class)] + public sealed class ModuleInitializerAttribute : Attribute + { + } +} diff --git a/Source/Engine/Scripting/BinaryModule.cpp b/Source/Engine/Scripting/BinaryModule.cpp index 8a7f8ddbe..44ec43ad9 100644 --- a/Source/Engine/Scripting/BinaryModule.cpp +++ b/Source/Engine/Scripting/BinaryModule.cpp @@ -947,6 +947,28 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly) InitType(mclass); } } + + // Invoke module initializers + if (flaxEngine->Assembly->IsLoaded() && this != flaxEngine) + { + const MClass* attribute = flaxEngine->Assembly->GetClass("FlaxEngine.ModuleInitializerAttribute"); + ASSERT_LOW_LAYER(attribute); + for (auto i = classes.Begin(); i.IsNotEnd(); ++i) + { + MClass* mclass = i->Value; + if (mclass->IsStatic() && !mclass->IsInterface() && mclass->HasAttribute(attribute)) + { + const auto& methods = mclass->GetMethods(); + for (const MMethod* method : methods) + { + if (method->GetParametersCount() == 0) + { + method->Invoke(nullptr, nullptr, nullptr); + } + } + } + } + } #endif }