Merge remote-tracking branch 'origin/main' into SP3-1-Rendering

This commit is contained in:
Brandon Mak 2022-10-30 13:18:15 +08:00
commit 7b769057a2
26 changed files with 1037 additions and 448 deletions

View File

@ -159,7 +159,7 @@ namespace Sandbox
SHSceneManager::Exit();
SHSystemManager::Exit();
SHAssetManager::Unload();
SHAssetManager::Exit();
}
}

View File

@ -61,8 +61,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -86,7 +103,7 @@ namespace SHADE
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1> action)
{
targetAction = action;
@ -103,7 +120,7 @@ namespace SHADE
{
targetAction.Invoke(t1);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
_ = targetMethod.Invoke(TargetObject, parameters);
@ -138,8 +155,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[2];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -158,12 +192,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[2];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2> action)
{
targetAction = action;
@ -180,7 +214,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -216,8 +250,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[3];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -236,12 +287,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[3];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3> action)
{
targetAction = action;
@ -258,7 +309,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -295,8 +346,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[4];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -315,12 +383,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[4];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4> action)
{
targetAction = action;
@ -337,7 +405,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -375,8 +443,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[5];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -395,12 +480,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[5];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5> action)
{
targetAction = action;
@ -417,7 +502,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -456,8 +541,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[6];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -476,12 +578,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[6];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5, T6> action)
{
targetAction = action;
@ -498,7 +600,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5, t6);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -538,8 +640,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[7];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -558,12 +677,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[7];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
{
targetAction = action;
@ -580,7 +699,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5, t6, t7);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -621,8 +740,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[8];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -641,12 +777,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[8];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
{
targetAction = action;
@ -663,7 +799,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5, t6, t7, t8);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -705,8 +841,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[9];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -725,12 +878,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[9];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
{
targetAction = action;
@ -747,7 +900,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5, t6, t7, t8, t9);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;
@ -790,8 +943,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[10];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -810,12 +980,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[10];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
{
targetAction = action;
@ -832,7 +1002,7 @@ namespace SHADE
{
targetAction.Invoke(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
parameters[0] = t1;
parameters[1] = t2;

View File

@ -78,8 +78,25 @@ namespace SHADE
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified method on the
/// specified target.
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[<#=i#>];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
@ -98,12 +115,12 @@ namespace SHADE
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[1];
parameters = new Object[<#=i#>];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action"></param>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action)
{
targetAction = action;
@ -120,7 +137,7 @@ namespace SHADE
{
targetAction.Invoke(<# for (int t = 1; t < i + 1; ++t) { #>t<#=t#><# if (t != i) { #>, <# } #><# } #>);
}
else if (TargetObject != null && targetMethod != null)
else if (targetMethod != null)
{
<# for (int t = 0; t < i; ++t) {#>parameters[<#=t#>] = t<#=t+1#>;
<# } #>_ = targetMethod.Invoke(TargetObject, parameters);

View File

@ -0,0 +1,23 @@
/******************************************************************************
* \file SHMaterialAsset.h
* \author Loh Xiao Qi
* \date 29 October 2022
* \brief
*
* \copyright 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
#include "Assets/Asset Types/SHAssetData.h"
#include <string>
namespace SHADE
{
struct SHMaterialAsset : SHAssetData
{
std::string name;
std::string data;
};
}

View File

@ -0,0 +1,23 @@
/******************************************************************************
* \file SHPrefabAsset.h
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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
#include "SHAssetData.h"
#include <string>
namespace SHADE
{
struct SHPrefabAsset : SHAssetData
{
std::string name;
std::string data;
};
}

View File

@ -0,0 +1,23 @@
/******************************************************************************
* \file SHSceneAsset.h
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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
#include "SHAssetData.h"
#include <string>
namespace SHADE
{
struct SHSceneAsset : SHAssetData
{
std::string name;
std::string data;
};
}

View File

@ -18,5 +18,6 @@ namespace SHADE
struct SHAssetLoader
{
virtual SHAssetData* Load(AssetPath path) = 0;
virtual void Write(SHAssetData const* data, AssetPath path) = 0;
};
}

View File

@ -22,6 +22,7 @@ namespace SHADE
if (!file.is_open())
{
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
return;
}
const std::string name{ path.stem().string() };
@ -75,4 +76,55 @@ namespace SHADE
return result;
}
void SHMeshLoader::Write(SHAssetData const* data, AssetPath path)
{
std::ofstream file{ path, std::ios::out | std::ios::binary | std::ios::trunc };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
}
auto asset = *dynamic_cast<SHMeshAsset const*>(data);
file.write(
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
sizeof(uint32_t)
);
file.write(
reinterpret_cast<const char*>(&(asset.header.indexCount)),
sizeof(uint32_t)
);
auto const vertexVec3Byte{ sizeof(SHVec3) * asset.header.vertexCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * asset.header.vertexCount };
file.write(
reinterpret_cast<char const*>(asset.vertexPosition.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexTangent.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.vertexNormal.data()),
vertexVec3Byte
);
file.write(
reinterpret_cast<char const*>(asset.texCoords.data()),
vertexVec2Byte
);
file.write(
reinterpret_cast<char const*>(asset.indices.data()),
sizeof(uint32_t) * asset.header.indexCount
);
file.close();
}
}

View File

@ -10,7 +10,6 @@
* of DigiPen Institute of Technology is prohibited.
*****************************************************************************/
#pragma once
#include "Assets/SHAssetMacros.h"
#include "Assets/Asset Types/SHMeshAsset.h"
#include "SHAssetLoader.h"
@ -20,5 +19,6 @@ namespace SHADE
{
void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
SHAssetData* Load(AssetPath path) override;
void Write(SHAssetData const* data, AssetPath path) override;
};
}

View File

@ -43,4 +43,27 @@ namespace SHADE
return result;
}
void SHShaderSourceLoader::Write(SHAssetData const* data, AssetPath path)
{
std::ofstream file{ path, std::ios::binary | std::ios::out | std::ios::trunc };
auto asset = *dynamic_cast<SHShaderAsset const*>(data);
file.write(
reinterpret_cast<char const*>(&asset.shaderType), sizeof(uint8_t)
);
size_t const byteCount = sizeof(uint32_t) * asset.spirvBinary.size();
file.write(
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
);
file.write(
reinterpret_cast<char const*>(asset.spirvBinary.data()), byteCount
);
file.close();
}
}

View File

@ -11,12 +11,12 @@
#pragma once
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE
{
struct SHShaderSourceLoader : SHAssetLoader
{
SHAssetData* Load(AssetPath path) override;
void Write(SHAssetData const* data, AssetPath path) override;
};
}

View File

@ -0,0 +1,95 @@
/******************************************************************************
* \file SHTextBasedLoader.cpp
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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.
******************************************************************************/
#include "SHpch.h"
#include "SHTextBasedLoader.h"
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Assets/Asset Types/SHPrefabAsset.h"
#include "Assets/Asset Types/SHMaterialAsset.h"
#include <fstream>
#include <sstream>
namespace SHADE
{
SHAssetData* SHTextBasedLoader::Load(AssetPath path)
{
std::ifstream file{ path, std::ios::in };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open text File: {}", path.string());
return nullptr;
}
std::stringstream stream;
stream << file.rdbuf();
std::string content = stream.str();
SHAssetData* result;
if (path.extension().string() == SCENE_EXTENSION)
{
auto data = new SHSceneAsset();
data->name = path.stem().string();
data->data = std::move(content);
result = data;
}
else if (path.extension().string() == PREFAB_EXTENSION)
{
auto data = new SHPrefabAsset();
data->name = path.stem().string();
data->data = std::move(content);
result = data;
}
else if (path.extension().string() == MATERIAL_EXTENSION)
{
auto data = new SHMaterialAsset();
data->name = path.stem().string();
data->data = std::move(content);
result = data;
}
file.close();
return result;
}
void SHTextBasedLoader::Write(SHAssetData const* data, AssetPath path)
{
std::ofstream file{ path, std::ios::out | std::ios::trunc };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open text File: {}", path.string());
return;
}
if (path.extension().string() == SCENE_EXTENSION)
{
auto scene = dynamic_cast<SHSceneAsset const*>(data);
file << scene->data;
}
else if (path.extension().string() == PREFAB_EXTENSION)
{
auto prefab = dynamic_cast<SHPrefabAsset const*>(data);
file << prefab->data;
}
else if (path.extension().string() == MATERIAL_EXTENSION)
{
auto material = dynamic_cast<SHMaterialAsset const*>(data);
file << material->data;
}
file.close();
}
}

View File

@ -0,0 +1,21 @@
/******************************************************************************
* \file Header.h
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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
#include "SHAssetLoader.h"
namespace SHADE
{
struct SHTextBasedLoader : SHAssetLoader
{
SHAssetData* Load(AssetPath path) override;
void Write(SHAssetData const* data, AssetPath path) override;
};
}

View File

@ -55,4 +55,56 @@ namespace SHADE
return result;
}
void SHTextureLoader::Write(SHAssetData const* data, AssetPath path)
{
std::ofstream file{ path, std::ios::out | std::ios::binary };
if (!file.is_open())
{
SHLOG_ERROR("Unable to open file for writing texture file: {}", path.string());
}
auto asset = *dynamic_cast<SHTextureAsset const*>(data);
constexpr auto intBytes{ sizeof(uint32_t) };
uint32_t const mipOffsetCount{ static_cast<uint32_t>(asset.mipOffsets.size()) };
file.write(
reinterpret_cast<char const*>(&asset.numBytes),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.width),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.height),
intBytes
);
file.write(
reinterpret_cast<char const*>(&asset.format),
sizeof(SHTexture::TextureFormat)
);
file.write(
reinterpret_cast<char const*>(&mipOffsetCount),
intBytes
);
file.write(
reinterpret_cast<char const*>(asset.mipOffsets.data()),
intBytes * asset.mipOffsets.size()
);
file.write(
reinterpret_cast<char const*>(asset.pixelData),
asset.numBytes
);
file.close();
}
}

View File

@ -10,8 +10,6 @@
* of DigiPen Institute of Technology is prohibited.
*****************************************************************************/
#pragma once
#include "Assets/SHAssetMacros.h"
#include "Assets/Asset Types/SHTextureAsset.h"
#include "SHAssetLoader.h"
@ -21,5 +19,6 @@ namespace SHADE
{
void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
SHAssetData* Load(AssetPath path) override;
void Write(SHAssetData const* data, AssetPath path) override;
};
}

View File

@ -11,7 +11,6 @@
*****************************************************************************/
#pragma once
#include "Filesystem/SHFileSystem.h"
#include "Assets/SHAssetMacros.h"
#include "SH_API.h"
@ -23,6 +22,5 @@ namespace SHADE
AssetID id;
AssetType type;
AssetPath path;
FolderLocation location;
};
}

View File

@ -47,17 +47,27 @@ enum class AssetType : AssetTypeMeta
SHADER_BUILT_IN,
TEXTURE,
MESH,
SCENE,
PREFAB,
MATERIAL,
MAX_COUNT
};
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
//Directory
#ifdef _PUBLISH
constexpr std::string_view ASSET_ROOT {"Assets"};
constexpr std::string_view ASSET_ROOT{ "Assets" };
constexpr std::string_view BUILT_IN_ASSET_ROOT {"Built_In"};
#else
constexpr std::string_view ASSET_ROOT {"../../Assets"};
constexpr std::string_view BUILT_IN_ASSET_ROOT{ "../../Built_In" };
#endif
// INTERNAL ASSET PATHS
constexpr std::string_view SCENE_FOLDER{ "/Scenes/" };
constexpr std::string_view PREFAB_FOLDER{ "/Prefabs/" };
constexpr std::string_view MATERIAL_FOLDER{ "/Materials/" };
// ASSET EXTENSIONS
constexpr std::string_view META_EXTENSION {".shmeta"};

View File

@ -10,28 +10,34 @@
#include "SHpch.h"
#include <random>
#include <chrono>
#include <ranges>
#include "SHAssetManager.h"
#include "SHAssetMetaHandler.h"
#include "Filesystem/SHFileSystem.h"
#include "Libraries/Loaders/SHMeshLoader.h"
#include "Libraries/Loaders/SHTextureLoader.h"
#include "Libraries/Loaders/SHShaderSourceLoader.h"
#include "Libraries/Loaders/SHTextBasedLoader.h"
#include "Libraries/Compilers/SHMeshCompiler.h"
#include "Libraries/Compilers/SHTextureCompiler.h"
#include "Libraries/Compilers/SHShaderSourceCompiler.h"
#include "Filesystem/SHFileSystem.h"
namespace SHADE
{
FolderPointer SHAssetManager::folderRoot{ nullptr };
FMOD::System* SHAssetManager::audioSystem;
std::unordered_map<AssetID, SHSound >* SHAssetManager::audioSoundList;
std::vector<SHAssetLoader*> SHAssetManager::loaders(TYPE_COUNT);
std::vector<SHAsset> SHAssetManager::assetCollection;
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetCollection;
std::unordered_map<AssetID, SHAssetData * const> SHAssetManager::assetData;
/****************************************************************************
* \brief Static function to generate asset ID.
****************************************************************************/
@ -45,13 +51,7 @@ namespace SHADE
result |= unique;
while (result == 0 ||
std::ranges::any_of(
assetCollection.begin(),
assetCollection.end(),
[result](SHAsset const& asset) { return asset.id == result; }
)
)
while (result == 0 || assetCollection.contains(result))
{
result = GenerateAssetID(type);
}
@ -61,11 +61,6 @@ namespace SHADE
/****************************************************************************
* \brief Deallocate all memory used by asset data
****************************************************************************/
void SHAssetManager::Unload() noexcept
{
}
void SHAssetManager::Unload(AssetID assetId) noexcept
{
// TODO
@ -73,14 +68,14 @@ namespace SHADE
void SHAssetManager::Exit() noexcept
{
for (auto const& loader : loaders)
{
delete loader;
}
delete loaders[static_cast<size_t>(AssetType::SHADER)];
delete loaders[static_cast<size_t>(AssetType::TEXTURE)];
delete loaders[static_cast<size_t>(AssetType::MESH)];
delete loaders[static_cast<size_t>(AssetType::SCENE)];
for (auto const& data : assetData)
for (auto const& data : std::ranges::views::values(assetData))
{
delete data.second;
delete data;
}
}
@ -133,9 +128,17 @@ namespace SHADE
*
* \return const& to unordered_map<AssetName, AssetID>
****************************************************************************/
std::vector<SHAsset> const& SHAssetManager::GetAllAssets() noexcept
std::vector<SHAsset> SHAssetManager::GetAllAssets() noexcept
{
return assetCollection;
std::vector<SHAsset> result;
result.reserve(assetCollection.size());
for (auto const& asset : std::ranges::views::values(assetCollection))
{
result.push_back(asset);
}
return result;
}
/****************************************************************************
@ -148,41 +151,113 @@ namespace SHADE
****************************************************************************/
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
{
AssetID id{ GenerateAssetID(type) };
SHAsset meta;
meta.id = id;
meta.type = type;
std::string newPath{ ASSET_ROOT };
switch (type)
{
case AssetType::PREFAB:
newPath += PREFAB_FOLDER;
break;
std::string folder;
//TODO implement folder choosing
//switch (type)
//{
//default:
// folder = "";
// break;
//}
AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
case AssetType::SCENE:
newPath += SCENE_FOLDER;
break;
SHAssetMetaHandler::WriteMetaData(meta);
case AssetType::MATERIAL:
newPath += MATERIAL_FOLDER;
break;
assetCollection.push_back(meta);
return id;
default:
SHLOG_ERROR("Asset type of {} not an internal asset type, cannot be created", name);
return 0;
}
AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept
{
AssetID id = GenerateAssetID(type);
assetCollection.emplace_back(
auto id = GenerateAssetID(type);
SHAsset asset{
name,
id,
type,
GenerateNewPath(name, type),
0
);
newPath
};
assetCollection.insert({
id,
SHAsset(
name,
id,
type,
newPath
)
});
return id;
}
bool SHAssetManager::SaveAsset(AssetID id) noexcept
{
if (assetCollection.contains(id))
{
auto const& asset = assetCollection[id];
if (
asset.type == AssetType::SCENE ||
asset.type == AssetType::PREFAB ||
asset.type == AssetType::MATERIAL
)
{
if (assetData.contains(id))
{
auto const data = assetData.at(id);
loaders[static_cast<size_t>(asset.type)]->Write(data, asset.path);
SHAssetMetaHandler::WriteMetaData(asset);
return true;
}
SHLOG_ERROR("Asset data has not been written into, cannot be saved: {}",
asset.path.filename().string());
return false;
}
}
SHLOG_WARNING("Asset id: {} not an internal asset type, save cannot be triggered", id);
return false;
}
bool SHAssetManager::DeleteAsset(AssetID id) noexcept
{
if (assetCollection.contains(id))
{
auto const& asset = assetCollection[id];
if (
asset.type == AssetType::SCENE ||
asset.type == AssetType::PREFAB ||
asset.type == AssetType::MATERIAL
)
{
return (DeleteLocalFile(asset.path) && DeleteLocalFile(asset.path.string() + META_EXTENSION.data()));
}
SHLOG_WARNING("Asset id: {} not an internal asset type, file deletion not allowed", id);
}
SHLOG_WARNING("Asset id does not exist, nothing was deleted: {}", id);
return false;
}
//AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept
//{
// AssetID id = GenerateAssetID(type);
// assetCollection.emplace_back(
// name,
// id,
// type,
// GenerateNewPath(name, type)
// );
// return id;
//}
/****************************************************************************
* \brief Import new asset from outside editor window.
*
@ -205,7 +280,8 @@ namespace SHADE
std::filesystem::copy(path, newPath);
assetCollection.push_back(CreateAssetFromPath(newPath));
auto asset = CreateAssetFromPath(newPath);
assetCollection.insert({asset.id, asset});
return id;
}
@ -235,7 +311,7 @@ namespace SHADE
std::vector<SHAsset> SHAssetManager::GetAllRecordOfType(AssetType type) noexcept
{
std::vector<SHAsset> result;
for (auto const& asset : assetCollection)
for (auto const& asset : std::ranges::views::values(assetCollection))
{
if (asset.type == type)
{
@ -246,12 +322,11 @@ namespace SHADE
return result;
}
AssetID SHAssetManager::CompileAsset(AssetPath path) noexcept
AssetID SHAssetManager::CompileAsset(AssetPath const& path) noexcept
{
SHAsset newAsset
{
.name = path.stem().string(),
.location = 0
.name = path.stem().string()
};
auto const ext{ path.extension().string() };
@ -262,12 +337,17 @@ namespace SHADE
newAsset.type = AssetType::SHADER_BUILT_IN;
}
assetCollection.push_back(newAsset);
assetCollection.insert({ newAsset.id, newAsset });
SHAssetMetaHandler::WriteMetaData(newAsset);
return newAsset.id;
}
FolderPointer SHAssetManager::GetRootFolder() noexcept
{
return folderRoot;
}
bool SHAssetManager::IsRecognised(char const* ext) noexcept
{
for (auto const& e : EXTENSIONS)
@ -289,7 +369,6 @@ namespace SHADE
result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string());
result.id = GenerateAssetID(result.type);
result.path = path;
result.location = 0;
return result;
}
@ -316,8 +395,7 @@ namespace SHADE
{
SHAsset newAsset
{
.name = path.stem().string(),
.location = 0
.name = path.stem().string()
};
auto const ext{ path.extension().string() };
@ -342,29 +420,37 @@ namespace SHADE
for (auto const& mesh : meshes)
{
SHAsset meshAsset{
.name = mesh->header.name,
.location = 0
.name = mesh->header.name
};
meshAsset.path = SHMeshCompiler::CompileMeshBinary(*mesh, path).value();
meshAsset.id = GenerateAssetID(AssetType::MESH);
meshAsset.type = AssetType::MESH;
assetCollection.push_back(meshAsset);
//SHAssetMetaHandler::WriteMetaData(meshAsset);
assetCollection.insert({ meshAsset.id, meshAsset });
SHAssetMetaHandler::WriteMetaData(meshAsset);
}
continue;
}
assetCollection.push_back(newAsset);
//SHAssetMetaHandler::WriteMetaData(newAsset);
assetCollection.insert({ newAsset.id, newAsset });
SHAssetMetaHandler::WriteMetaData(newAsset);
}
}
void SHAssetManager::InitLoaders() noexcept
bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept
{
//TODO Move this to dedicated library
return std::filesystem::remove(path);
}
void SHAssetManager:: InitLoaders() noexcept
{
loaders[static_cast<size_t>(AssetType::SHADER)] = dynamic_cast<SHAssetLoader*>(new SHShaderSourceLoader());
loaders[static_cast<size_t>(AssetType::SHADER_BUILT_IN)] = loaders[static_cast<size_t>(AssetType::SHADER)];
loaders[static_cast<size_t>(AssetType::TEXTURE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader());
loaders[static_cast<size_t>(AssetType::SCENE)] = dynamic_cast<SHAssetLoader*>(new SHTextBasedLoader());
loaders[static_cast<size_t>(AssetType::PREFAB)] = loaders[static_cast<size_t>(AssetType::SCENE)];
loaders[static_cast<size_t>(AssetType::MATERIAL)] = loaders[static_cast<size_t>(AssetType::SCENE)];
}
/****************************************************************************
@ -372,9 +458,9 @@ namespace SHADE
****************************************************************************/
void SHAssetManager::Load() noexcept
{
CompileAll();
InitLoaders();
//CompileAll();
BuildAssetCollection();
InitLoaders();
//LoadAllData();
}
@ -383,7 +469,7 @@ namespace SHADE
****************************************************************************/
void SHAssetManager::LoadAllData() noexcept
{
for (auto const& asset : assetCollection)
for (auto const& asset : std::ranges::views::values(assetCollection))
{
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
assetData.emplace(asset.id, data);
@ -408,15 +494,6 @@ namespace SHADE
void SHAssetManager::BuildAssetCollection() noexcept
{
for (auto const& dir : std::filesystem::recursive_directory_iterator{ASSET_ROOT})
{
if (dir.is_regular_file())
{
if (dir.path().extension().string() == META_EXTENSION.data())
{
assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path()));
}
}
}
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection);
}
}

View File

@ -10,10 +10,12 @@
******************************************************************************/
#pragma once
#include "tinyddsloader.h"
#include "SHAsset.h"
#include "Asset Types/SHAssetData.h"
#include "Assets/Libraries/Loaders/SHAssetLoader.h"
#include <memory>
#include "Filesystem/SHFolder.h"
#include "SH_API.h"
@ -26,19 +28,17 @@ namespace SHADE
* \brief Static function to generate resource ID.
****************************************************************************/
static AssetID GenerateAssetID(AssetType type) noexcept;
static AssetPath GenerateLocalPath(AssetPath path) noexcept;
static AssetPath GenerateNewPath(AssetName name, AssetType type);
/****************************************************************************
* \brief Deallocate all memory used by resource data
****************************************************************************/
static void Unload() noexcept;
static void Unload(AssetID assetId) noexcept;
static void Exit() noexcept;
static void Unload(AssetID assetId) noexcept;
/****************************************************************************
* \brief Load all resources that are in the folder
****************************************************************************/
@ -49,7 +49,7 @@ namespace SHADE
*
* \return const& to unordered_map<AssetName, AssetID>
****************************************************************************/
static std::vector<SHAsset> const& GetAllAssets() noexcept;
static std::vector<SHAsset> GetAllAssets() noexcept;
/****************************************************************************
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
@ -59,8 +59,9 @@ namespace SHADE
* \param name of resource
* \return resource id generated for new asset
****************************************************************************/
static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
static AssetID CreateAsset(AssetName name, AssetType type) noexcept;
static AssetID CreateNewAsset(AssetType type, AssetName name) noexcept;
static bool SaveAsset(AssetID id) noexcept;
static bool DeleteAsset(AssetID id) noexcept;
/****************************************************************************
* \brief Import new resource from outside editor window.
@ -78,12 +79,17 @@ namespace SHADE
// -------------------------------------------------------------------------/
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> GetData(AssetID id) noexcept;
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T* const> GetData(AssetID id) noexcept;
template<typename T>
static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> GetConstData(AssetID id) noexcept;
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static AssetID CompileAsset(AssetPath path) noexcept;
static AssetID CompileAsset(AssetPath const& path) noexcept;
static FolderPointer GetRootFolder() noexcept;
private:
@ -98,13 +104,20 @@ namespace SHADE
static void CompileAll() noexcept;
static bool DeleteLocalFile(AssetPath path) noexcept;
//TODO use this function to create asset data internall at all calls to generate id
//static AssetID CreateAsset(AssetName name, AssetType type) noexcept;
static FolderPointer folderRoot;
static FMOD::System* audioSystem;
static std::unordered_map<AssetID,SHSound>* audioSoundList;
static std::vector<SHAssetLoader*> loaders;
// For all resources
static std::vector<SHAsset> assetCollection;
static std::unordered_map<AssetID, SHAsset> assetCollection;
static std::unordered_map<AssetID, SHAssetData * const> assetData;
};
}

View File

@ -4,11 +4,32 @@
namespace SHADE
{
template<typename T>
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> SHAssetManager::GetData(AssetID id) noexcept
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T* const> SHAssetManager::GetData(AssetID id) noexcept
{
if (!assetData.contains(id))
{
for (auto const& asset : assetCollection)
for (auto const& asset : std::ranges::views::values(assetCollection))
{
if (asset.id == id)
{
assetData.emplace(id, LoadData(asset));
return dynamic_cast<T* const>(assetData[id]);
}
}
SHLOG_ERROR("Asset ID provided does not exist: {}", id);
return nullptr;
}
return dynamic_cast<T* const>(assetData[id]);
}
template<typename T>
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const * const> SHAssetManager::GetConstData(AssetID id) noexcept
{
if (!assetData.contains(id))
{
for (auto const& asset : std::ranges::views::values(assetCollection))
{
if (asset.id == id)
{

View File

@ -1,159 +1,82 @@
/*************************************************************************//**
* \file SHFileSystem.cpp
* \author Loh Xiao Qi
* \date 30 October 2022
* \brief
*
* Copyright (C) 2022 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.
*****************************************************************************/
#include "SHpch.h"
#include "SHFileSystem.h"
#include "fileapi.h"
#include <filesystem>
#include <queue>
#include "Assets/SHAssetMetaHandler.h"
namespace SHADE
{
char const FOLDER_MAX_COUNT {15};
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders;
FolderPointer SHFileSystem::root {nullptr};
SHFolder::SHFolder(FolderHandle id, FolderName name)
:id{ id }, name{ name }, subFolders(0), folded{ false }, path{""}
{
}
FolderLocation SHFileSystem::CreateNewFolderHere(FolderName name, FolderLocation here) noexcept
{
if (here == 0)
{
if (!folders.contains(0))
{
folders[0] = std::make_unique<SHFolder>(0, "root");
}
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
if (count >= FOLDER_MAX_COUNT)
{
SHLOG_ERROR("Max subfolder reached: {}\n", name);
}
auto const location = static_cast<FolderLocation>(count);
CreateFolder(folders[0]->path, here, location, name);
return location;
}
if (!folders.contains(here))
{
SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here);
}
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
FolderHandle location = here;
location <<= FOLDER_BIT_ALLOCATE;
location |= count;
if (count >= FOLDER_MAX_COUNT)
{
SHLOG_ERROR("Max subfolder reached: {}\n", name);
}
CreateFolder(folders[0]->path, here, location, name);
return location;
}
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
{
if (!folders.contains(location->id))
{
SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name);
}
for (auto const& subFolder : folders[location->id]->subFolders)
{
DeleteFolder(subFolder);
}
RemoveDirectoryA(folders[location->id]->path.c_str());
//TODO IMPLEMENT
return true;
}
void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
{
std::queue<FolderPointer> folderQueue;
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
root = new SHFolder("root");
root->path = path;
folderQueue.push(root);
while (!folderQueue.empty())
{
auto folder = folderQueue.front();
auto const folder = folderQueue.front();
folderQueue.pop();
FolderCounter count = 0;
std::vector<SHAsset> assets;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
{
auto const& path = dirEntry.path();
if (!dirEntry.is_directory())
{
if (path.extension().string() == META_EXTENSION)
{
//auto asset = SHAssetMetaHandler::RetrieveMetaData(path);
//assetCollection.insert({ asset.id, asset });
assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path));
}
else
{
folder->files.emplace_back(
dirEntry.path().filename().string(),
dirEntry.path().string(),
dirEntry.path().extension().string()
path.stem().string(),
path.string(),
path.extension().string(),
nullptr
);
}
continue;
}
FolderLocation location = folder->id;
location <<= FOLDER_BIT_ALLOCATE;
location |= ++count;
std::string name = dirEntry.path().string();
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
FolderPointer newFolder{ RegisterFolder(
dirEntry.path().string(),
folder->id,
location,
name)
};
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
folderQueue.push(newFolder);
folder->subFolders.push_back(newFolder);
}
}
}
FolderPointer SHFileSystem::GetRoot() noexcept
for (auto const& asset : assets)
{
return root;
}
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
assetCollection.emplace(asset.id, asset);
for(auto& file : folder->files)
{
if (!CreateDirectoryA(path.c_str(), nullptr))
if (file.name == asset.name)
{
SHLOG_ERROR("Failed to create folder: {}\n", path);
file.assetMeta = &assetCollection[asset.id];
break;
}
}
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return folders[location].get();
}
}

View File

@ -1,70 +1,28 @@
/******************************************************************************
* \file SHFileSystem.h
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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
#include <string>
#include <vector>
#include <memory>
#include "SHFolder.h"
#include <unordered_map>
namespace SHADE
{
class SHFolder;
typedef unsigned char FolderCounter;
typedef unsigned char FileCounter;
typedef uint64_t FolderLocation;
typedef uint64_t FolderHandle;
typedef std::string FolderName;
typedef std::string FileName;
typedef std::string FolderPath;
typedef std::string FilePath;
typedef std::string FileExt;
typedef SHFolder* FolderPointer;
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
constexpr char FOLDER_MAX_DEPTH{ 16 };
struct SHFile
{
FileName name;
FilePath path;
FileExt ext;
};
class SHFolder
{
public:
SHFolder(FolderHandle id, FolderName name);
FolderHandle id;
FolderName name;
std::vector<FolderPointer> subFolders;
std::vector<SHFile> files;
bool folded;
private:
FolderPath path;
friend class SHFileSystem;
};
class SHFileSystem
{
public:
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
static bool DeleteFolder(FolderPointer location) noexcept;
static void StartupFillDirectories(FolderPath path) noexcept;
static FolderPointer GetRoot() noexcept;
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
private:
static FolderPointer root;
static bool DeleteFolder(FolderPointer location) noexcept;
static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders;
static FolderPointer CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
};
}

View File

@ -0,0 +1,38 @@
/*************************************************************************//**
* \file SHFolder.cpp
* \author Loh Xiao Qi
* \date 30 October 2022
* \brief
*
* Copyright (C) 2022 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.
*****************************************************************************/
#include "SHpch.h"
#include "SHFolder.h"
namespace SHADE
{
SHFolder::SHFolder(FolderName name)
:name{ name }, subFolders(0), folded{ false }, path{ "" }
{
}
FolderPointer SHFolder::CreateSubFolderHere(FolderName name)
{
for (auto const& folder : subFolders)
{
if (name == folder->name)
{
SHLOG_ERROR("Unable to create subfolder {} at {} as it already exists", name, folder->name);
return nullptr;
}
}
auto result = new SHFolder(name);
result->path = path + "/" + name;
subFolders.push_back(result);
return result;
}
}

View File

@ -0,0 +1,52 @@
/******************************************************************************
* \file SHFolder.h
* \author Loh Xiao Qi
* \date 28 October 2022
* \brief
*
* \copyright 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
#include <string>
#include <vector>
#include "Assets/SHAsset.h"
namespace SHADE
{
class SHFolder;
typedef unsigned char FolderCounter;
typedef unsigned char FileCounter;
typedef std::string FolderName;
typedef std::string FileName;
typedef std::string FolderPath;
typedef std::string FilePath;
typedef std::string FileExt;
typedef SHFolder* FolderPointer;
struct SHFile
{
FileName name;
FilePath path;
FileExt ext;
SHAsset const* assetMeta;
};
class SHFolder
{
public:
SHFolder(FolderName name);
FolderName name;
std::vector<FolderPointer> subFolders;
std::vector<SHFile> files;
bool folded;
FolderPointer CreateSubFolderHere(FolderName name);
FolderPath path;
};
}

View File

@ -194,7 +194,7 @@ namespace SHADE
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Total number of ColliderBounds in the Collider component.
/// Total number of ColliderShapes in the Collider component.
/// </summary>
property int CollisionShapeCount
{

View File

@ -28,7 +28,7 @@ public class PhysicsTest : Script
Debug.LogError("Collider is NULL!");
}
var subColider = Collider.ColliderBoundsCount;
var subColider = Collider.CollisionShapeCount;
Debug.Log($"There are {subColider} colliders.");
}
protected override void update()