diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj
index 178b98f7..0300064c 100644
--- a/SHADE_Engine/SHADE_Engine.vcxproj
+++ b/SHADE_Engine/SHADE_Engine.vcxproj
@@ -102,6 +102,10 @@
+
+
+
+
@@ -183,9 +187,9 @@
-
+
@@ -193,6 +197,9 @@
+
+
+
@@ -253,11 +260,11 @@
-
Create
+
diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters
index c28e339e..7feecdc7 100644
--- a/SHADE_Engine/SHADE_Engine.vcxproj.filters
+++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters
@@ -1,6 +1,9 @@
+
+ {3824E0A7-24C6-0A7E-0D81-1ED2F9C191CE}
+
{DBC7D3B0-C769-FE86-B024-12DB9C6585D7}
@@ -117,6 +120,18 @@
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
Engine\ECS_Base\Components
@@ -364,6 +379,9 @@
Scene
+
+ Scene
+
Scene
@@ -376,22 +394,20 @@
Tools
-
-
-
-
-
-
-
-
-
-
-
Tools
+
+ Assets
+
+
+ Assets
+
+
+ Assets
+
Engine\ECS_Base\Components
@@ -576,6 +592,9 @@
Resource
+
+ Scene
+
Scene
@@ -588,12 +607,5 @@
Tools
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h
new file mode 100644
index 00000000..b84165fb
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetMacros.h
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * \file SHAssetMacros.h
+ * \author Loh Xiao Qi
+ * \brief Macros and typedefs for assets
+ *
+ * \copyright 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
+ ******************************************************************************/
+#ifndef SH_RESOURCE_MACROS_H
+#define SH_RESOURCE_MACROS_H
+
+#include
+#include
+#include
+
+// FMOD Fwd Declare
+namespace FMOD
+{
+ class Sound;
+ class System;
+ class ChannelGroup;
+ class Channel;
+}
+enum FMOD_RESULT : int;
+enum FMOD_SPEAKERMODE : int;
+
+// Typedefs
+typedef uint32_t AssetID;
+typedef std::string AssetName;
+typedef std::filesystem::path AssetPath;
+typedef unsigned char* AssetData;
+typedef std::string AssetMetaVersion;
+typedef std::string AssetExtension;
+typedef unsigned char AssetTypeMeta;
+
+typedef FMOD::Sound* SHSound;
+
+// Asset Meta Version
+#define RESOURCE_META_VER "1.0"
+
+// Asset type enum
+enum class AssetType : AssetTypeMeta
+{
+ AUDIO = 0,
+ SHADER,
+ MATERIAL,
+ IMAGE,
+ TEXTURE,
+ MESH,
+ SCRIPT,
+ SCENE,
+ PREFAB,
+ AUDIO_WAV
+};
+
+// RESOURCE EXTENSIONS
+#define META_EXTENSION ".shmeta"
+#define IMAGE_EXTENSION ".png"
+#define AUDIO_EXTENSION ".ogg"
+#define AUDIO_WAV_EXTENSION ".wav"
+#define SHADER_EXTENSION ".glsl"
+#define SCRIPT_EXTENSION ".cs"
+#define SCENE_EXTENSION ".SHADE"
+#define PREFAB_EXTENSION ".SHPrefab"
+#define MATERIAL_EXTENSION ".SHMat"
+#define TEXTURE_EXTENSION ".dds"
+#define MESH_EXTENSION ".gltf"
+
+std::string const EXTENSIONS[] = {
+ AUDIO_EXTENSION,
+ SHADER_EXTENSION,
+ MATERIAL_EXTENSION,
+ IMAGE_EXTENSION,
+ TEXTURE_EXTENSION,
+ MESH_EXTENSION,
+ SCRIPT_EXTENSION,
+ SCENE_EXTENSION,
+ PREFAB_EXTENSION,
+ AUDIO_WAV_EXTENSION
+};
+
+// Error flags
+#define FILE_NOT_FOUND_ERR "FILE NOT FOUND"
+#define META_NOT_FOUND_ERR "META NOT FOUND"
+#define RESOURCE_NOT_FOUND_ERR "RESOURCE NOT FOUND"
+#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED"
+
+#endif // !SH_RESOURCE_MACROS_H
diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp
new file mode 100644
index 00000000..65acc232
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp
@@ -0,0 +1,1013 @@
+/******************************************************************************
+ * \file SHAssetManager.cpp
+ * \author Loh Xiao Qi
+ * \brief Implementations for SHAssetManager.h
+ *
+ * \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
+#include
+#include "SHAssetManager.h"
+#include "SHAssetMetaHandler.h"
+#include "Filesystem/SHFileSystem.h"
+
+namespace SHADE
+{
+ FMOD::System* SHAssetManager::audioSystem;
+ std::unordered_map* SHAssetManager::audioSoundList;
+
+ std::vector SHAssetManager::metaCollection;
+ std::unordered_map SHAssetManager::pathRegistry;
+ std::unordered_map SHAssetManager::typeRegistry;
+ std::unordered_map SHAssetManager::nameIDRegistry;
+ std::unordered_map SHAssetManager::idNameRegistry;
+ std::unordered_map SHAssetManager::filenameRegistry;
+ std::unordered_map SHAssetManager::filenameReverse;
+
+ /****************************************************************************
+ * \brief Static function to generate resource ID.
+ ****************************************************************************/
+ AssetID SHAssetManager::GenerateAssetID() noexcept
+ {
+ std::default_random_engine randEngine{
+ static_cast(std::chrono::system_clock::now().time_since_epoch().count()) };
+ std::mt19937 idGen{ randEngine() };
+ AssetID result{ idGen() };
+ while (result == 0)
+ {
+ result = idGen();
+ }
+ return result;
+ }
+
+ /****************************************************************************
+ * Generate path relative to exe
+ *
+ * \param p - std::filesystem::path containing file
+ * \return std::filesystem::path - containing full relative path
+ ****************************************************************************/
+ AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept
+ {
+ if (!IsRecognised(path.extension().string().c_str()))
+ {
+ //TODO:ASSERT UNRECOGNISED FILE TYPE
+ return std::filesystem::path();
+ }
+
+ AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
+ std::string folder;
+ switch (type)
+ {
+ case AssetType::AUDIO:
+ folder = AUDIO_FOLDER;
+ break;
+ case AssetType::AUDIO_WAV:
+ folder = AUDIO_FOLDER;
+ break;
+ case AssetType::IMAGE:
+ folder = IMAGES_FOLDER;
+ break;
+ default:
+ //TODO:ASSERT UNSUPPORTED FILE TYPE
+ return std::filesystem::path();
+ }
+
+ return std::filesystem::path(RESOURCE_ROOT + folder + path.filename().string());
+ }
+
+ /****************************************************************************
+ * \brief Deallocates all memory used by image data
+ ****************************************************************************/
+ void SHAssetManager::UnloadImages() noexcept
+ {
+ for (auto& [key, value] : imageData)
+ {
+ stbi_image_free(value.data);
+ }
+
+ imageData.clear();
+ }
+
+ bool SHAssetManager::UpdateSpriteSetIndices(std::shared_ptr& set) noexcept
+ {
+ return SHSpriteSetLibrary::UpdateIndicesAuto(set);
+ }
+
+ bool SHAssetManager::IsRecognised(char const* ext) noexcept
+ {
+ for (auto const& e : EXTENSIONS)
+ {
+ if (strcmp(ext, e.c_str()) == 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /****************************************************************************
+ * \brief Deallocate all memory used by resource data
+ ****************************************************************************/
+ void SHAssetManager::Unload() noexcept
+ {
+ for (auto const& meta : metaCollection)
+ {
+ SHAssetMetaHandler::WriteMetaData(meta, pathRegistry[meta.GetID()].string().append(META_EXTENSION));
+ }
+ UnloadImages();
+ }
+
+ /****************************************************************************
+ * \param Name of resource
+
+ * \brief Gets resource ID
+ ****************************************************************************/
+ AssetID SHAssetManager::GetIDFromName(AssetName const& name) noexcept
+ {
+ if (nameIDRegistry.find(name) == nameIDRegistry.end())
+ {
+ // Error resource does not exist
+ return 0;
+ }
+ else
+ {
+ return nameIDRegistry[name];
+ }
+ }
+
+ std::vector SHAssetManager::GetIDFromNames(std::initializer_list const& files) noexcept
+ {
+ std::vector result;
+ for (auto const& file : files)
+ {
+ result.push_back(GetIDFromName(file));
+ }
+
+ return result;
+ }
+
+ /****************************************************************************
+ * \param file name
+
+ * \brief Returns resource ID from provided file name
+ ****************************************************************************/
+ AssetID SHAssetManager::GetIDFromFilename(std::string const& name) noexcept
+ {
+ if (filenameRegistry.find(name) == filenameRegistry.end())
+ {
+ // Error resource does not exist
+ return 0;
+ }
+ else
+ {
+ return filenameRegistry[name];
+ }
+ }
+
+ /****************************************************************************
+ * \brief Get filename from resource ID.
+ *
+ * \param id - id of asset
+ * \return std::string
+ ****************************************************************************/
+ std::string SHAssetManager::GetFilenameFromID(AssetID id) noexcept
+ {
+ if (filenameReverse.find(id) == filenameReverse.end())
+ {
+ // Error resource does not exist
+ return FILE_NOT_FOUND_ERR;
+ }
+ else
+ {
+ return filenameReverse[id];
+ }
+ }
+
+ /****************************************************************************
+ * \brief Get asset name from resource ID.
+ *
+ * \param id - resource id
+ * \return - std::string
+ ****************************************************************************/
+ AssetName SHAssetManager::GetNameFromID(AssetID id) noexcept
+ {
+ if (idNameRegistry.find(id) == idNameRegistry.end())
+ {
+ // Error
+ return "INVALID";
+ }
+ else
+ {
+ return idNameRegistry[id];
+ }
+ }
+
+ /****************************************************************************
+ * \param list of file names
+
+ * \brief Returns vector of resource IDs
+ ****************************************************************************/
+ std::vector SHAssetManager::GetIDFromFilenames(std::initializer_list const& files) noexcept
+ {
+ std::vector result;
+ for (auto const& file : files)
+ {
+ result.push_back(GetIDFromFilename(file));
+ }
+
+ return result;
+ }
+
+ /****************************************************************************
+ * \brief Get record of all resources currently loaded with name and id.
+ *
+ * \return const& to unordered_map
+ ****************************************************************************/
+ std::unordered_map const& SHAssetManager::GetAllAssets() noexcept
+ {
+ return nameIDRegistry;
+ }
+
+ /****************************************************************************
+ * \brief Get type of asset from ID
+ *
+ * \param resource id of file
+ * \return AssetType enum class value
+ ****************************************************************************/
+ AssetType SHAssetManager::GetTypeFromID(AssetID id) noexcept
+ {
+ return typeRegistry[id];
+ }
+
+ /****************************************************************************
+ * \brief Get registered path of asset.
+ *
+ * \param resource id of file
+ * \return std::filesystem::path
+ ****************************************************************************/
+ AssetPath SHAssetManager::GetPathFromID(AssetID id) noexcept
+ {
+ return pathRegistry[id];
+ }
+
+ /****************************************************************************
+ * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
+ * RESOURCES CREATED BY THE ENGINE.
+ *
+ * \param type of resource
+ * \param name of resource
+ * \return resource id generated for new asset
+ ****************************************************************************/
+ AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
+ {
+ AssetID id{ GenerateAssetID() };
+ SHAssetMeta meta;
+ meta.SetID(id);
+ meta.SetType(type);
+ meta.SetVersion(RESOURCE_META_VER);
+
+ std::string folder;
+ switch (type)
+ {
+ case AssetType::SPRITE_SET:
+ folder = SPRITE_SET_FOLDER;
+ break;
+ default:
+ folder = "";
+ break;
+ }
+ AssetPath path{ RESOURCE_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
+
+ metaCollection.push_back(meta);
+ pathRegistry[id] = path;
+ typeRegistry[id] = type;
+ idNameRegistry[id] = name;
+ nameIDRegistry[name] = id;
+ filenameRegistry[name + SHAssetMetaHandler::GetExtensionFromType(type)] = id;
+ filenameReverse[id] = name + SHAssetMetaHandler::GetExtensionFromType(type);
+
+ SHAssetMetaHandler::WriteMetaData(meta, path.string() + META_EXTENSION);
+
+ return id;
+ }
+
+ /****************************************************************************
+ * \brief Import new resource from outside editor window.
+ *
+ * \param path - c style string to full path
+ * \return resource if generated for new
+ ****************************************************************************/
+ AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept
+ {
+ std::filesystem::path path{ p };
+ for (auto const& pa : pathRegistry)
+ {
+ if (std::strcmp(pa.second.string().c_str(), path.filename().string().c_str()) == 0)
+ {
+ return pa.first;
+ }
+ }
+
+ std::filesystem::path newPath{ GenerateLocalPath(path) };
+ if (newPath.empty())
+ {
+ //TODO: Assert imported file is not recognised
+ std::cout << "Unsupported File Formate: " << path.filename() << "\n";
+ return 0;
+ }
+
+ std::filesystem::copy(path, newPath);
+
+ AssetID id{ RetrieveAsset(newPath.string().c_str()) };
+ if (id != 0)
+ {
+ LoadData(id);
+ }
+
+ return id;
+ }
+
+ /****************************************************************************
+ * \brief Search through resources folder for new unregistered assets.
+ * Takes in no params and returns nothing. Only updates internally.
+ ****************************************************************************/
+ void SHAssetManager::RefreshAllAssets() noexcept
+ {
+ std::vector metaFiles;
+ std::vector resourceFiles;
+
+ SHFileSystem::LoadAllFiles(metaFiles, resourceFiles);
+ //std::vector resourceFilesVerified;
+ std::vector resourceFilesNew;
+
+ for (auto const& resource : resourceFiles)
+ {
+ bool found = false;
+ for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it)
+ {
+ std::string fileExtCheck{ resource.filename().string() };
+ fileExtCheck += META_EXTENSION;
+ if (it->filename().string() == fileExtCheck)
+ {
+ metaFiles.erase(it);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found && IsRecognised(resource.extension().string().c_str()))
+ {
+ resourceFilesNew.push_back(resource);
+ }
+ }
+
+ std::vector newLoad;
+ newLoad.reserve(resourceFilesNew.size());
+
+ //TODO: Handle if meta does not match all resources (if meta exist and asset doesnt, vice versa)
+ for (auto const& file : resourceFilesNew)
+ {
+ newLoad.push_back(RegisterAssetNew(file));
+ }
+
+ //UpdateAllSpriteSets();
+
+ }
+
+ /****************************************************************************
+ * \param Asset ID to image resource
+
+ * \brief Gets image raw data from provided ID.
+ ****************************************************************************/
+ SHImageRawData const* SHAssetManager::GetImageRawData(AssetID const& id) noexcept
+ {
+ if (imageData.find(id) == imageData.end())
+ {
+ // Error resource does not exist
+ return 0;
+ }
+ else
+ {
+ return &imageData[id];
+ }
+ }
+
+ /****************************************************************************
+ * \param resource ID
+
+ * \brief Gets image dimensions of image file
+ ****************************************************************************/
+ SHUMathVec2i SHAssetManager::GetImageDimensions(AssetID const& image) noexcept
+ {
+ SHImageRawData const* const data = GetImageRawData(image);
+ if (data != nullptr)
+ {
+ return SHUMathVec2i{ data->width, data->height };
+ }
+ return SHUMathVec2i();
+ }
+
+ /****************************************************************************
+ * \param vector containing resource IDs
+
+ * \brief Checks if all images referred to by resource IDs have the same
+ * dimensions. To be used when checking images in the same batch
+ ****************************************************************************/
+ bool SHAssetManager::MatchImageFiles(std::vector const& files) noexcept
+ {
+ if (files.size() == 0)
+ {
+ std::cout << "Nothing to compare. Image files list is empty or doesn't contain enough to compare. " << std::endl;
+ return false;
+ }
+
+ if (!imageData.contains(*files.begin()))
+ {
+ std::cout << "Comparison failed. " << *files.begin() << "does not exist in the image library." << std::endl;
+ return false;
+ }
+
+ auto const& firstElement = GetImageRawData(*files.begin());
+ for (auto it = files.begin() + 1; it < files.end(); ++it)
+ {
+ if (imageData.contains(*it))
+ {
+ if (firstElement->CompareProperties(*GetImageRawData(*it)) == false)
+ {
+ std::cout << "Comparison failed. Not all images are the same. " << std::endl;
+ return false;
+ }
+ }
+ else
+ {
+ std::cout << "Comparison failed. " << *files.begin() << "does not exist in the image library." << std::endl;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /****************************************************************************
+ * \brief Create sprite set with single image.
+ *
+ * \param imageName - file name of image
+ * \return result of creation
+ ****************************************************************************/
+ bool SHAssetManager::AddSpriteSet(std::string const& imageName) noexcept
+ {
+ if (spriteSetNameRegistry.find(imageName) == spriteSetNameRegistry.end())
+ {
+ std::shared_ptr ptr = SHSpriteSetLibrary::AddSpriteSet(imageName);
+ if (ptr != nullptr)
+ {
+ AssetID id{ CreateNewAsset(AssetType::SPRITE_SET, imageName) };
+ ptr->SetImageRef(filenameRegistry[imageName]);
+ spriteSetData[id] = ptr;
+ spriteSetNameRegistry[imageName] = id;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /****************************************************************************
+ * \brief Create sprite set with single image (Asset ID).
+ *
+ * \param id - resource id of single image
+ * \return resource id of sprite set created
+ ****************************************************************************/
+ AssetID SHAssetManager::AddSpriteSet(AssetID id) noexcept
+ {
+ AssetName newName{ idNameRegistry[id] };
+ newName += "SpriteSet";
+ if (spriteSetNameRegistry.find(newName) == spriteSetNameRegistry.end())
+ {
+ AssetID ssID{ CreateEmptySpriteSet(newName) };
+ if (ssID)
+ {
+ std::shared_ptr ptr = spriteSetData[ssID];
+ if (ptr != nullptr)
+ {
+ ptr->SetImageRef(id);
+ UpdateSpriteSetIndices(ptr);
+ SHSpriteSetLibrary::WriteSpriteSet(
+ ptr,
+ pathRegistry[ssID]
+ );
+ return ssID;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ /****************************************************************************
+ * \brief Create empty sprite set without any image references.
+ *
+ * \param setName - std::string sprite set name
+ * \return resource ID of sprite set created
+ ****************************************************************************/
+ AssetID SHAssetManager::CreateEmptySpriteSet(std::string setName) noexcept
+ {
+ if (spriteSetNameRegistry.find(setName) == spriteSetNameRegistry.end())
+ {
+ std::shared_ptr ptr = std::make_shared(setName);
+ if (ptr != nullptr)
+ {
+ AssetID id{ CreateNewAsset(AssetType::SPRITE_SET, setName) };
+ spriteSetData[id] = ptr;
+ spriteSetNameRegistry[setName] = id;
+ return id;
+ }
+ }
+ return 0;
+ }
+
+ /****************************************************************************
+ * \brief Get ID of sprite set by name.
+ *
+ * \param name - name of sprite set std::string
+ * \return resource iD
+ ****************************************************************************/
+ AssetID SHAssetManager::GetSpriteSet(std::string name) noexcept
+ {
+ if (spriteSetNameRegistry.find(name) == spriteSetNameRegistry.end())
+ {
+ return 0;
+ }
+
+ return spriteSetNameRegistry[name];
+ }
+
+ /****************************************************************************
+ * \brief Get name of sprite set from resource ID.
+ *
+ * \param id - resource id
+ * \return std::string sprite set name
+ ****************************************************************************/
+ std::string SHAssetManager::GetSpriteSetName(AssetID id) noexcept
+ {
+ for (auto const& entry : spriteSetNameRegistry)
+ {
+ if (entry.second == id)
+ {
+ return entry.first;
+ }
+ }
+
+ return std::string("NO SUCH SPRITE SET");
+ }
+
+ /****************************************************************************
+ * \brief Get data of sprite set with sprite set name.
+ *
+ * \param name - std::string sprite set name
+ * \return pointer to sprite set
+ ****************************************************************************/
+ std::shared_ptr SHAssetManager::GetSpriteSetData(std::string name) noexcept
+ {
+ if (spriteSetNameRegistry.find(name) == spriteSetNameRegistry.end())
+ {
+ return nullptr;
+ }
+ return spriteSetData[spriteSetNameRegistry[name]];
+ }
+
+ /****************************************************************************
+ * \brief Get data of sprite set with sprite set resource id.
+ *
+ * \param id - sprite set resource id
+ * \return pointer to sprite set
+ ****************************************************************************/
+ std::shared_ptr SHAssetManager::GetSpriteSetData(AssetID id) noexcept
+ {
+ return spriteSetData[id];
+ }
+
+ /****************************************************************************
+ * \brief Add event to frame in sprite set.
+ *
+ * \param spriteSet - sprite set resource ID
+ * \param evt - pointer to method in script class
+ * \param soh - script object handle to script instance object
+ * \param frame - target frame in sprite set
+ ****************************************************************************/
+ void SHAssetManager::AddSpriteEvent(AssetID spriteSet, MonoMethod* evt, uint32_t soh, size_t frame) noexcept
+ {
+ SHSpriteSet& set = *spriteSetData[spriteSet];
+ set.ModifyFrameEvent(static_cast(frame), evt, soh);
+ }
+
+ /****************************************************************************
+ * \brief Remove event from frame in sprite set.
+ *
+ * \param spriteSet - sprite set resource iD
+ * \param frame - target frame
+ ****************************************************************************/
+ void SHAssetManager::RemoveSpriteEvent(AssetID spriteSet, size_t frame) noexcept
+ {
+ SHSpriteSet& set = *spriteSetData[spriteSet];
+ set.ModifyFrameEvent(static_cast(frame), nullptr, 0);
+ }
+
+ /****************************************************************************
+ * \brief Write sprite set to memory in system.
+ *
+ * \param id - sprite set resource id
+ ****************************************************************************/
+ void SHAssetManager::SaveSpriteSet(AssetID id) noexcept
+ {
+ SHAssetMeta meta;
+ for (auto const& met : metaCollection)
+ {
+ if (met.GetID() == id)
+ {
+ meta = met;
+ break;
+ }
+ }
+ SHSpriteSetLibrary::WriteSpriteSet(
+ spriteSetData[id],
+ pathRegistry[id]
+ );
+ }
+
+ /****************************************************************************
+ * \brief Update all texture layer indices in sprite set.
+ ****************************************************************************/
+ void SHAssetManager::UpdateAllSpriteSets() noexcept
+ {
+ for (auto& data : spriteSetData)
+ {
+ SHSpriteSetLibrary::UpdateIndicesAuto(data.second);
+ }
+ }
+
+ std::shared_ptr SHAssetManager::GetAtlas(AssetID id) noexcept
+ {
+ auto const it = spriteSetData.find(id);
+ if (it == spriteSetData.end())
+ {
+ return nullptr;
+ }
+
+ return it->second->GetAtlasData();
+ }
+
+ bool SHAssetManager::SliceSpriteFixed(AssetID id, uint32_t cols, uint32_t rows) noexcept
+ {
+ std::shared_ptr atlas = nullptr;
+
+ auto const it = spriteSetData.find(id);
+ if (it == spriteSetData.end())
+ {
+ // TODO error log no sprite set found for data
+ return false;
+ }
+ else
+ {
+ atlas = std::make_shared(SHAtlasSlicer::FixedSlice(idNameRegistry[id], imageData[id], cols, rows));
+ }
+
+ std::vector slices;
+ slices.reserve(atlas->slices.size());
+ for (auto const& slice : atlas->slices)
+ {
+ AssetID newID{ GenerateAssetID() };
+ typeRegistry[newID] = AssetType::IMAGE;
+ idNameRegistry[newID] = slice.name;
+ nameIDRegistry[slice.name] = newID;
+ spriteSetNameRegistry[slice.name] = newID;
+
+ slices.emplace_back(newID);
+ }
+
+ auto& spriteSet = spriteSetData[id];
+ spriteSet->SetAtlas(true);
+ spriteSet->SetIsAnimation(true);
+ spriteSet->SetAtlasData(atlas);
+ SHSpriteSetLibrary::UpdateIndicesAuto(spriteSet);
+
+ SHSpriteSetLibrary::WriteSpriteSet(
+ spriteSet,
+ pathRegistry[id]
+ );
+
+ return true;
+ }
+
+ bool SHAssetManager::SliceSpriteAuto(AssetID id) noexcept
+ {
+ std::shared_ptr atlas = nullptr;
+ auto const it = spriteSetData.find(id);
+ if (it == spriteSetData.end())
+ {
+ // TODO error log sprite set does not exist
+ return false;
+ }
+ else
+ {
+ atlas = std::make_shared(SHAtlasSlicer::AutoSlice(idNameRegistry[id], imageData[id]));
+ }
+
+ auto& spriteSet = spriteSetData[id];
+ spriteSet->SetAtlas(true);
+ spriteSet->SetIsAnimation(false);
+ std::vector slices;
+ slices.reserve(atlas->slices.size());
+ for (auto const& slice : atlas->slices)
+ {
+ AssetID newID{ GenerateAssetID() };
+
+ std::shared_ptr newSpriteSet = std::make_shared(slice.name);
+ newSpriteSet->SetImageRef(id);
+ SHSpriteSetLibrary::UpdateIndicesAuto(newSpriteSet);
+ spriteSetData[newID] = newSpriteSet;
+ typeRegistry[newID] = AssetType::IMAGE;
+ idNameRegistry[newID] = slice.name;
+ nameIDRegistry[slice.name] = newID;
+ spriteSetNameRegistry[slice.name] = newID;
+
+ slices.emplace_back(newID);
+ }
+ spriteSet->SetAtlasData(atlas);
+ spriteSet->SetNonFixedSlicesID(slices);
+
+ return true;
+ }
+
+ /****************************************************************************
+ * \param Pointer to FMOD system
+ * \param reference to vector containing class holding sound data
+
+ * \brief Loads all audio resource data into memory and fmod system
+ ****************************************************************************/
+ void SHAssetManager::LoadAllAudio(FMOD::System* system, std::unordered_map& soundList)
+ {
+ audioSystem = system;
+ audioSoundList = &soundList;
+
+ for (auto const& meta : metaCollection)
+ {
+ if (meta.GetType() == AssetType::AUDIO || meta.GetType() == AssetType::AUDIO_WAV)
+ {
+ char name[256], newName[256];
+ SHSound sound;
+ system->createSound(pathRegistry[meta.GetID()].string().c_str(), FMOD_LOOP_NORMAL | FMOD_3D, nullptr, &sound);
+
+ sound->getName(newName, 256);
+ std::vector::size_type i = 0;
+ for (auto& snd : soundList)
+ {
+ snd.second->getName(name, 256);
+ if (strcmp(name, newName) == 0) // sound already exists in soundList
+ {
+ sound->release();
+ }
+ ++i;
+ }
+ soundList.emplace(meta.GetID(),sound);
+ }
+ }
+ }
+
+ /****************************************************************************
+ * \param Path for meta data file
+ * \param Path for resource file
+
+ * \brief Links meta data to resource in registries. Meta data should
+ * already exist
+ ****************************************************************************/
+ void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept
+ {
+ SHAssetMeta meta = SHAssetMetaHandler::RetrieveMetaData(metaPath);
+
+ metaCollection.push_back(meta);
+ pathRegistry.emplace(meta.GetID(), path);
+ typeRegistry.emplace(meta.GetID(), meta.GetType());
+ nameIDRegistry.emplace(GetNameFromPath(path), meta.GetID());
+ idNameRegistry.emplace(meta.GetID(), GetNameFromPath(path));
+ filenameRegistry.emplace(path.filename().string(), meta.GetID());
+ filenameReverse.emplace(meta.GetID(), path.filename().string());
+ }
+
+ /****************************************************************************
+ * \param Path for resource file
+
+ * \brief Creates new meta data for new resource.
+ ****************************************************************************/
+ SHAssetMeta SHAssetManager::RegisterAssetNew(AssetPath const& resource) noexcept
+ {
+ SHAssetMeta meta;
+ meta.SetID(GenerateAssetID());
+ meta.SetType(SHAssetMetaHandler::GetTypeFromExtension(resource.extension().string()));
+ meta.SetVersion(RESOURCE_META_VER);
+
+ metaCollection.push_back(meta);
+ pathRegistry.emplace(meta.GetID(), resource);
+ typeRegistry.emplace(meta.GetID(), meta.GetType());
+ nameIDRegistry.emplace(GetNameFromPath(resource), meta.GetID());
+ idNameRegistry.emplace(meta.GetID(), GetNameFromPath(resource));
+ filenameRegistry.emplace(resource.filename().string(), meta.GetID());
+ filenameReverse.emplace(meta.GetID(), resource.filename().string());
+
+ //LoadData(meta.GetID());
+
+ SHAssetMetaHandler::WriteMetaData(meta, resource.string() + META_EXTENSION);
+ return metaCollection.back();
+ }
+
+ /****************************************************************************
+ * \brief Load all resources that are in the folder
+ ****************************************************************************/
+ void SHAssetManager::Load() noexcept
+ {
+ RetrieveAssets();
+ LoadAllData();
+
+ //SHShaderLibrary::Load();
+ SHShaderLibrary::Load();
+
+ // Load all the default meshes
+ SHMeshLibrary::Load();
+
+ // Initialize all array textures
+ SHTexture2DArrayContainer::Init();
+
+ UpdateAllSpriteSets();
+ }
+
+ /****************************************************************************
+ * \brief Load resource data into memory
+ ****************************************************************************/
+ void SHAssetManager::LoadAllData() noexcept
+ {
+ for (auto const& meta : metaCollection)
+ {
+ if (meta.GetType() == AssetType::IMAGE)
+ {
+ SHImageRawData data;
+ std::string string{ pathRegistry[meta.GetID()].string() };
+ SHImageLibrary::LoadImageFromFile(string, data);
+ imageData.emplace(meta.GetID(), data);
+ }
+ else if (meta.GetType() == AssetType::SPRITE_SET)
+ {
+ std::shared_ptr data = SHSpriteSetLibrary::LoadSpriteSet(pathRegistry[meta.GetID()]);
+ UpdateSpriteSetIndices(data);
+ spriteSetNameRegistry[data->GetSpriteSetName()] = meta.GetID();
+ spriteSetData.emplace(meta.GetID(), data);
+ }
+ else if (meta.GetType() == AssetType::WAYPOINTS_C)
+ {
+ std::shared_ptr data = SHWaypointLibrary::LoadWaypointCollection(pathRegistry[meta.GetID()]);
+ waypointData.emplace(meta.GetID(), data);
+ }
+ }
+ }
+
+ void SHAssetManager::LoadData(AssetID id) noexcept
+ {
+ AssetType type{ typeRegistry[id] };
+ if (type == AssetType::IMAGE)
+ {
+ SHImageRawData data;
+ std::string string{ pathRegistry[id].string() };
+ SHImageLibrary::LoadImageFromFile(string, data);
+ imageData.emplace(id, data);
+ SHTexture2DArrayContainer::AddImageToTexture(imageData[id], idNameRegistry[id]);
+ }
+ else if (type == AssetType::AUDIO || type == AssetType::AUDIO_WAV)
+ {
+ char name[256], newName[256];
+ SHSound sound;
+ audioSystem->createSound(pathRegistry[id].string().c_str(), FMOD_LOOP_NORMAL | FMOD_3D, nullptr, &sound);
+
+ sound->getName(newName, 256);
+ std::vector::size_type i = 0;
+ for (auto& snd : *audioSoundList)
+ {
+ snd.second->getName(name, 256);
+ if (strcmp(name, newName) == 0) // sound already exists in soundList
+ {
+ sound->release();
+ }
+ ++i;
+ }
+ audioSoundList->emplace(id,sound);
+ }
+ else if (type == AssetType::SPRITE_SET)
+ {
+ std::shared_ptr data = SHSpriteSetLibrary::LoadSpriteSet(pathRegistry[id]);
+ UpdateSpriteSetIndices(data);
+ spriteSetNameRegistry[data->GetSpriteSetName()] = id;
+ spriteSetData.emplace(id, data);
+ }
+ }
+
+ /****************************************************************************
+ * \brief Retrieve all resource files and meta files from filesystem
+ ****************************************************************************/
+ void SHAssetManager::RetrieveAssets() noexcept
+ {
+ std::vector metaFiles;
+ std::vector resourceFiles;
+
+ SHFileSystem::LoadAllFiles(metaFiles, resourceFiles);
+
+ for (auto const& meta : metaFiles)
+ {
+ for (std::vector::const_iterator it{ resourceFiles.cbegin() };
+ it != resourceFiles.cend();
+ ++it)
+ {
+ // Asset exists for meta file
+ std::string fileExtCheck{ it->filename().string() };
+ fileExtCheck += META_EXTENSION;
+ if (meta.filename().string() == fileExtCheck)
+ {
+ RegisterAsset(meta, *it);
+ resourceFiles.erase(it);
+ break;
+ }
+ }
+ }
+
+ //TODO: Handle if meta does not match all resources (if meta exist and asset doesnt, vice versa)
+ for (auto const& file : resourceFiles)
+ {
+ if (IsRecognised(file.extension().string().c_str()))
+ {
+ SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file), file.string() + META_EXTENSION);
+ }
+ else
+ {
+ std::cout << "Unsupported File Format: " << file.filename() << "\n";
+ }
+ }
+ }
+
+ AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
+ {
+ std::filesystem::path p{ path };
+ if (IsRecognised(p.extension().string().c_str()))
+ {
+ SHAssetMeta const& meta{ RegisterAssetNew(p) };
+ SHAssetMetaHandler::WriteMetaData(meta, p.string() + META_EXTENSION);
+ return meta.GetID();
+ }
+ else
+ {
+ std::cout << "Unsupported File Format: " << p.filename() << "\n";
+ }
+
+ // Assert that file imported is not recognised
+ return 0;
+ }
+
+ /****************************************************************************
+ * \param Full path of file
+
+ * \brief Extracts file name from path. Formats file name into readable
+ * with spaces and capitalises first letter of every word
+ ****************************************************************************/
+ AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept
+ {
+ std::string name{ filepath.filename().string() };
+ name = name.substr(0, name.find_last_of('.'));
+
+ //if (name[0] <= 122 && name[0] >= 97)
+ //{
+ // name[0] -= 32;
+ //}
+
+ //for (size_t i{ 1 }; i < name.length(); ++i)
+ //{
+ // // Replace all underscores with spaces
+ // if (name[i] == '_')
+ // {
+ // name[i] = ' ';
+ // continue;
+ // }
+
+ // if (name[i + 1] <= 'Z' && name[i + 1] >= 'A'
+ // && name[i] <= 'z' && name[i] >= 'a')
+ // {
+ // name.insert(i + 1, 1, ' ');
+ // continue;
+ // }
+
+ // if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a')
+ // {
+ // name[i] -= 32;
+ // }
+ //}
+
+ return name;
+ }
+}
diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h
new file mode 100644
index 00000000..16375b4b
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetManager.h
@@ -0,0 +1,199 @@
+/******************************************************************************
+ * \file SHAssetManager.h
+ * \author Loh Xiao Qi
+ * \brief Interface for resource manager, to be used by engine side
+ * operations.
+ *
+ * \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.
+******************************************************************************/
+#ifndef SH_RESOURCE_MANAGER_H
+#define SH_RESOURCE_MANAGER_H
+
+#include
+#include
+#include
+#include "SHAssetMeta.h"
+
+#include
+
+struct _MonoMethod;
+
+namespace SHADE
+{
+ class SHAssetManager
+ {
+ public:
+ /****************************************************************************
+ * \brief Static function to generate resource ID.
+ ****************************************************************************/
+ static AssetID GenerateAssetID() noexcept;
+
+ /****************************************************************************
+ * Generate path relative to exe
+ *
+ * \param p - std::filesystem::path containing file
+ * \return std::filesystem::path - containing full relative path
+ ****************************************************************************/
+ static AssetPath GenerateLocalPath(AssetPath p) noexcept;
+
+ /****************************************************************************
+ * \brief Deallocate all memory used by resource data
+ ****************************************************************************/
+ static void Unload() noexcept;
+
+ /****************************************************************************
+ * \brief Load all resources that are in the folder
+ ****************************************************************************/
+ static void Load() noexcept;
+
+ // General------------------------------------------------------------------/
+ /****************************************************************************
+ * \param Name of resource
+
+ * \brief Gets resource ID
+ ****************************************************************************/
+ static AssetID GetIDFromName(AssetName const&) noexcept;
+
+ /****************************************************************************
+ * \param Name of resource
+
+ * \brief Gets resource ID
+ ****************************************************************************/
+ static std::vector GetIDFromNames(std::initializer_list const&) noexcept;
+
+ /****************************************************************************
+ * \brief Get asset name from resource ID.
+ *
+ * \param id - resource id
+ * \return - std::string
+ ****************************************************************************/
+ static AssetName GetNameFromID(AssetID) noexcept;
+
+ /****************************************************************************
+ * \param file name
+
+ * \brief Returns resource ID from provided file name
+ ****************************************************************************/
+ static AssetID GetIDFromFilename(std::string const&) noexcept;
+
+ /****************************************************************************
+ * \brief Get filename from resource ID.
+ *
+ * \param id - id of asset
+ * \return std::string
+ ****************************************************************************/
+ static std::string GetFilenameFromID(AssetID id) noexcept;
+
+ /****************************************************************************
+ * \param list of file names
+
+ * \brief Returns vector of resource IDs
+ ****************************************************************************/
+ static std::vector GetIDFromFilenames(std::initializer_list const&) noexcept;
+
+ /****************************************************************************
+ * \brief Get record of all resources currently loaded with name and id.
+ *
+ * \return const& to unordered_map
+ ****************************************************************************/
+ static std::unordered_map const& GetAllAssets() noexcept;
+
+ /****************************************************************************
+ * \brief Get type of asset from ID
+ *
+ * \param resource id of file
+ * \return AssetType enum class value
+ ****************************************************************************/
+ static AssetType GetTypeFromID(AssetID) noexcept;
+
+ /****************************************************************************
+ * \brief Get registered path of asset.
+ *
+ * \param resource id of file
+ * \return std::filesystem::path
+ ****************************************************************************/
+ static AssetPath GetPathFromID(AssetID) noexcept;
+
+ /****************************************************************************
+ * \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
+ * RESOURCES CREATED BY THE ENGINE.
+ *
+ * \param type of resource
+ * \param name of resource
+ * \return resource id generated for new asset
+ ****************************************************************************/
+ static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
+
+ /****************************************************************************
+ * \brief Import new resource from outside editor window.
+ *
+ * \param path - c style string to full path
+ * \return resource if generated for new
+ ****************************************************************************/
+ static AssetID ImportNewAsset(char const* path) noexcept;
+
+ /****************************************************************************
+ * \brief Search through resources folder for new unregistered assets.
+ * Takes in no params and returns nothing. Only updates internally.
+ ****************************************************************************/
+ static void RefreshAllAssets() noexcept;
+ // -------------------------------------------------------------------------/
+
+ private:
+ /****************************************************************************
+ * \brief Load resource data into memory
+ ****************************************************************************/
+ static void LoadAllData() noexcept;
+
+ static void LoadData(AssetID id) noexcept;
+
+ /****************************************************************************
+ * \brief Retrieve all resource files and meta files from filesystem
+ ****************************************************************************/
+ static void RetrieveAssets() noexcept;
+
+ static AssetID RetrieveAsset(char const* path) noexcept;
+
+ /****************************************************************************
+ * \param Full path of file
+
+ * \brief Extracts file name from path. Formats file name into readable
+ * with spaces and capitalises first letter of every word
+ ****************************************************************************/
+ static AssetName GetNameFromPath(AssetPath) noexcept;
+
+ /****************************************************************************
+ * \param Path for meta data file
+ * \param Path for resource file
+
+ * \brief Links meta data to resource in registries. Meta data should
+ * already exist
+ ****************************************************************************/
+ static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept;
+
+ /****************************************************************************
+ * \param Path for resource file
+
+ * \brief Creates new meta data for new resource.
+ ****************************************************************************/
+ static SHAssetMeta RegisterAssetNew(AssetPath const&) noexcept;
+
+ static bool IsRecognised(char const*) noexcept;
+
+ static FMOD::System* audioSystem;
+ static std::unordered_map* audioSoundList;
+
+ // For all resources
+ static std::vector metaCollection;
+ static std::unordered_map pathRegistry;
+ static std::unordered_map typeRegistry;
+ static std::unordered_map idNameRegistry;
+ static std::unordered_map nameIDRegistry;
+ static std::unordered_map filenameRegistry;
+ static std::unordered_map filenameReverse;
+ };
+}
+
+#endif // !SH_RESOURCE_MANAGER_H
diff --git a/SHADE_Engine/src/Assets/SHAssetMeta.cpp b/SHADE_Engine/src/Assets/SHAssetMeta.cpp
new file mode 100644
index 00000000..e8608159
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetMeta.cpp
@@ -0,0 +1,102 @@
+/******************************************************************************
+ * \file SHResourceMeta.cpp
+ * \author Loh Xiao Qi
+ * \brief Implementation for SHResourceMeta.h
+ *
+ * \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 "SHResourceMeta.h"
+
+namespace SHADE
+{
+ /****************************************************************************
+ * \brief Default constructor
+ ****************************************************************************/
+ SHResourceMeta::SHResourceMeta() noexcept : id{ 0 }, type{ResourceType::INVALID}
+ {
+
+ }
+
+ /****************************************************************************
+ * \param copy
+
+ * \brief copy constructor
+ ****************************************************************************/
+ SHResourceMeta::SHResourceMeta(SHResourceMeta const& ref) noexcept
+ {
+ ver = ref.ver;
+ id = ref.id;
+ type = ref.type;
+ }
+
+ /****************************************************************************
+ * \param reference
+
+ * \brief copy assignment operator overload
+ ****************************************************************************/
+ SHResourceMeta& SHResourceMeta::operator=(SHResourceMeta const& ref) noexcept
+ {
+ ver = ref.ver;
+ id = ref.id;
+ type = ref.type;
+
+ return *this;
+ }
+
+ /****************************************************************************
+ * \param std::string representation for meta resource file version
+
+ * \brief Set meta version for data file
+ ****************************************************************************/
+ void SHResourceMeta::SetVersion(ResourceMetaVersion vers) noexcept
+ {
+ ver = vers;
+ }
+
+ /****************************************************************************
+ * \param ID of resource
+
+ * \brief Set ID
+ ****************************************************************************/
+ void SHResourceMeta::SetID(ResourceID idin) noexcept
+ {
+ this->id = idin;
+ }
+
+ /****************************************************************************
+ * \param Enum class value
+
+ * \brief Set Resource Type
+ ****************************************************************************/
+ void SHResourceMeta::SetType(ResourceType rType) noexcept
+ {
+ this->type = rType;
+ }
+
+ /****************************************************************************
+ * \brief Get version
+ ****************************************************************************/
+ ResourceMetaVersion SHResourceMeta::GetVersion() const noexcept
+ {
+ return ver;
+ }
+
+ /****************************************************************************
+ * \brief Get ID
+ ****************************************************************************/
+ ResourceID SHResourceMeta::GetID() const noexcept
+ {
+ return id;
+ }
+
+ /****************************************************************************
+ * \brief Get resource type
+ ****************************************************************************/
+ ResourceType SHResourceMeta::GetType() const noexcept
+ {
+ return type;
+ }
+}
diff --git a/SHADE_Engine/src/Assets/SHAssetMeta.h b/SHADE_Engine/src/Assets/SHAssetMeta.h
new file mode 100644
index 00000000..9f2e6b5c
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetMeta.h
@@ -0,0 +1,82 @@
+/******************************************************************************
+ * \file SHAssetMeta.h
+ * \author Loh Xiao Qi
+ * \brief Class to hold meta data values for resources
+ *
+ * \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
+ ******************************************************************************/
+#ifndef SH_RESOURCE_META_H
+#define SH_RESOURCE_META_H
+
+#include "SHAssetMacros.h"
+
+namespace SHADE
+{
+ class SHAssetMeta
+ {
+ public:
+ /****************************************************************************
+ * \brief Default constructor
+ ****************************************************************************/
+ SHAssetMeta() noexcept;
+
+ /****************************************************************************
+ * \param copy
+
+ * \brief copy constructor
+ ****************************************************************************/
+ SHAssetMeta(SHAssetMeta const&) noexcept;
+
+ /****************************************************************************
+ * \param reference
+
+ * \brief copy assignment operator overload
+ ****************************************************************************/
+ SHAssetMeta& operator=(SHAssetMeta const&) noexcept;
+
+ /****************************************************************************
+ * \param std::string representation for meta resource file version
+
+ * \brief Set meta version for data file
+ ****************************************************************************/
+ void SetVersion(AssetMetaVersion) noexcept;
+
+ /****************************************************************************
+ * \param ID of resource
+
+ * \brief Set ID
+ ****************************************************************************/
+ void SetID(AssetID) noexcept;
+
+ /****************************************************************************
+ * \param Enum class value
+
+ * \brief Set Asset Type
+ ****************************************************************************/
+ void SetType(AssetType) noexcept;
+
+ /****************************************************************************
+ * \brief Get version
+ ****************************************************************************/
+ AssetMetaVersion GetVersion() const noexcept;
+
+ /****************************************************************************
+ * \brief Get ID
+ ****************************************************************************/
+ AssetID GetID() const noexcept;
+
+ /****************************************************************************
+ * \brief Get resouce type
+ ****************************************************************************/
+ AssetType GetType() const noexcept;
+
+ private:
+ AssetMetaVersion ver;
+ AssetID id;
+ AssetType type;
+ };
+}
+
+#endif // !SH_RESOURCE_META_H
diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp
new file mode 100644
index 00000000..9493f56c
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * \file SHAssetMetaHandler.cpp
+ * \author Loh Xiao Qi
+ * \brief Implementations for SHAssetMetaHandler.h
+ *
+ * \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 "SHAssetMetaHandler.h"
+#include
+#include
+
+namespace SHADE
+{
+ /****************************************************************************
+ * \param reference to ifstream file to read line from
+ * \param reference to string to store line into
+
+ * \brief Helper function to retrieve field value from meta data file
+ * for processing
+ ****************************************************************************/
+ void GetFieldValue(std::ifstream& file, std::string& line) noexcept
+ {
+ line = "";
+ std::getline(file, line);
+ line = line.substr(line.find_last_of(':') + 2, line.length());
+ }
+
+ /****************************************************************************
+ * \param String containing extension of resource file
+
+ * \brief Get correct resource type from file extension of resource.
+ ****************************************************************************/
+ AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
+ {
+ for (int i{0}; i < EXTENSIONS->size())
+ }
+
+ /****************************************************************************
+ * \param String containing extension of resource file
+
+ * \brief Get correct resource type from file extension of resource.
+ ****************************************************************************/
+ AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept
+ {
+ switch (type)
+ {
+ case AssetType::AUDIO:
+ return AUDIO_EXTENSION;
+ case AssetType::AUDIO_WAV:
+ return AUDIO_WAV_EXTENSION;
+ case AssetType::IMAGE:
+ return IMAGE_EXTENSION;
+ case AssetType::SPRITE_SET:
+ return SPRITE_SET_EXTENSION;
+ case AssetType::SCRIPT:
+ return SCRIPT_EXTENSION;
+ case AssetType::WAYPOINTS_C:
+ return WAYPOINT_EXTENSION;
+ case AssetType::PREFAB:
+ return PREFAB_EXTENSION;
+ default:
+ break;
+ }
+
+ return EXT_DOES_NOT_EXIST;
+ }
+
+ /****************************************************************************
+ * \param Create class containing meta data from meta file
+
+ * \brief path to meta data file
+ ****************************************************************************/
+ SHAssetMeta SHAssetMetaHandler::RetrieveMetaData(AssetPath const& path) noexcept
+ {
+ std::ifstream metaFile{ path.string(), std::ios_base::in };
+ if (!metaFile.is_open())
+ {
+ // Error unable to open
+ }
+
+ std::string line;
+ SHAssetMeta meta;
+
+ // Get file version
+ GetFieldValue(metaFile, line);
+ meta.SetVersion(line);
+
+ // Get resource id
+ GetFieldValue(metaFile, line);
+ std::stringstream idStream{ line };
+ AssetID id;
+ idStream >> id;
+ meta.SetID(id);
+
+ // Get resource type
+ GetFieldValue(metaFile, line);
+ std::stringstream typeStream{ line };
+ AssetTypeMeta type;
+ typeStream >> type;
+ meta.SetType(SHAssetMetaHandler::GetTypeFromString(type));
+
+ metaFile.close();
+
+ return meta;
+ }
+
+ /****************************************************************************
+ * \param Asset meta data to be written into
+ * \param Path to be written into
+
+ * \brief Writes meta data into text file
+ ****************************************************************************/
+ void SHAssetMetaHandler::WriteMetaData(SHAssetMeta const& meta, AssetPath const& path) noexcept
+ {
+ std::ofstream metaFile{ path, std::ios_base::out };
+
+ if (!metaFile.is_open())
+ {
+ // Log error
+ }
+
+ metaFile << "Meta Version: " << meta.GetVersion() << "\n";
+ metaFile << "ID: " << meta.GetID() << "\n";
+ metaFile << "Type: " << GetStringFromType(meta.GetType()) << std::endl;
+ metaFile.close();
+ }
+
+}
diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.h b/SHADE_Engine/src/Assets/SHAssetMetaHandler.h
new file mode 100644
index 00000000..69095600
--- /dev/null
+++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * \file SHAssetMetaHandler.h
+ * \author Loh Xiao Qi
+ * \brief Handler classes for meta data for all resources
+ *
+ * \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
+ ******************************************************************************/
+#ifndef SH_RESOURCE_META_HANDLER_H
+#define SH_RESOURCE_META_HANDLER_H
+
+#include "SHAssetMacros.h"
+#include "SHAssetMeta.h"
+
+namespace SHADE
+{
+ struct SHAssetMetaHandler
+ {
+ /****************************************************************************
+ * \param String containing extension of resource file
+
+ * \brief Get correct resource type from file extension of resource.
+ ****************************************************************************/
+ static AssetType GetTypeFromExtension(AssetExtension) noexcept;
+
+ /****************************************************************************
+ * \param String containing extension of resource file
+
+ * \brief Get correct resource type from file extension of resource.
+ ****************************************************************************/
+ static AssetExtension GetExtensionFromType(AssetType) noexcept;
+
+ /****************************************************************************
+ * \param Create class containing meta data from meta file
+
+ * \brief path to meta data file
+ ****************************************************************************/
+ static SHAssetMeta RetrieveMetaData(AssetPath const&) noexcept;
+
+ /****************************************************************************
+ * \param Asset meta data to be written into
+ * \param Path to be written into
+
+ * \brief Writes meta data into text file
+ ****************************************************************************/
+ static void WriteMetaData(SHAssetMeta const&, AssetPath const&) noexcept;
+ };
+}
+
+#endif // !SH_RESOURCE_META_HANDLER_H