// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Threading/ThreadLocal.h"
#include "ScriptingObject.h"
class BinaryModule;
///
/// 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 Action ScriptsLoaded;
///
/// Action fired on scripting engine unloading start (always main thread).
///
static Action ScriptsUnload;
///
/// Action fired on scripting engine reload start (always main thread).
///
static Action ScriptsReloading;
///
/// Action fired on scripting engine reload start (always main thread).
///
static Action ScriptsReloaded;
public:
///
/// Gets mono root domain
///
/// The Mono root domain.
static MDomain* GetRootDomain();
///
/// Gets mono scripts domain
///
/// The Mono domain.
static MonoDomain* GetMonoScriptsDomain();
///
/// Gets scripts domain
///
/// The domain.
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 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 class with given fully qualified name within whole assembly.
///
/// The full name of the type eg: System.Int64.MaxInt.
/// The MClass object or null if missing.
static MClass* FindClass(const StringAnsiView& fullname);
///
/// Finds the native class with given fully qualified name within whole assembly.
///
/// The full name of the type eg: System.Int64.MaxInt.
/// The MClass object or null if missing.
static MonoClass* FindClassNative(const StringAnsiView& fullname);
///
/// Finds the scripting type of the given fullname by searching loaded scripting assemblies.
///
/// The full name of the type eg: System.Int64.MaxInt.
/// The scripting type or invalid type if missing.
static ScriptingTypeHandle FindScriptingType(const StringAnsiView& fullname);
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.
/// The found object or null if missing.
static ScriptingObject* FindObject(Guid id, 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.
/// The found object or null if missing.
static ScriptingObject* TryFindObject(Guid id, MClass* type);
///
/// 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 MonoObject* 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);
};