Files
FlaxEngine/Source/Engine/Scripting/Scripting.h

212 lines
7.4 KiB
C++

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