298 lines
14 KiB
C++
298 lines
14 KiB
C++
/************************************************************************************//*!
|
|
\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"
|
|
#include "Serialization/SHSerialization.h"
|
|
|
|
namespace SHADE
|
|
{
|
|
/// <summary>
|
|
/// Responsible for managing all scripts attached to Entities as well as executing
|
|
/// all lifecycle functions of scripts.
|
|
/// </summary>
|
|
public ref class ScriptStore abstract sealed
|
|
{
|
|
public:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Scripts Manipulation Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Adds a Script to a specified Entity.
|
|
/// </summary>
|
|
/// <typeparam name="T">
|
|
/// Type of script to add.
|
|
/// This needs to be a default constructable PlushieScript.
|
|
/// </typeparam>
|
|
/// <param name="entity">The entity to add a script to.</param>
|
|
/// <returns>Reference to the script added.</returns>
|
|
/// <exception cref="ArgumentException">
|
|
/// If the specified Entity is invalid.
|
|
/// </exception>
|
|
generic<typename T> where T : ref class, Script
|
|
static T AddScript(Entity entity);
|
|
/// <summary>
|
|
/// Adds a Script to a specified Entity.
|
|
/// <br/>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to add a script to.</param>
|
|
/// <param name="scriptName">The entity to add a script to.</param>
|
|
/// <returns>
|
|
/// True if successfully added. False otherwise with the error logged to the
|
|
/// console.
|
|
/// </returns>
|
|
static bool AddScriptViaName(Entity entity, System::String^ scriptName);
|
|
/// <summary>
|
|
/// Adds a Script to a specified Entity.
|
|
/// <br/>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to add a script to.</param>
|
|
/// <param name="scriptName">The entity to add a script to.</param>
|
|
/// <param name="createdScript">
|
|
/// Out parameter handle to the Script that was created.
|
|
/// </param>
|
|
/// <returns>
|
|
/// True if successfully added. False otherwise with the error logged to the
|
|
/// console.
|
|
/// </returns>
|
|
static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript);
|
|
/// <summary>
|
|
/// Retrieves the first Script from the specified Entity that matches the
|
|
/// specified type.
|
|
/// </summary>
|
|
/// <typeparam name="T">
|
|
/// Type of script to get.
|
|
/// This needs to be a default constructable Script.
|
|
/// </typeparam>
|
|
/// <param name="entity">
|
|
/// The entity which the script to retrieve is attached.
|
|
/// </param>
|
|
/// <returns>
|
|
/// Reference to the script. This can be null if no script of the specified
|
|
/// type is attached.
|
|
/// </returns>
|
|
/// <exception cref="ArgumentException">
|
|
/// If the specified Entity is invalid.
|
|
/// </exception>
|
|
generic<typename T> where T : ref class, Script
|
|
static T GetScript(Entity entity);
|
|
/// <summary>
|
|
/// Retrieves the first Script from the specified Entity's children that matches
|
|
/// the specified type.
|
|
/// </summary>
|
|
/// <typeparam name="T">
|
|
/// Type of script to get.
|
|
/// This needs to be a default constructable Script.
|
|
/// </typeparam>
|
|
/// <param name="entity">
|
|
/// The entity which the script to retrieve is attached.
|
|
/// </param>
|
|
/// <returns>
|
|
/// Reference to the script. This can be null if no script of the specified
|
|
/// type is attached.
|
|
/// </returns>
|
|
/// <exception cref="ArgumentException">
|
|
/// If the specified Entity is invalid.
|
|
/// </exception>
|
|
generic<typename T> where T : ref class, Script
|
|
static T GetScriptInChildren(Entity entity);
|
|
/// <summary>
|
|
/// Retrieves a immutable list of scripts from the specified Entity that
|
|
/// matches the specified type.
|
|
/// <br/>
|
|
/// Note that this function allocates. It should be used sparingly.
|
|
/// </summary>
|
|
/// <typeparam name="T">
|
|
/// Type of scripts to get.
|
|
/// This needs to be a default constructable Script.
|
|
/// </typeparam>
|
|
/// <param name="entity">
|
|
/// The entity which the scripts to retrieve are attached.
|
|
/// </param>
|
|
/// <returns>
|
|
/// Immutable list of references to scripts of the specified type.
|
|
/// </returns>
|
|
generic<typename T> where T : ref class, Script
|
|
static System::Collections::Generic::IEnumerable<T> ^ GetScripts(Entity entity);
|
|
/// <summary>
|
|
/// Retrieves an immutable list of all scripts attached to a specified Entity.
|
|
/// </summary>
|
|
/// <param name="entity">
|
|
/// The entity which the scripts to retrieve are attached.
|
|
/// </param>
|
|
/// <returns>
|
|
/// 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.
|
|
/// </returns>
|
|
static System::Collections::Generic::IEnumerable<Script^>^ GetAllScripts(Entity entity);
|
|
/// <summary>
|
|
/// Removes all Scripts of the specified type from the specified Entity.
|
|
/// </summary>
|
|
/// <typeparam name="T">
|
|
/// Type of script to remove.
|
|
/// This needs to be a default constructable Script.
|
|
/// </typeparam>
|
|
/// <param name="entity">The entity to remove the script from.</param>
|
|
/// <exception cref="ArgumentException">
|
|
/// If the specified Entity is invalid.
|
|
/// </exception>
|
|
generic<typename T> where T : ref class, Script
|
|
static void RemoveScript(Entity entity);
|
|
/// <summary>
|
|
/// Removes a specific script from the
|
|
/// </summary>
|
|
/// <param name="entity">The entity to remove the script from.</param>
|
|
/// <param name="script">The script to remove.</param>
|
|
/// <returns>True if successfully removed. False otherwise.</returns>
|
|
static bool RemoveScript(Entity entity, Script^ script);
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to remove the scripts from.</param>
|
|
static void RemoveAllScripts(Entity entity);
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to remove the scripts from.</param>
|
|
/// <param name="callOnDestroy">
|
|
/// Whether or not to call OnDestroy on the scripts.This is ignored if not in
|
|
/// play mode.
|
|
/// </param>
|
|
static void RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy);
|
|
|
|
internal:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Lifecycle Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Initializes the ScriptStore to allocate and pre-populate reflection data.
|
|
/// </summary>
|
|
static void Init();
|
|
/// <summary>
|
|
/// Sets up scripts that were marked for initialization. This calls the Awake()
|
|
/// and Start() for Scripts that have yet to have done so.
|
|
/// </summary>
|
|
static void FrameSetUp();
|
|
/// <summary>
|
|
/// Cleans up scripts that were marked for deletion. This calls the OnDestroy()
|
|
/// for these Scripts.
|
|
/// </summary>
|
|
static void FrameCleanUp();
|
|
/// <summary>
|
|
/// Cleans up data stored in the ScriptStore to free up memory for garbage
|
|
/// collection.
|
|
/// </summary>
|
|
static void Exit();
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Script Information Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Retrieves a immutable list of available scripts that can be added.
|
|
/// </summary>
|
|
/// <returns>Immutable list of available scripts that can be added.</returns>
|
|
static System::Collections::Generic::IEnumerable<System::Type^>^ GetAvailableScriptList();
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Script Execution Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Executes FixedUpdate() for all scripts.
|
|
/// </summary>
|
|
static void ExecuteFixedUpdate();
|
|
/// <summary>
|
|
/// Executes Update() for all scripts.
|
|
/// </summary>
|
|
static void ExecuteUpdate();
|
|
/// <summary>
|
|
/// Executes LateUpdate() for all scripts.
|
|
/// </summary>
|
|
static void ExecuteLateUpdate();
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Serialisation Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Populates a YAML node with the scripts for a specified Entity.
|
|
/// <br/> <br/>
|
|
/// This function should only be called from native unmanaged code.
|
|
/// </summary>
|
|
/// <param name="entity">The Entity to Serialise.</param>
|
|
/// <param name="yamlNode">
|
|
/// Pointer to a YAML::Node that will be populated with all of the serialised
|
|
/// scripts and their associated fields.
|
|
/// </param>
|
|
/// <returns>
|
|
/// True if serialisation is successful. False if the buffer is too small for
|
|
/// the serialised output.
|
|
/// </returns>
|
|
static bool SerialiseScripts(Entity entity, System::IntPtr yamlNode);
|
|
/// <summary>
|
|
/// Processes a YAML node that contains a list of multiple scripts to be loaded
|
|
/// into the specified Entity.
|
|
/// <br/> <br/>
|
|
/// This function should only be called from native unmanaged code.
|
|
/// </summary>
|
|
/// <param name="entity">
|
|
/// The Entity to attach the deserialised Scripts to.
|
|
/// </param>
|
|
/// <param name="yaml">
|
|
/// Pointer to the YAML::Node that contains serialized script data.
|
|
/// </param>
|
|
/// <returns></returns>
|
|
static bool DeserialiseScripts(Entity entity, System::IntPtr yamlNode);
|
|
|
|
private:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Type Definition */
|
|
/*-----------------------------------------------------------------------------*/
|
|
using ScriptList = System::Collections::Generic::List<Script^>;
|
|
using ScriptDictionary = System::Collections::Generic::Dictionary<Entity, ScriptList^>;
|
|
using ScriptQueue = System::Collections::Generic::Queue<Script^>;
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Static Data Members */
|
|
/*-----------------------------------------------------------------------------*/
|
|
static ScriptDictionary scripts;
|
|
static ScriptList awakeList;
|
|
static ScriptList startList;
|
|
static ScriptList inactiveStartList;
|
|
static ScriptQueue disposalQueue;
|
|
static System::Collections::Generic::IEnumerable<System::Type^>^ 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
|