// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Scripting/ScriptingType.h" #include "Types.h" template class ThreadLocal; /// /// Embedded managed scripting runtime service. /// class FLAXENGINE_API Scripting { DECLARE_SCRIPTING_TYPE_NO_SPAWN(Scripting); friend ScriptingObject; friend BinaryModule; public: /// /// Action fired when scripting loads a binary module (eg. with game scripts). /// static Delegate BinaryModuleLoaded; /// /// Action fired on scripting engine loaded (always main thread). /// static Delegate<> ScriptsLoaded; /// /// Action fired on scripting engine unloading start (always main thread). /// static Delegate<> ScriptsUnload; /// /// Action fired on scripting engine reload start (always main thread). /// static Delegate<> ScriptsReloading; /// /// Action fired on scripting engine reload start (always main thread). /// static Delegate<> ScriptsReloaded; public: /// /// Gets the root domain. /// static MDomain* GetRootDomain(); /// /// Gets the scripts domain (it can be the root domain if not using separate domain for scripting). /// static MDomain* GetScriptsDomain(); public: /// /// Load/Reload scripts now /// /// True if failed or cannot be done, otherwise false static bool Load(); /// /// Release scripting layer (will destroy internal scripts data) /// static void Release(); #if USE_EDITOR /// /// Reloads scripts. /// /// True if allow to scene scripts reload callback, otherwise it won't be possible. static void Reload(bool canTriggerSceneReload = true); #endif public: /// /// Finds the class with given fully qualified name within whole assembly. /// /// The full name of the type eg: System.Int64. /// The MClass object or null if missing. static MClass* FindClass(const StringAnsiView& fullname); #if USE_MONO /// /// Finds the class from the given Mono class object within whole assembly. /// /// The Mono class. /// The MClass object or null if missing. static MClass* FindClass(MonoClass* monoClass); /// /// Finds the native class with given fully qualified name within whole assembly. /// /// The full name of the type eg: System.Int64. /// The MClass object or null if missing. static MonoClass* FindClassNative(const StringAnsiView& fullname); #endif /// /// Finds the scripting type of the given fullname by searching loaded scripting assemblies. /// /// The full name of the type eg: System.Int64. /// The scripting type or invalid type if missing. static ScriptingTypeHandle FindScriptingType(const StringAnsiView& fullname); /// /// Creates a new instance of the given class object (native construction). /// /// The Managed type class. /// The created object or null if failed. static ScriptingObject* NewObject(const MClass* type); public: typedef Dictionary IdsMappingTable; /// /// The objects lookup identifier mapping used to override the object ids on FindObject call (used by the object references deserialization). /// static ThreadLocal ObjectsLookupIdMapping; /// /// Finds the object by the given identifier. Searches registered scene objects and optionally assets. Logs warning if fails. /// /// The object unique identifier. /// The found object or null if missing. template FORCE_INLINE static T* FindObject(const Guid& id) { return (T*)FindObject(id, T::GetStaticClass()); } /// /// Finds the object by the given identifier. Searches registered scene objects and optionally assets. Logs warning if fails. /// /// The object unique identifier. /// The type of the object to find (optional). /// The found object or null if missing. static ScriptingObject* FindObject(Guid id, MClass* type = nullptr); /// /// Tries to find the object by the given class. /// /// The found object or null if missing. static ScriptingObject* TryFindObject(MClass* type); /// /// Tries to find the object by the given identifier. /// /// The object unique identifier. /// The found object or null if missing. template FORCE_INLINE static T* TryFindObject(const Guid& id) { return (T*)TryFindObject(id, T::GetStaticClass()); } /// /// Tries to find the object by the given identifier. /// /// The object unique identifier. /// The type of the object to find (optional). /// The found object or null if missing. static ScriptingObject* TryFindObject(Guid id, MClass* type = nullptr); /// /// Finds the object by the given managed instance handle. Searches only registered scene objects. /// /// The managed instance pointer. /// The found object or null if missing. static ScriptingObject* FindObject(const MObject* managedInstance); /// /// Event called by the internal call on a finalizer thread when the managed objects gets deleted by the GC. /// /// The unmanaged object pointer that was related to the managed object. static void OnManagedInstanceDeleted(ScriptingObject* obj); public: /// /// Returns true if game modules are loaded. /// static bool HasGameModulesLoaded(); /// /// Returns true if every assembly is loaded. /// static bool IsEveryAssemblyLoaded(); /// /// Returns true if given type is from one of the game scripts assemblies. /// static bool IsTypeFromGameScripts(MClass* type); static void ProcessBuildInfoPath(String& path, const String& projectFolderPath); private: static bool LoadBinaryModules(const String& path, const String& projectFolderPath); // Scripting Object API static void RegisterObject(ScriptingObject* obj); static void UnregisterObject(ScriptingObject* obj); static void OnObjectIdChanged(ScriptingObject* obj, const Guid& oldId); };