Merge remote-tracking branch 'origin/main' into SP3-2-Physics
This commit is contained in:
commit
d897ac01e6
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Report a bug that should be fixed
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest a feature for the project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
|
@ -560,6 +560,34 @@ namespace SHADE
|
||||||
assetCollection.emplace(newAsset.id, newAsset);
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
SHAssetMetaHandler::WriteMetaData(newAsset);
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
|
||||||
|
return newAsset.id;
|
||||||
|
}
|
||||||
|
else if (ext == SCENE_EXTENSION)
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::SCENE),
|
||||||
|
AssetType::SCENE,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
|
||||||
|
return newAsset.id;
|
||||||
|
}
|
||||||
|
else if (ext == FONT_EXTENSION)
|
||||||
|
{
|
||||||
|
SHAsset newAsset{
|
||||||
|
path.stem().string(),
|
||||||
|
GenerateAssetID(AssetType::FONT),
|
||||||
|
AssetType::FONT,
|
||||||
|
path,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
assetCollection.emplace(newAsset.id, newAsset);
|
||||||
|
SHAssetMetaHandler::WriteMetaData(newAsset);
|
||||||
|
|
||||||
return newAsset.id;
|
return newAsset.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,8 +599,11 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& file : toGenNew)
|
for (auto& file : toGenNew)
|
||||||
{
|
{
|
||||||
auto newID{ GenerateNewMeta(file->path).value() };
|
auto newID{ GenerateNewMeta(file->path) };
|
||||||
file->assetMeta = &assetCollection[newID];
|
if (newID.has_value())
|
||||||
|
{
|
||||||
|
file->assetMeta = &assetCollection[newID.value()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& asset : std::ranges::views::values(assetCollection))
|
for (auto& asset : std::ranges::views::values(assetCollection))
|
||||||
|
|
|
@ -130,6 +130,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// If item is folder
|
// If item is folder
|
||||||
|
if (path.stem().string() == "bin"
|
||||||
|
|| path.stem().string() == "obj"
|
||||||
|
|| !std::filesystem::exists(path))
|
||||||
|
{
|
||||||
|
SHLOG_INFO("[FileSystem] Skipped paths in directory building: {}", path.string());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
|
||||||
folderStack.push(newFolder);
|
folderStack.push(newFolder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,11 @@ namespace SHADE
|
||||||
void SHRenderable::OnDestroy()
|
void SHRenderable::OnDestroy()
|
||||||
{
|
{
|
||||||
// Remove from SuperBatch
|
// Remove from SuperBatch
|
||||||
|
if (sharedMaterial)
|
||||||
|
{
|
||||||
Handle<SHSuperBatch> superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
Handle<SHSuperBatch> superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
|
||||||
superBatch->Remove(this);
|
superBatch->Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Free resources
|
// Free resources
|
||||||
if (material)
|
if (material)
|
||||||
|
|
|
@ -288,7 +288,15 @@ namespace YAML
|
||||||
{
|
{
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
node[MESH_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMesh>(rhs.GetMesh()).value_or(0);
|
||||||
|
auto mat = rhs.GetMaterial();
|
||||||
|
if (mat)
|
||||||
|
{
|
||||||
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
node[MAT_YAML_TAG.data()] = SHResourceManager::GetAssetID<SHMaterial>(rhs.GetMaterial()->GetBaseMaterial()).value_or(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node[MAT_YAML_TAG.data()] = 0;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
static bool decode(YAML::Node const& node, SHRenderable& rhs)
|
||||||
|
|
|
@ -27,6 +27,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Scene/SHSceneGraph.h"
|
#include "Scene/SHSceneGraph.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
|
#include "Graphics\MiddleEnd\Interface\SHRenderable.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "Utility/Convert.hxx"
|
#include "Utility/Convert.hxx"
|
||||||
#include "Utility/Debug.hxx"
|
#include "Utility/Debug.hxx"
|
||||||
|
@ -36,6 +37,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Components/Camera.hxx"
|
#include "Components/Camera.hxx"
|
||||||
#include "Components/CameraArm.hxx"
|
#include "Components/CameraArm.hxx"
|
||||||
#include "Components/Light.hxx"
|
#include "Components/Light.hxx"
|
||||||
|
#include "Components\Renderable.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -166,6 +168,70 @@ namespace SHADE
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic<typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ ECS::GetComponentsInChildren(EntityID entity)
|
||||||
|
{
|
||||||
|
System::Type^ componentType = T::typeid;
|
||||||
|
|
||||||
|
// Check if entity is correct
|
||||||
|
if (!SHEntityManager::IsValidEID(entity))
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ECS] Attempted to retrieve Component \""
|
||||||
|
<< Convert::ToNative(componentType->Name)
|
||||||
|
<< "\" from invalid Entity.";
|
||||||
|
Debug::LogError(oss.str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search all elements via a iterative breadth first search
|
||||||
|
System::Collections::Generic::List<T>^ results;
|
||||||
|
System::Collections::Generic::Queue<Entity>^ searchSpace = gcnew System::Collections::Generic::Queue<Entity>();
|
||||||
|
// Start off with direct children
|
||||||
|
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity);
|
||||||
|
if (entityNode == nullptr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptStore] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||||
|
SHLog::Warning(oss.str());
|
||||||
|
}
|
||||||
|
for (const auto& child : entityNode->GetChildren())
|
||||||
|
{
|
||||||
|
searchSpace->Enqueue(child->GetEntityID());
|
||||||
|
}
|
||||||
|
// Continue with all subsequent children
|
||||||
|
while (searchSpace->Count > 0)
|
||||||
|
{
|
||||||
|
// Check if this entity has the component we need
|
||||||
|
Entity curr = searchSpace->Dequeue();
|
||||||
|
T component = GetComponent<T>(curr);
|
||||||
|
if (component != nullptr)
|
||||||
|
{
|
||||||
|
// We only construct if we need to
|
||||||
|
if (results == nullptr)
|
||||||
|
results = gcnew System::Collections::Generic::List<T>();
|
||||||
|
results->Add(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add children to the queue
|
||||||
|
SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(curr);
|
||||||
|
if (sceneGraphNode == nullptr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ECS_CLI] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||||
|
SHLog::Warning(oss.str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const auto& child : sceneGraphNode->GetChildren())
|
||||||
|
{
|
||||||
|
searchSpace->Enqueue(child->GetEntityID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// None here
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
T ECS::EnsureComponent(EntityID entity)
|
T ECS::EnsureComponent(EntityID entity)
|
||||||
{
|
{
|
||||||
|
@ -249,6 +315,7 @@ namespace SHADE
|
||||||
static ECS::ECS()
|
static ECS::ECS()
|
||||||
{
|
{
|
||||||
componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
|
componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
|
||||||
|
componentMap.Add(createComponentSet<SHRenderable, Renderable>());
|
||||||
componentMap.Add(createComponentSet<SHColliderComponent, Collider>());
|
componentMap.Add(createComponentSet<SHColliderComponent, Collider>());
|
||||||
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
componentMap.Add(createComponentSet<SHRigidBodyComponent, RigidBody>());
|
||||||
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
componentMap.Add(createComponentSet<SHCameraComponent, Camera>());
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace SHADE
|
||||||
generic<typename T> where T : BaseComponent
|
generic<typename T> where T : BaseComponent
|
||||||
static T GetComponent(EntityID entity);
|
static T GetComponent(EntityID entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the first Component from the specified GameObjectt's children that
|
/// Retrieves the first Component from the specified GameObject's children that
|
||||||
/// matches the specified type.
|
/// matches the specified type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
@ -65,6 +65,20 @@ namespace SHADE
|
||||||
generic<typename T> where T : BaseComponent
|
generic<typename T> where T : BaseComponent
|
||||||
static T GetComponentInChildren(EntityID entity);
|
static T GetComponentInChildren(EntityID entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves a list of Components from the specified GameObject's children that
|
||||||
|
/// matches the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetComponentInChildren() instead.
|
||||||
|
/// This does not search the specified entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
/// <param name="entity"> Entity object to get the Component from. </param>
|
||||||
|
/// <returns>
|
||||||
|
/// Newly allocated List of components. Will be null if no components are found.
|
||||||
|
/// </returns>
|
||||||
|
generic<typename T> where T : BaseComponent
|
||||||
|
static System::Collections::Generic::IEnumerable<T>^ GetComponentsInChildren(EntityID entity);
|
||||||
|
/// <summary>
|
||||||
/// Ensures a Component on the specified Entity.
|
/// Ensures a Component on the specified Entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
|
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
|
||||||
|
|
|
@ -170,6 +170,14 @@ namespace SHADE
|
||||||
return ECS::GetComponentInChildren<T>(entity);
|
return ECS::GetComponentInChildren<T>(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic<typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GameObject::GetComponentsInChildren()
|
||||||
|
{
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
return ECS::GetComponentsInChildren<T>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
T GameObject::EnsureComponent()
|
T GameObject::EnsureComponent()
|
||||||
{
|
{
|
||||||
|
@ -212,6 +220,13 @@ namespace SHADE
|
||||||
throw gcnew System::NullReferenceException();
|
throw gcnew System::NullReferenceException();
|
||||||
return ScriptStore::GetScriptInChildren<T>(entity);
|
return ScriptStore::GetScriptInChildren<T>(entity);
|
||||||
}
|
}
|
||||||
|
generic <typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScriptsInChildren()
|
||||||
|
{
|
||||||
|
if (!valid)
|
||||||
|
throw gcnew System::NullReferenceException();
|
||||||
|
return ScriptStore::GetScriptsInChildren<T>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
|
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
|
||||||
|
|
|
@ -153,6 +153,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the first Component from this GameObject's children that matches
|
/// Retrieves the first Component from this GameObject's children that matches
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
@ -162,6 +163,19 @@ namespace SHADE
|
||||||
generic<typename T> where T : BaseComponent
|
generic<typename T> where T : BaseComponent
|
||||||
T GetComponentInChildren();
|
T GetComponentInChildren();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves a list of Components from this GameObject's children that matches
|
||||||
|
/// the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetComponentInChildren() instead.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// Newly allocated List of components. Will be null if no components are found.
|
||||||
|
/// </returns>
|
||||||
|
generic<typename T> where T : BaseComponent
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GetComponentsInChildren();
|
||||||
|
/// <summary>
|
||||||
/// Ensures a Component on this GameObject.
|
/// Ensures a Component on this GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
|
/// <typeparam name="T">Type of the Component to ensure.</typeparam>
|
||||||
|
@ -201,12 +215,26 @@ namespace SHADE
|
||||||
/// Retrieves a Script of the specified type from child GameObjects.
|
/// Retrieves a Script of the specified type from child GameObjects.
|
||||||
/// If multiple Scripts of the same specified type are added on the same
|
/// If multiple Scripts of the same specified type are added on the same
|
||||||
/// child GameObject, this will retrieve the first one added.
|
/// child GameObject, this will retrieve the first one added.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of Script to retrieve.</typeparam>
|
/// <typeparam name="T">Type of Script to retrieve.</typeparam>
|
||||||
/// <returns>Reference to the Script to retrieve.</returns>
|
/// <returns>Reference to the Script to retrieve.</returns>
|
||||||
generic<typename T> where T : ref class, Script
|
generic<typename T> where T : ref class, Script
|
||||||
T GetScriptInChildren();
|
T GetScriptInChildren();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves a list of Scripts from this GameObject's children that matches
|
||||||
|
/// the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetComponentInChildren() instead.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// Newly allocated List of components. Will be null if no components are found.
|
||||||
|
/// </returns>
|
||||||
|
generic<typename T> where T : ref class, Script
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GetScriptsInChildren();
|
||||||
|
/// <summary>
|
||||||
/// Retrieves a immutable list of Scripts of the specified type from this
|
/// Retrieves a immutable list of Scripts of the specified type from this
|
||||||
/// GameObject.
|
/// GameObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -42,6 +42,12 @@ namespace SHADE
|
||||||
return owner.GetComponentInChildren<T>();
|
return owner.GetComponentInChildren<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic<typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ Script::GetComponentsInChildren()
|
||||||
|
{
|
||||||
|
return owner.GetComponentsInChildren<T>();
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
T Script::EnsureComponent()
|
T Script::EnsureComponent()
|
||||||
{
|
{
|
||||||
|
@ -72,6 +78,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return ScriptStore::GetScriptInChildren<T>(owner.GetEntity());
|
return ScriptStore::GetScriptInChildren<T>(owner.GetEntity());
|
||||||
}
|
}
|
||||||
|
generic <typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ Script::GetScriptsInChildren()
|
||||||
|
{
|
||||||
|
return ScriptStore::GetScriptsInChildren<T>(owner.GetEntity());
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
System::Collections::Generic::IEnumerable<T>^ Script::GetScripts()
|
System::Collections::Generic::IEnumerable<T>^ Script::GetScripts()
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the first Component from this GameObject's children that matches
|
/// Retrieves the first Component from this GameObject's children that matches
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// Type of the Component to get. Must be derived from BaseComponent.
|
/// Type of the Component to get. Must be derived from BaseComponent.
|
||||||
|
@ -77,6 +78,19 @@ namespace SHADE
|
||||||
generic<typename T> where T : BaseComponent
|
generic<typename T> where T : BaseComponent
|
||||||
T GetComponentInChildren();
|
T GetComponentInChildren();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves a list of Components from this GameObject's children that
|
||||||
|
/// matches the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetComponentInChildren() instead.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// Newly allocated List of components. Will be null if no components are found.
|
||||||
|
/// </returns>
|
||||||
|
generic<typename T> where T : BaseComponent
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GetComponentsInChildren();
|
||||||
|
/// <summary>
|
||||||
/// Ensures a Component on the GameObject that this Script belongs to.
|
/// Ensures a Component on the GameObject that this Script belongs to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
|
@ -121,6 +135,7 @@ namespace SHADE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the first Script from this GameObject's children that matches the
|
/// Retrieves the first Script from this GameObject's children that matches the
|
||||||
/// specified type.
|
/// specified type.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">
|
/// <typeparam name="T">
|
||||||
/// Type of script to get.
|
/// Type of script to get.
|
||||||
|
@ -130,6 +145,19 @@ namespace SHADE
|
||||||
generic<typename T> where T : ref class, Script
|
generic<typename T> where T : ref class, Script
|
||||||
T GetScriptInChildren();
|
T GetScriptInChildren();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves a list of Scripts from this GameObject's children that matches
|
||||||
|
/// the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetComponentInChildren() instead.
|
||||||
|
/// Unlike Unity, we do not search this GameObject, only the children.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the Component to get.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// Newly allocated List of components. Will be null if no components are found.
|
||||||
|
/// </returns>
|
||||||
|
generic<typename T> where T : ref class, Script
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ GetScriptsInChildren();
|
||||||
|
/// <summary>
|
||||||
/// Retrieves a immutable list of scripts from the specified Entity that
|
/// Retrieves a immutable list of scripts from the specified Entity that
|
||||||
/// matches the specified type.
|
/// matches the specified type.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
|
|
@ -211,6 +211,70 @@ namespace SHADE
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic<typename T>
|
||||||
|
System::Collections::Generic::IEnumerable<T>^ ScriptStore::GetScriptsInChildren(Entity entity)
|
||||||
|
{
|
||||||
|
System::Type^ componentType = T::typeid;
|
||||||
|
|
||||||
|
// Check if entity is correct
|
||||||
|
if (!SHEntityManager::IsValidEID(entity))
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptStore] Attempted to retrieve Script \""
|
||||||
|
<< Convert::ToNative(componentType->Name)
|
||||||
|
<< "\" from invalid Entity.";
|
||||||
|
Debug::LogError(oss.str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search all elements via a iterative breadth first search
|
||||||
|
System::Collections::Generic::List<T>^ results;
|
||||||
|
System::Collections::Generic::Queue<Entity>^ searchSpace = gcnew System::Collections::Generic::Queue<Entity>();
|
||||||
|
// Start off with direct children
|
||||||
|
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity);
|
||||||
|
if (entityNode == nullptr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptStore] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||||
|
SHLog::Warning(oss.str());
|
||||||
|
}
|
||||||
|
for (const auto& child : entityNode->GetChildren())
|
||||||
|
{
|
||||||
|
searchSpace->Enqueue(child->GetEntityID());
|
||||||
|
}
|
||||||
|
// Continue with all subsequent children
|
||||||
|
while (searchSpace->Count > 0)
|
||||||
|
{
|
||||||
|
// Check if this entity has the component we need
|
||||||
|
Entity curr = searchSpace->Dequeue();
|
||||||
|
T script = GetScript<T>(curr);
|
||||||
|
if (script != nullptr)
|
||||||
|
{
|
||||||
|
// We only construct if we need to
|
||||||
|
if (results == nullptr)
|
||||||
|
results = gcnew System::Collections::Generic::List<T>();
|
||||||
|
results->Add(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add children to the queue
|
||||||
|
SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(curr);
|
||||||
|
if (sceneGraphNode == nullptr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptStore] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!";
|
||||||
|
SHLog::Warning(oss.str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const auto& child : sceneGraphNode->GetChildren())
|
||||||
|
{
|
||||||
|
searchSpace->Enqueue(child->GetEntityID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// None here
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
generic <typename T>
|
generic <typename T>
|
||||||
System::Collections::Generic::IEnumerable<T>^ ScriptStore::GetScripts(Entity entity)
|
System::Collections::Generic::IEnumerable<T>^ ScriptStore::GetScripts(Entity entity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -137,6 +137,29 @@ namespace SHADE
|
||||||
generic<typename T> where T : ref class, Script
|
generic<typename T> where T : ref class, Script
|
||||||
static T GetScriptInChildren(Entity entity);
|
static T GetScriptInChildren(Entity entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Retrieves the list of Scripts from the specified Entity and the Entity's
|
||||||
|
/// children that matches the specified type.
|
||||||
|
/// This function performs allocations. If expecting only 1 component, use
|
||||||
|
/// GetScriptInChildren() instead.
|
||||||
|
/// This does not search the specified entity.
|
||||||
|
/// </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 System::Collections::Generic::IEnumerable<T>^ GetScriptsInChildren(Entity entity);
|
||||||
|
/// <summary>
|
||||||
/// Retrieves a immutable list of scripts from the specified Entity that
|
/// Retrieves a immutable list of scripts from the specified Entity that
|
||||||
/// matches the specified type.
|
/// matches the specified type.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
|
|
|
@ -28,7 +28,47 @@ namespace SHADE
|
||||||
template<typename FieldType>
|
template<typename FieldType>
|
||||||
bool SerialisationUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode)
|
bool SerialisationUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Node& fieldNode)
|
||||||
{
|
{
|
||||||
return varInsertYamlInternal<FieldType>(fieldInfo->GetValue(object), fieldNode);
|
// Handle null objects
|
||||||
|
System::Object^ fieldObject = fieldInfo->GetValue(object);
|
||||||
|
if (fieldObject == nullptr)
|
||||||
|
{
|
||||||
|
// Default construct if null
|
||||||
|
if (fieldInfo->FieldType == FieldType::typeid)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<FieldType, System::Enum>)
|
||||||
|
{
|
||||||
|
fieldNode = 0;
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, System::String>)
|
||||||
|
{
|
||||||
|
fieldNode = "";
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, Vector2>)
|
||||||
|
{
|
||||||
|
fieldNode.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
fieldNode.push_back(0.0f);
|
||||||
|
fieldNode.push_back(0.0f);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, Vector3>)
|
||||||
|
{
|
||||||
|
fieldNode.SetStyle(YAML::EmitterStyle::Flow);
|
||||||
|
fieldNode.push_back(0.0f);
|
||||||
|
fieldNode.push_back(0.0f);
|
||||||
|
fieldNode.push_back(0.0f);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<FieldType, GameObject>)
|
||||||
|
{
|
||||||
|
fieldNode = MAX_EID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldNode = FieldType();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return varInsertYamlInternal<FieldType>(fieldObject, fieldNode);
|
||||||
}
|
}
|
||||||
template<typename FieldType>
|
template<typename FieldType>
|
||||||
bool SerialisationUtilities::varInsertYamlInternal(System::Object^ object, YAML::Node& fieldNode)
|
bool SerialisationUtilities::varInsertYamlInternal(System::Object^ object, YAML::Node& fieldNode)
|
||||||
|
|
Loading…
Reference in New Issue