Added UI Element and other QoL fixes for scripting #329

Merged
Pycorax merged 7 commits from SP3-6-c-scripting into main 2023-02-02 10:57:20 +08:00
19 changed files with 334 additions and 41 deletions

View File

@ -4,6 +4,7 @@
//|| SHADE Includes || //|| SHADE Includes ||
//#==============================================================# //#==============================================================#
#include "Editor/EditorWindow/SHEditorWindow.h" #include "Editor/EditorWindow/SHEditorWindow.h"
#include "Editor/SHEditor.h"
namespace SHADE namespace SHADE
{ {

View File

@ -31,6 +31,9 @@ of DigiPen Institute of Technology is prohibited.
#include "Assets/SHAssetMacros.h" #include "Assets/SHAssetMacros.h"
#include "Tools/Utilities/SHExecUtilities.h" #include "Tools/Utilities/SHExecUtilities.h"
#include "SHVSUtilities.h" #include "SHVSUtilities.h"
#include "UI/Events/SHButtonClickEvent.h"
#include "UI/SHUIComponent.h"
#include "Editor/EditorWindow/MenuBar/SHEditorMenuBar.h"
namespace SHADE namespace SHADE
{ {
@ -121,6 +124,11 @@ namespace SHADE
csScriptsRemoveAllImmediately(entity, callOnDestroy); csScriptsRemoveAllImmediately(entity, callOnDestroy);
} }
void SHScriptEngine::RemoveAllScriptsFromAllImmediately(bool callOnDestroy)
{
csScriptRemoveAllForAllNow(callOnDestroy);
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -346,6 +354,21 @@ namespace SHADE
return eventData->handle; return eventData->handle;
} }
SHEventHandle SHScriptEngine::onUIElementRemoved(SHEventPtr eventPtr)
{
auto eventData = reinterpret_cast<const SHEventSpec<SHComponentRemovedEvent>*>(eventPtr.get());
if (eventData->data->removedComponentType == ComponentFamily::GetID<SHUIComponent>())
csUIElementOnRemoved(eventData->data->eid);
return eventData->handle;
}
SHEventHandle SHScriptEngine::onUIElementClicked(SHEventPtr eventPtr)
{
auto eventData = reinterpret_cast<const SHEventSpec<SHButtonClickEvent>*>(eventPtr.get());
csUIElementOnClicked(eventData->data->EID);
return eventData->handle;
}
SHEventHandle SHScriptEngine::onSceneNodeChildrenAdded(SHEventPtr eventPtr) SHEventHandle SHScriptEngine::onSceneNodeChildrenAdded(SHEventPtr eventPtr)
{ {
auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphAddChildEvent>*>(eventPtr.get()); auto eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphAddChildEvent>*>(eventPtr.get());
@ -360,6 +383,13 @@ namespace SHADE
return eventData->handle; return eventData->handle;
} }
SHEventHandle SHScriptEngine::onSceneDestroyed(SHEventPtr eventPtr)
{
auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get());
csScriptRemoveAllForAllNow(true);
return eventData->handle;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -460,6 +490,12 @@ namespace SHADE
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"RemoveAllScriptsImmediately" "RemoveAllScriptsImmediately"
); );
csScriptRemoveAllForAllNow = dotNet.GetFunctionPtr<CsScriptBoolFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"RemoveAllScriptsFromAllImmediately"
);
csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr> csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
@ -490,6 +526,18 @@ namespace SHADE
DEFAULT_CSHARP_NAMESPACE + ".ChildListCache", DEFAULT_CSHARP_NAMESPACE + ".ChildListCache",
"OnChildrenChanged" "OnChildrenChanged"
); );
csUIElementOnRemoved = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".UIElement",
"OnComponentRemoved"
);
csUIElementOnClicked = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
(
DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".UIElement",
"OnClicked"
);
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
@ -520,6 +568,14 @@ namespace SHADE
}; };
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver)); SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
/* Editor */
// Register for editor state change event
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedSceneEventReceiver
{
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneDestroyed)
};
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedSceneEventReceiver));
/* Colliders */ /* Colliders */
// Register for collider added event // Register for collider added event
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addedColliderEventReceiver
@ -540,6 +596,18 @@ namespace SHADE
}; };
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver)); SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedColliderComponentEventReceiver));
/* UI Element */
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> removedUIElementEventReceiver
{
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onUIElementRemoved)
};
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(removedUIElementEventReceiver));
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> clickedUIElementEventReceiver
{
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onUIElementClicked)
};
SHEventManager::SubscribeTo(SH_BUTTON_CLICK_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(clickedUIElementEventReceiver));
/* SceneGraph */ /* SceneGraph */
// Register for SceneNode child added event // Register for SceneNode child added event
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addChildEventReceiver std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> addChildEventReceiver

View File

@ -148,6 +148,13 @@ namespace SHADE
/// play mode. /// play mode.
/// </param> /// </param>
void RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy); void RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy);
/// <summary>
/// Removes all Scripts attached to all entities immediately. The
/// </summary>
/// <param name="callOnDestroy">
/// Whether or not to call OnDestroy on the scripts.
/// </param>
void RemoveAllScriptsFromAllImmediately(bool callOnDestroy);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
@ -235,6 +242,7 @@ namespace SHADE
using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); using CsScriptManipFuncPtr = bool(*)(EntityID, const char*);
using CsScriptBasicFuncPtr = void(*)(EntityID); using CsScriptBasicFuncPtr = void(*)(EntityID);
using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); using CsScriptOptionalFuncPtr = void(*)(EntityID, bool);
using CsScriptBoolFuncPtr = void(*)(bool);
using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*);
using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*);
using CsScriptEditorFuncPtr = void(*)(EntityID); using CsScriptEditorFuncPtr = void(*)(EntityID);
@ -271,12 +279,15 @@ namespace SHADE
CsScriptManipFuncPtr csScriptsAdd = nullptr; CsScriptManipFuncPtr csScriptsAdd = nullptr;
CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr;
CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr;
CsScriptBoolFuncPtr csScriptRemoveAllForAllNow = nullptr;
CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr;
CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr;
// - Events // - Events
CsEventRelayFuncPtr csColliderOnListChanged = nullptr; CsEventRelayFuncPtr csColliderOnListChanged = nullptr;
CsEventRelayFuncPtr csColliderOnRemoved = nullptr; CsEventRelayFuncPtr csColliderOnRemoved = nullptr;
CsEventRelayFuncPtr csSceneNodeChildrenChanged = nullptr; CsEventRelayFuncPtr csSceneNodeChildrenChanged = nullptr;
CsEventRelayFuncPtr csUIElementOnRemoved = nullptr;
CsEventRelayFuncPtr csUIElementOnClicked = nullptr;
// - Editor // - Editor
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
CsFuncPtr csEditorUndo = nullptr; CsFuncPtr csEditorUndo = nullptr;
@ -289,8 +300,11 @@ namespace SHADE
SHEventHandle onColliderAdded(SHEventPtr eventPtr); SHEventHandle onColliderAdded(SHEventPtr eventPtr);
SHEventHandle onColliderRemoved(SHEventPtr eventPtr); SHEventHandle onColliderRemoved(SHEventPtr eventPtr);
SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr); SHEventHandle onColliderComponentRemoved(SHEventPtr eventPtr);
SHEventHandle onUIElementRemoved(SHEventPtr eventPtr);
SHEventHandle onUIElementClicked(SHEventPtr eventPtr);
SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr); SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr);
SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr); SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr);
SHEventHandle onSceneDestroyed(SHEventPtr eventPtr);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -41,6 +41,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Asset::operator bool(Asset asset) Asset::operator bool(Asset asset)
{ {
static_assert(INVALID_ASSET_ID == 0,
"This must be 0 due to the way structs are default initialized to ensure Assets are invalid if default constructed.");
return asset.NativeAssetID != INVALID_ASSET_ID; return asset.NativeAssetID != INVALID_ASSET_ID;
} }
} }

View File

@ -22,7 +22,8 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/// <summary> /// <summary>
/// Struct that contains native asset information. /// Struct that contains native asset information. Default constructed assets have
/// an internval value of 0 which is the invalid ID.
/// </summary> /// </summary>
public value struct Asset public value struct Asset
{ {

View File

@ -30,34 +30,36 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHADE::MeshAsset^ Renderable::Mesh::get() MeshAsset Renderable::Mesh::get()
{ {
return gcnew SHADE::MeshAsset(GetNativeComponent()->GetMesh()); auto mesh = GetNativeComponent()->GetMesh();
return mesh ? MeshAsset(mesh) : MeshAsset();
} }
void Renderable::Mesh::set(SHADE::MeshAsset^ value) void Renderable::Mesh::set(MeshAsset value)
{ {
if (value == nullptr) if (value)
{ {
GetNativeComponent()->SetMesh(Handle<SHMesh>()); GetNativeComponent()->SetMesh(Handle<SHMesh>());
} }
else else
{ {
GetNativeComponent()->SetMesh(value->NativeObject); GetNativeComponent()->SetMesh(value.NativeObject);
} }
} }
SHADE::Material^ Renderable::Material::get() SHADE::Material Renderable::Material::get()
{ {
return gcnew SHADE::Material(GetNativeComponent()->GetMaterial()); auto mat = GetNativeComponent()->GetMaterial();
return mat ? SHADE::Material(mat) : SHADE::Material();
} }
void Renderable::Material::set(SHADE::Material^ value) void Renderable::Material::set(SHADE::Material value)
{ {
if (value == nullptr) if (value)
{ {
GetNativeComponent()->SetMaterial(Handle<SHMaterialInstance>()); GetNativeComponent()->SetMaterial(Handle<SHMaterialInstance>());
} }
else else
{ {
GetNativeComponent()->SetMaterial(Handle<SHMaterialInstance>(Convert::ToNative(value->NativeObjectHandle))); GetNativeComponent()->SetMaterial(Handle<SHMaterialInstance>(Convert::ToNative(value.NativeObjectHandle)));
} }
} }
System::Byte Renderable::LightLayer::get() System::Byte Renderable::LightLayer::get()

View File

@ -49,18 +49,18 @@ namespace SHADE
/// <summary> /// <summary>
/// Mesh used to render this Renderable. /// Mesh used to render this Renderable.
/// </summary> /// </summary>
property SHADE::MeshAsset^ Mesh property MeshAsset Mesh
{ {
SHADE::MeshAsset^ get(); MeshAsset get();
void set(SHADE::MeshAsset^ value); void set(MeshAsset value);
} }
/// <summary> /// <summary>
/// Material used to render this Renderable. /// Material used to render this Renderable.
/// </summary> /// </summary>
property SHADE::Material^ Material property SHADE::Material Material
{ {
SHADE::Material^ get(); SHADE::Material get();
void set(SHADE::Material^ value); void set(SHADE::Material value);
} }
/// <summary> /// <summary>
/// Material used to render this Renderable. /// Material used to render this Renderable.

View File

@ -39,19 +39,20 @@ namespace SHADE
{ {
GetNativeComponent()->SetText(Convert::ToNative(value)); GetNativeComponent()->SetText(Convert::ToNative(value));
} }
SHADE::FontAsset^ TextRenderable::Font::get() FontAsset TextRenderable::Font::get()
{ {
return gcnew SHADE::FontAsset(GetNativeComponent()->GetFont()); auto font = GetNativeComponent()->GetFont();
return font ? FontAsset(font) : FontAsset();
} }
void TextRenderable::Font::set(SHADE::FontAsset^ value) void TextRenderable::Font::set(FontAsset value)
{ {
if (value == nullptr) if (value)
{ {
GetNativeComponent()->SetFont(Handle<SHFont>()); GetNativeComponent()->SetFont(Handle<SHFont>());
} }
else else
{ {
GetNativeComponent()->SetFont(value->NativeObject); GetNativeComponent()->SetFont(value.NativeObject);
} }
} }
} }

View File

@ -55,10 +55,10 @@ namespace SHADE
/// <summary> /// <summary>
/// Font to use to render using this TextRenderable. /// Font to use to render using this TextRenderable.
/// </summary> /// </summary>
property SHADE::FontAsset^ Font property FontAsset Font
{ {
SHADE::FontAsset^ get(); FontAsset get();
void set(SHADE::FontAsset^ value); void set(FontAsset value);
} }
}; };
} }

View File

@ -0,0 +1,75 @@
/************************************************************************************//*!
\file UIElement.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Jan 30, 2023
\brief Contains the definition of the functions of the managed UIElement class.
Note: This file is written in C++17/CLI.
Copyright (C) 2023 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.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "UIElement.hxx"
#include "Assets/NativeAsset.hxx"
#include "Utility/Convert.hxx"
#include "Utility/Debug.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
UIElement::UIElement(Entity entity)
: Component(entity)
{}
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
CallbackEvent^ UIElement::OnClick::get()
{
// Create map if it wasn't before
if (onClickEventMap == nullptr)
{
onClickEventMap = gcnew System::Collections::Generic::Dictionary<Entity, CallbackEvent ^>();
}
// Create event if it wasn't before
if (!onClickEventMap->ContainsKey(owner.EntityId))
{
onClickEventMap->Add(owner.EntityId, gcnew CallbackEvent());
}
// Return the event
return onClickEventMap[owner.EntityId];
}
/*---------------------------------------------------------------------------------*/
/* Event Handling Functions */
/*-----------------------------------------------------------------------------a----*/
void UIElement::OnComponentRemoved(EntityID entity)
{
SAFE_NATIVE_CALL_BEGIN
// Remove the event if it contained an event
if (onClickEventMap != nullptr && onClickEventMap->ContainsKey(entity))
{
onClickEventMap->Remove(entity);
}
SAFE_NATIVE_CALL_END("UIElement.OnComponentRemoved")
}
void UIElement::OnClicked(EntityID entity)
{
SAFE_NATIVE_CALL_BEGIN
// Remove the event if it contained an event
if (onClickEventMap != nullptr && onClickEventMap->ContainsKey(entity))
{
onClickEventMap[entity]->Invoke();
}
SAFE_NATIVE_CALL_END("UIElement.OnClicked")
}
}

View File

@ -0,0 +1,75 @@
/************************************************************************************//*!
\file UIElement.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Jan 30, 2023
\brief Contains the definition of the managed UIElement class with the
declaration of functions for working with it.
Note: This file is written in C++17/CLI.
Copyright (C) 2023 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 "Components/Component.hxx"
#include "Math/Vector3.hxx"
#include "Math/Quaternion.hxx"
// External Dependencies
#include "UI/SHUIComponent.h"
namespace SHADE
{
/// <summary>
/// CLR version of the SHADE Engine's SHUIComponent.
/// </summary>
public ref class UIElement : public Component<SHUIComponent>
{
internal:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructs a UIElement Component that represents a native SHUIComponent
/// tied to the specified Entity.
/// </summary>
/// <param name="entity">Entity that this Component will be tied to.</param>
UIElement(Entity entity);
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Event that is raised when this UIElement is clicked.
/// </summary>
property CallbackEvent^ OnClick
{
CallbackEvent^ get();
}
private:
/*-----------------------------------------------------------------------------*/
/* Event Handling Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// To be called from native code when this component is removed.
/// </summary>
/// <param name="entity">The entity which has it's component removed.</param>
static void OnComponentRemoved(EntityID entity);
/// <summary>
/// To be called from native code when this component is clicked.
/// </summary>
/// <param name="entity">The entity which was clicked.</param>
static void OnClicked(EntityID entity);
/*-----------------------------------------------------------------------------*/
/* Static Data Members */
/*-----------------------------------------------------------------------------*/
static System::Collections::Generic::Dictionary<Entity, CallbackEvent^>^ onClickEventMap;
};
}

View File

@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Tools/Logger/SHLog.h" #include "Tools/Logger/SHLog.h"
#include "Graphics\MiddleEnd\Interface\SHRenderable.h" #include "Graphics\MiddleEnd\Interface\SHRenderable.h"
#include "Graphics\MiddleEnd\TextRendering\SHTextRenderableComponent.h" #include "Graphics\MiddleEnd\TextRendering\SHTextRenderableComponent.h"
#include "UI\SHUIComponent.h"
// Project Headers // Project Headers
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
@ -40,6 +41,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Components/Light.hxx" #include "Components/Light.hxx"
#include "Components\Renderable.hxx" #include "Components\Renderable.hxx"
#include "Components\TextRenderable.hxx" #include "Components\TextRenderable.hxx"
#include "Components\UIElement.hxx"
namespace SHADE namespace SHADE
{ {
@ -324,6 +326,7 @@ namespace SHADE
componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>()); componentMap.Add(createComponentSet<SHCameraArmComponent, CameraArm>());
componentMap.Add(createComponentSet<SHLightComponent, Light>()); componentMap.Add(createComponentSet<SHLightComponent, Light>());
componentMap.Add(createComponentSet<SHTextRenderableComponent, TextRenderable>()); componentMap.Add(createComponentSet<SHTextRenderableComponent, TextRenderable>());
componentMap.Add(createComponentSet<SHUIComponent, UIElement>());
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -259,6 +259,13 @@ namespace SHADE
ScriptStore::RemoveScript<T>(entity); ScriptStore::RemoveScript<T>(entity);
} }
void GameObject::RemoveScript(Script^ script)
{
if (!valid)
throw gcnew System::NullReferenceException();
ScriptStore::RemoveScript(entity, script);
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Scene Graph Functions */ /* Scene Graph Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -259,6 +259,12 @@ namespace SHADE
/// <typeparam name="T">Type of Scripts to remove.</typeparam> /// <typeparam name="T">Type of Scripts to remove.</typeparam>
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
void RemoveScript(); void RemoveScript();
/// <summary>
/// Removes a specific script from this script's parent.
/// </summary>
/// <param name="script">The script to remove.</param>
/// <returns>True if successfully removed. False otherwise.</returns>
void RemoveScript(Script^ script);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Scene Graph Functions */ /* Scene Graph Functions */

View File

@ -126,6 +126,11 @@ namespace SHADE
ScriptStore::RemoveScript<T>(owner.GetEntity()); ScriptStore::RemoveScript<T>(owner.GetEntity());
} }
void Script::RemoveScript(Script^ script)
{
ScriptStore::RemoveScript(owner.GetEntity(), script);
}
Script::operator bool(Script^ s) Script::operator bool(Script^ s)
{ {
return s != nullptr; return s != nullptr;

View File

@ -198,6 +198,12 @@ namespace SHADE
/// </typeparam> /// </typeparam>
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
void RemoveScript(); void RemoveScript();
/// <summary>
/// Removes a specific script from this script's parent.
/// </summary>
/// <param name="script">The script to remove.</param>
/// <returns>True if successfully removed. False otherwise.</returns>
void RemoveScript(Script^ script);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */

View File

@ -400,21 +400,21 @@ namespace SHADE
return; return;
// Clear all // Clear all
System::Collections::Generic::List<Script^>^ scriptList = scripts[entity]; removeAllScriptsImmediately(entity, callOnDestroy && Application::IsPlaying || Application::IsPaused);
for each (Script ^ script in scriptList) SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
{
// Call OnDestroy only if indicated and also if the game has run
if (callOnDestroy && Application::IsPlaying || Application::IsPaused)
{
script->OnDestroy();
} }
script->OnDetached();
// Remove scripts from awakening if they were not woken up to begin with void ScriptStore::RemoveAllScriptsFromAllImmediately(bool callOnDestroy)
awakeList.Remove(script); {
startList.Remove(script); SAFE_NATIVE_CALL_BEGIN
// Clear all
for each (System::Collections::Generic::KeyValuePair<Entity, ScriptList^>^ pair in scripts)
{
removeAllScriptsImmediately(pair->Key, callOnDestroy);
} }
scriptList->Clear(); awakeList.Clear();
startList.Clear();
disposalQueue.Clear();
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
} }
@ -798,6 +798,25 @@ namespace SHADE
script->OnDetached(); script->OnDetached();
} }
void ScriptStore::removeAllScriptsImmediately(Entity entity, bool callOnDestroy)
{
System::Collections::Generic::List<Script^>^ scriptList = scripts[entity];
for each (Script ^ script in scriptList)
{
// Call OnDestroy only if indicated and also if the game has run
if (callOnDestroy)
{
script->OnDestroy();
}
script->OnDetached();
// Remove scripts from awakening if they were not woken up to begin with
awakeList.Remove(script);
startList.Remove(script);
}
scriptList->Clear();
}
namespace namespace
{ {
/* Select Many */ /* Select Many */

View File

@ -203,7 +203,7 @@ namespace SHADE
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
static void RemoveScript(Entity entity); static void RemoveScript(Entity entity);
/// <summary> /// <summary>
/// Removes a specific script from the /// Removes a specific script from the specified entity.
/// </summary> /// </summary>
/// <param name="entity">The entity to remove the script from.</param> /// <param name="entity">The entity to remove the script from.</param>
/// <param name="script">The script to remove.</param> /// <param name="script">The script to remove.</param>
@ -228,6 +228,13 @@ namespace SHADE
/// play mode. /// play mode.
/// </param> /// </param>
static void RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy); static void RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy);
/// <summary>
/// Removes all Scripts attached to all entities immediately. The
/// </summary>
/// <param name="callOnDestroy">
/// Whether or not to call OnDestroy on the scripts.
/// </param>
static void RemoveAllScriptsFromAllImmediately(bool callOnDestroy);
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -343,6 +350,7 @@ namespace SHADE
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static void removeScript(Script^ script); static void removeScript(Script^ script);
static void removeAllScriptsImmediately(Entity script, bool callOnDestroy);
static void refreshScriptTypeList(); static void refreshScriptTypeList();
static void getGenericMethods(); static void getGenericMethods();
static System::Type^ getScriptType(System::String^ scriptName); static System::Type^ getScriptType(System::String^ scriptName);