/************************************************************************************//*! \file ScriptStore.hxx \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Oct 28, 2021 \brief Contains the definitions of the GameObject managed class which define an abstraction for working with Entities in managed code. Note: This file is written in C++17/CLI. Copyright (C) 2021 DigiPen Institute of Technology. Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once // Project Includes #include "Engine/Entity.hxx" #include "Script.hxx" namespace SHADE { /// /// Responsible for managing all scripts attached to Entities as well as executing /// all lifecycle functions of scripts. /// public ref class ScriptStore abstract sealed { public: /*-----------------------------------------------------------------------------*/ /* Scripts Manipulation Functions */ /*-----------------------------------------------------------------------------*/ /// /// Adds a Script to a specified Entity. /// /// /// Type of script to add. /// This needs to be a default constructable PlushieScript. /// /// The entity to add a script to. /// Reference to the script added. /// /// If the specified Entity is invalid. /// generic where T : ref class, Script static T AddScript(Entity entity); /// /// Adds a Script to a specified Entity. ///
/// This function is meant for consumption from native code. If you are writing /// in C# or C++/CLI, use AddScript<T>() instead as it is faster. ///
/// The entity to add a script to. /// The entity to add a script to. /// /// True if successfully added. False otherwise with the error logged to the /// console. /// static bool AddScriptViaName(Entity entity, System::String^ scriptName); /// /// Adds a Script to a specified Entity. ///
/// This function is meant for consumption from native code or for serialisation /// purposes. If you are writing in C# or C++/CLI and not doing serialisation, /// use AddScript<T>() instead as it is faster. ///
/// The entity to add a script to. /// The entity to add a script to. /// /// Out parameter handle to the Script that was created. /// /// /// True if successfully added. False otherwise with the error logged to the /// console. /// static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript); /// /// Retrieves the first Script from the specified Entity that matches the /// specified type. /// /// /// Type of script to get. /// This needs to be a default constructable Script. /// /// /// The entity which the script to retrieve is attached. /// /// /// Reference to the script. This can be null if no script of the specified /// type is attached. /// /// /// If the specified Entity is invalid. /// generic where T : ref class, Script static T GetScript(Entity entity); /// /// Retrieves the first Script from the specified Entity's children that matches /// the specified type. /// /// /// Type of script to get. /// This needs to be a default constructable Script. /// /// /// The entity which the script to retrieve is attached. /// /// /// Reference to the script. This can be null if no script of the specified /// type is attached. /// /// /// If the specified Entity is invalid. /// generic where T : ref class, Script static T GetScriptInChildren(Entity entity); /// /// Retrieves a immutable list of scripts from the specified Entity that /// matches the specified type. ///
/// Note that this function allocates. It should be used sparingly. ///
/// /// Type of scripts to get. /// This needs to be a default constructable Script. /// /// /// The entity which the scripts to retrieve are attached. /// /// /// Immutable list of references to scripts of the specified type. /// generic where T : ref class, Script static System::Collections::Generic::IEnumerable ^ GetScripts(Entity entity); /// /// Retrieves an immutable list of all scripts attached to a specified Entity. /// /// /// The entity which the scripts to retrieve are attached. /// /// /// Immutable list of references to scripts attached to the specified Entity. /// This can also be null if there are no scripts at all or an invalid Entity /// was specified. /// static System::Collections::Generic::IEnumerable^ GetAllScripts(Entity entity); /// /// Removes all Scripts of the specified type from the specified Entity. /// /// /// Type of script to remove. /// This needs to be a default constructable Script. /// /// The entity to remove the script from. /// /// If the specified Entity is invalid. /// generic where T : ref class, Script static void RemoveScript(Entity entity); /// /// Removes a specific script from the /// /// The entity to remove the script from. /// The script to remove. /// True if successfully removed. False otherwise. static bool RemoveScript(Entity entity, Script^ script); /// /// Removes all Scripts attached to the specified Entity. Does not do anything /// if the specified Entity is invalid or does not have any Scripts /// attached. /// /// The entity to remove the scripts from. static void RemoveAllScripts(Entity entity); /// /// Removes all Scripts attached to the specified Entity. Unlike /// RemoveAllScripts(), this removes all the scripts immediately. /// Does not do anything if the specified Entity is invalid or does not have any /// Scripts attached. /// /// The entity to remove the scripts from. /// /// Whether or not to call OnDestroy on the scripts.This is ignored if not in /// play mode. /// static void RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy); internal: /*-----------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*-----------------------------------------------------------------------------*/ /// /// Initializes the ScriptStore to allocate and pre-populate reflection data. /// static void Init(); /// /// Sets up scripts that were marked for initialization. This calls the Awake() /// and Start() for Scripts that have yet to have done so. /// static void FrameSetUp(); /// /// Cleans up scripts that were marked for deletion. This calls the OnDestroy() /// for these Scripts. /// static void FrameCleanUp(); /// /// Cleans up data stored in the ScriptStore to free up memory for garbage /// collection. /// static void Exit(); /*-----------------------------------------------------------------------------*/ /* Script Information Functions */ /*-----------------------------------------------------------------------------*/ /// /// Retrieves a immutable list of available scripts that can be added. /// /// Immutable list of available scripts that can be added. static System::Collections::Generic::IEnumerable^ GetAvailableScriptList(); /*-----------------------------------------------------------------------------*/ /* Script Execution Functions */ /*-----------------------------------------------------------------------------*/ /// /// Executes FixedUpdate() for all scripts. /// static void ExecuteFixedUpdate(); /// /// Executes Update() for all scripts. /// static void ExecuteUpdate(); /// /// Executes LateUpdate() for all scripts. /// static void ExecuteLateUpdate(); /*-----------------------------------------------------------------------------*/ /* Serialisation Functions */ /*-----------------------------------------------------------------------------*/ /// /// Generates a JSON string that represents the set of Scripts attached /// to the specified Entity. ///

/// This function should only be called from native unmanaged code. ///
/// The Entity to Serialise. /// /// StringBuilder handle that maps to a native char array that will contain the /// serialised string. /// /// /// The size of the char array. /// /// /// True if serialisation is successful. False if the buffer is too small for /// the serialised output. /// static bool SerialiseScripts(Entity entity, System::Text::StringBuilder^ buffer, int bufferSize); /// /// Processes a JSON string that represents a single Script and attaches /// it onto the specified Entity. ///

/// This function should only be called from native unmanaged code. ///
/// /// The Entity to attach the deserialised Scripts to. /// /// /// JSON string that describes the Script to serialise. /// /// static bool DeserialiseScript(Entity entity, System::String^ yaml); private: /*-----------------------------------------------------------------------------*/ /* Type Definition */ /*-----------------------------------------------------------------------------*/ using ScriptList = System::Collections::Generic::List; using ScriptDictionary = System::Collections::Generic::Dictionary; using ScriptQueue = System::Collections::Generic::Queue; /*-----------------------------------------------------------------------------*/ /* Static Data Members */ /*-----------------------------------------------------------------------------*/ static ScriptDictionary scripts; static ScriptList awakeList; static ScriptList startList; static ScriptList inactiveStartList; static ScriptQueue disposalQueue; static System::Collections::Generic::IEnumerable^ scriptTypeList; static System::Reflection::MethodInfo^ addScriptMethod; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ static void removeScript(Script^ script); static void refreshScriptTypeList(); static void getGenericMethods(); static System::Type^ getScriptType(System::String^ scriptName); static bool isEntityActive(Entity entity); }; } // namespace PlushieAPI