Static variables in scripts are now reset when leaving play mode #351
|
@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Utility/Debug.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Scripts/ScriptStore.hxx"
|
||||
#include "Serialisation/SerialisationUtilities.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -267,7 +268,9 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
ScriptAddCommand::ScriptAddCommand(EntityID id, Script^ script)
|
||||
: entity { id }
|
||||
, addedScript { script }
|
||||
, typeName { script->GetType()->FullName }
|
||||
, serialisedScript { SerialisationUtilities::Serialise(script) }
|
||||
, insertedIndex { ScriptStore::GetScriptIndex(script) }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -275,12 +278,20 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
bool ScriptAddCommand::Execute()
|
||||
{
|
||||
return ScriptStore::AddScript(entity, addedScript) != nullptr;
|
||||
Script^ script = nullptr;
|
||||
if (ScriptStore::AddScriptViaNameWithRef(entity, typeName, script))
|
||||
{
|
||||
SerialisationUtilities::Deserialise(script, serialisedScript);
|
||||
insertedIndex = ScriptStore::GetScriptIndex(script);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScriptAddCommand::Unexceute()
|
||||
{
|
||||
return ScriptStore::RemoveScript(entity, addedScript);
|
||||
return ScriptStore::RemoveScript(entity, insertedIndex);
|
||||
}
|
||||
|
||||
bool ScriptAddCommand::Merge(ICommand^)
|
||||
|
@ -294,7 +305,8 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
ScriptRemoveCommand::ScriptRemoveCommand(EntityID id, Script^ script, int index)
|
||||
: entity{ id }
|
||||
, removedScript { script }
|
||||
, typeName{ script->GetType()->FullName }
|
||||
, serialisedScript{ SerialisationUtilities::Serialise(script) }
|
||||
, originalIndex { index }
|
||||
{}
|
||||
|
||||
|
@ -303,12 +315,19 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
bool ScriptRemoveCommand::Execute()
|
||||
{
|
||||
return ScriptStore::RemoveScript(entity, removedScript);
|
||||
return ScriptStore::RemoveScript(entity, originalIndex);
|
||||
}
|
||||
|
||||
bool ScriptRemoveCommand::Unexceute()
|
||||
{
|
||||
return ScriptStore::AddScript(entity, removedScript, originalIndex) != nullptr;
|
||||
Script^ script = nullptr;
|
||||
if (ScriptStore::AddScriptViaNameWithRef(entity, typeName, script, originalIndex))
|
||||
{
|
||||
SerialisationUtilities::Deserialise(script, serialisedScript);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScriptRemoveCommand::Merge(ICommand^)
|
||||
|
|
|
@ -114,7 +114,9 @@ namespace SHADE
|
|||
|
||||
private:
|
||||
EntityID entity;
|
||||
Script^ addedScript;
|
||||
System::String^ typeName;
|
||||
System::String^ serialisedScript;
|
||||
int insertedIndex;
|
||||
};
|
||||
|
||||
private ref class ScriptRemoveCommand sealed : public ICommand
|
||||
|
@ -128,7 +130,8 @@ namespace SHADE
|
|||
|
||||
private:
|
||||
EntityID entity;
|
||||
Script^ removedScript;
|
||||
System::String^ typeName;
|
||||
System::String^ serialisedScript;
|
||||
int originalIndex;
|
||||
};
|
||||
|
||||
|
|
|
@ -100,6 +100,11 @@ namespace SHADE
|
|||
}
|
||||
|
||||
bool ScriptStore::AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, Script^% createdScript)
|
||||
{
|
||||
return AddScriptViaNameWithRef(entity, scriptName, createdScript, System::Int32::MaxValue);
|
||||
}
|
||||
|
||||
bool ScriptStore::AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript, int index)
|
||||
{
|
||||
// Check if we are set up to get scripts
|
||||
if (addScriptMethod == nullptr)
|
||||
|
@ -120,17 +125,18 @@ namespace SHADE
|
|||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, add the script
|
||||
// Add the script
|
||||
System::Reflection::MethodInfo^ method = addScriptMethod->MakeGenericMethod(scriptType);
|
||||
try
|
||||
{
|
||||
array<Object^>^ params = gcnew array<Object^>{entity};
|
||||
createdScript = safe_cast<Script^>(method->Invoke(nullptr, params));
|
||||
// Create the script and add it in
|
||||
createdScript = safe_cast<Script^>(System::Activator::CreateInstance(scriptType));
|
||||
AddScript(entity, createdScript, index);
|
||||
}
|
||||
catch (System::Exception^ e)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "[ScriptStore] Failed to add Script named \"" << Convert::ToNative(scriptName)
|
||||
oss << "[ScriptStore] Failed to add Script named \"" << Convert::ToNative(scriptType->Name)
|
||||
<< "\" to Entity #" << entity << "! (" << Convert::ToNative(e->GetType()->Name) << ")";
|
||||
oss << Convert::ToNative(e->ToString());
|
||||
Debug::LogError(oss.str());
|
||||
|
@ -321,6 +327,19 @@ namespace SHADE
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ScriptStore::GetScriptIndex(Script^ script)
|
||||
{
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(script->Owner.EntityId))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to query a Script that does not belong to the ScriptStore.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return scripts[script->Owner.EntityId]->IndexOf(script);
|
||||
}
|
||||
|
||||
generic<typename T>
|
||||
void ScriptStore::RemoveScript(Entity entity)
|
||||
{
|
||||
|
@ -376,6 +395,35 @@ namespace SHADE
|
|||
removeScript(script);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScriptStore::RemoveScript(Entity entity, int index)
|
||||
{
|
||||
// Check if entity exists
|
||||
if (!EntityUtils::IsValid(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove a Script from an invalid Entity!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if entity exists in the script storage
|
||||
if (!scripts.ContainsKey(entity))
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove a Script that does not belong to the specified Entity!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the script index is out of bounds
|
||||
if (index < 0 || index >= scripts[entity]->Count)
|
||||
{
|
||||
Debug::LogError("[ScriptStore] Attempted to remove a Script from an out of range index!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Script found, queue it for deletion
|
||||
removeScript((*scripts[entity])[index]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptStore::RemoveAllScripts(Entity entity)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
|
|
|
@ -82,9 +82,9 @@ namespace SHADE
|
|||
/// <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.
|
||||
/// This function is meant for deserialisation 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>
|
||||
|
@ -96,6 +96,7 @@ namespace SHADE
|
|||
/// console.
|
||||
/// </returns>
|
||||
static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript);
|
||||
static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript, int index);
|
||||
/// <summary>
|
||||
/// Retrieves the first Script from the specified Entity that matches the
|
||||
/// specified type.
|
||||
|
@ -190,6 +191,12 @@ namespace SHADE
|
|||
/// </returns>
|
||||
static System::Collections::Generic::IEnumerable<Script^>^ GetAllScripts(Entity entity);
|
||||
/// <summary>
|
||||
/// Retrieves the index of a Script within the list of it's Entity's script list.
|
||||
/// </summary>
|
||||
/// <param name="script">Script to get the index of.</param>
|
||||
/// <returns>Script index if valid. Otherwise -1.</returns>
|
||||
static int GetScriptIndex(Script^ script);
|
||||
/// <summary>
|
||||
/// Removes all Scripts of the specified type from the specified Entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
|
@ -210,6 +217,13 @@ namespace SHADE
|
|||
/// <returns>True if successfully removed. False otherwise.</returns>
|
||||
static bool RemoveScript(Entity entity, Script^ script);
|
||||
/// <summary>
|
||||
/// Removes a script at a specified index from the specified entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to remove the script from.</param>
|
||||
/// <param name="index">Index of the script to remove.</param>
|
||||
/// <returns>True if successfully removed. False otherwise.</returns>
|
||||
static bool RemoveScript(Entity entity, int index);
|
||||
/// <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.
|
||||
|
|
|
@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Assets/MaterialAsset.hxx"
|
||||
#include "Assets/MeshAsset.hxx"
|
||||
#include "Scripts/Script.hxx"
|
||||
#include "Scripts/ScriptStore.hxx"
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* File-Level Constants */
|
||||
|
@ -79,6 +80,21 @@ namespace SHADE
|
|||
|
||||
scriptListNode.push_back(scriptNode);
|
||||
}
|
||||
|
||||
System::String^ SerialisationUtilities::Serialise(Script^ script)
|
||||
{
|
||||
YAML::Node node;
|
||||
node.SetStyle(YAML::EmitterStyle::Block);
|
||||
Serialise(script, node);
|
||||
YAML::Emitter emitter;
|
||||
emitter << YAML::BeginMap;
|
||||
emitter << node;
|
||||
emitter << YAML::EndMap;
|
||||
return Convert::ToCLI(emitter.c_str());
|
||||
/*std::string str = emitter.c_str();
|
||||
return Convert::ToCLI(str.substr(2));*/
|
||||
}
|
||||
|
||||
void SerialisationUtilities::Deserialise(Object^ object, YAML::Node& yamlNode)
|
||||
{
|
||||
using namespace System::Reflection;
|
||||
|
@ -135,6 +151,12 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialisationUtilities::Deserialise(Script^ script, System::String^ yamlString)
|
||||
{
|
||||
Deserialise(script, YAML::Load(Convert::ToNative(yamlString)));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Serialization Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="object">The object to serialise.</param>
|
||||
static void Serialise(System::Object^ object, YAML::Node& yamlNode);
|
||||
static System::String^ Serialise(Script^ script);
|
||||
/// <summary>
|
||||
/// Deserialises a YAML node that contains a map of Scripts and copies the
|
||||
/// deserialised data into the specified object if there are matching fields.
|
||||
|
@ -48,6 +49,7 @@ namespace SHADE
|
|||
/// </param>
|
||||
/// <param name="object">The object to copy deserialised data into.</param>
|
||||
static void Deserialise(System::Object^ object, YAML::Node& yamlNode);
|
||||
static void Deserialise(Script^ script, System::String^ yamlString);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in New Issue