diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj
index 1aa92ae..0c0deab 100644
--- a/CopiumEngine/CopiumEngine.vcxproj
+++ b/CopiumEngine/CopiumEngine.vcxproj
@@ -166,6 +166,9 @@
+
+
+
@@ -184,6 +187,7 @@
+
@@ -198,14 +202,21 @@
+
+
+
+
+
+
+
@@ -224,6 +235,7 @@
+
@@ -239,14 +251,19 @@
+
+
+
+
+
diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters
index 502c68b..dce9c0c 100644
--- a/CopiumEngine/CopiumEngine.vcxproj.filters
+++ b/CopiumEngine/CopiumEngine.vcxproj.filters
@@ -129,6 +129,27 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
@@ -248,6 +269,30 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
@@ -256,5 +301,7 @@
+
+
\ No newline at end of file
diff --git a/CopiumEngine/assets/fox.meta b/CopiumEngine/assets/fox.meta
new file mode 100644
index 0000000..efe3944
--- /dev/null
+++ b/CopiumEngine/assets/fox.meta
@@ -0,0 +1,3 @@
+[Texture2D]
+filepath=res/textures/texture.png
+uuid=f49a5284-d666-0982-95ca-cf68cc3d4f45
diff --git a/CopiumEngine/assets/fox2.meta b/CopiumEngine/assets/fox2.meta
new file mode 100644
index 0000000..d0215b7
--- /dev/null
+++ b/CopiumEngine/assets/fox2.meta
@@ -0,0 +1,3 @@
+[Texture2D]
+filepath=res/textures/texture2.png
+uuid=0964e525-22c3-4d25-d5c6-a162965f6e8d
diff --git a/CopiumEngine/src/copium/asset/Asset.cpp b/CopiumEngine/src/copium/asset/Asset.cpp
new file mode 100644
index 0000000..67b0d01
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/Asset.cpp
@@ -0,0 +1,41 @@
+#include "copium/asset/Asset.h"
+
+namespace Copium
+{
+ Asset::Asset(AssetType type)
+ {
+ metaData.type = type;
+ }
+
+ Asset::~Asset() = default;
+
+ AssetHandle Asset::GetHandle() const
+ {
+ return metaData.handle;
+ }
+
+ AssetType Asset::GetType() const
+ {
+ return metaData.type;
+ }
+
+ const std::string& Asset::GetName() const
+ {
+ return metaData.name;
+ }
+
+ UUID Asset::GetUUID() const
+ {
+ return metaData.uuid;
+ }
+
+ bool Asset::isRuntime() const
+ {
+ return metaData.isRuntime;
+ }
+
+ Asset::operator AssetHandle() const
+ {
+ return metaData.handle;
+ }
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/asset/Asset.h b/CopiumEngine/src/copium/asset/Asset.h
new file mode 100644
index 0000000..1c0ac7e
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/Asset.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "copium/asset/AssetMeta.h"
+#include "copium/util/MetaFile.h"
+#include "copium/util/UUID.h"
+
+#include
+
+namespace Copium
+{
+
+ class Asset
+ {
+ friend class AssetManager;
+ public:
+ Asset(AssetType type);
+ virtual ~Asset();
+
+ AssetHandle GetHandle() const;
+ AssetType GetType() const;
+ const std::string& GetName() const;
+ UUID GetUUID() const;
+ bool isRuntime() const;
+
+ operator AssetHandle() const;
+
+ private:
+ AssetMeta metaData;
+ };
+}
diff --git a/CopiumEngine/src/copium/asset/AssetFile.cpp b/CopiumEngine/src/copium/asset/AssetFile.cpp
new file mode 100644
index 0000000..ea3200a
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetFile.cpp
@@ -0,0 +1,50 @@
+#include "copium/asset/AssetFile.h"
+
+#include "copium/util/FileSystem.h"
+
+namespace Copium
+{
+ AssetFile::AssetFile(const std::string& path)
+ : path{path}
+ {
+ Load();
+ }
+
+ bool AssetFile::NeedReload() const
+ {
+ return dateModified < FileSystem::DateModified(path);
+ }
+
+ void AssetFile::Load()
+ {
+ const std::vector> strToType{{"Texture2D", AssetType::Texture2D}};
+ MetaFile metaFile{path};
+ for (auto&& [str, type] : strToType)
+ {
+ if (!metaFile.HasMetaClass(str))
+ continue;
+
+ Load(metaFile, str, type);
+ return;
+ }
+ CP_ABORT("Load : Unknown Asset type");
+ }
+
+ const std::string& AssetFile::GetPath() const
+ {
+ return path;
+ }
+
+ UUID AssetFile::GetUUID() const
+ {
+ return uuid;
+ }
+
+ void AssetFile::Load(const MetaFile& metaFile, const std::string& className, AssetType assetType)
+ {
+ const MetaFileClass& metaClass = metaFile.GetMetaClass(className);
+ uuid = UUID{metaClass.GetValue("uuid")};
+ type = assetType;
+ dateModified = FileSystem::DateModified(path);
+ }
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/asset/AssetFile.h b/CopiumEngine/src/copium/asset/AssetFile.h
new file mode 100644
index 0000000..804115a
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetFile.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "copium/asset/AssetMeta.h"
+#include "copium/util/MetaFile.h"
+#include "copium/util/UUID.h"
+
+namespace Copium
+{
+ class AssetFile
+ {
+ private:
+ std::string path;
+ AssetType type;
+ UUID uuid;
+ int64_t dateModified;
+
+ public:
+ AssetFile(const std::string& path);
+
+ bool NeedReload() const;
+ void Load();
+
+ const std::string& GetPath() const;
+ UUID GetUUID() const;
+ private:
+ void Load(const MetaFile& metaFile, const std::string& className, AssetType assetType);
+ };
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/asset/AssetManager.cpp b/CopiumEngine/src/copium/asset/AssetManager.cpp
new file mode 100644
index 0000000..83f2c5f
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetManager.cpp
@@ -0,0 +1,163 @@
+#include "copium/asset/AssetManager.h"
+
+#include "copium/sampler/Texture2D.h"
+#include "copium/util/Common.h"
+#include "copium/util/MetaFile.h"
+
+#include
+#include
+
+namespace Copium
+{
+ std::vector AssetManager::assetDirs;
+ std::map> AssetManager::assets;
+ std::map AssetManager::pathToAssetCache;
+ std::map AssetManager::nameToAssetCache;
+ std::vector AssetManager::cachedAssetFiles;
+ AssetHandle AssetManager::assetHandle = 1;
+ AssetHandle AssetManager::runtimeAssetHandle = (1 << 31) + 1;
+
+ void AssetManager::RegisterAssetDir(std::string assetDir)
+ {
+ if (assetDir.back() == '/')
+ assetDir.pop_back();
+ assetDirs.emplace_back(assetDir);
+ for (std::filesystem::recursive_directory_iterator it(assetDir), end; it != end; ++it)
+ {
+ if (std::filesystem::is_directory(it->path()))
+ continue;
+ std::filesystem::path assetDirPath{assetDir};
+ cachedAssetFiles.emplace_back(assetDir + "/" + std::filesystem::absolute(it->path()).string().substr(std::filesystem::absolute(assetDirPath).string().size()).c_str());
+ }
+ UUID uuid{};
+ CP_INFO(uuid.ToString().c_str());
+ }
+
+ void AssetManager::UnregisterAssetDir(std::string assetDir)
+ {
+ if (assetDir.back() == '/')
+ assetDir.pop_back();
+
+ for (auto it = assetDirs.begin(); it != assetDirs.end(); ++it)
+ {
+ if (*it == assetDir)
+ {
+ assetDirs.erase(it);
+ return;
+ }
+ }
+ }
+
+ Asset& AssetManager::GetAsset(AssetHandle handle)
+ {
+ auto it = assets.find(handle);
+ CP_ASSERT(it != assets.end(), "GetAsset : Asset not loaded");
+ return *it->second.get();
+ }
+
+ Asset& AssetManager::LoadAsset(const std::string& assetPath)
+ {
+ CP_DEBUG("LoadAsset : Loading Asset: %s", assetPath.c_str());
+
+ for (auto& dir : assetDirs)
+ {
+ std::string path = dir + "/" + assetPath;
+ auto it = pathToAssetCache.find(path);
+ if (it != pathToAssetCache.end())
+ return *assets.find(it->second)->second.get();
+
+ std::ifstream file{path};
+ if (!file.good())
+ continue;
+
+ MetaFile metaFile{path};
+ if (metaFile.HasMetaClass("Texture2D"))
+ {
+ return CreateAsset(metaFile, "Texture2D");
+ }
+ CP_ABORT("LoadAsset : Unknown Asset type: %s/%s", dir.c_str(), assetPath.c_str());
+ }
+ CP_ABORT("LoadAsset : Unknown Asset: %s", assetPath.c_str());
+ }
+
+
+ Asset& AssetManager::LoadAsset(const UUID& uuid)
+ {
+ CP_DEBUG("LoadAsset : Loading uuid Asset: %s", uuid.ToString().c_str());
+ for (auto&& assetFile : cachedAssetFiles)
+ {
+ if (assetFile.GetUUID() != uuid)
+ continue;
+
+ if (assetFile.NeedReload())
+ assetFile.Load();
+
+ if (assetFile.GetUUID() != uuid)
+ continue;
+
+ CP_DEBUG("LoadAsset : Loading Asset: %s", assetFile.GetPath().c_str());
+ auto it = pathToAssetCache.find(assetFile.GetPath());
+ if (it != pathToAssetCache.end())
+ return *assets.find(it->second)->second.get();
+
+ MetaFile metaFile{assetFile.GetPath()};
+ if (metaFile.HasMetaClass("Texture2D"))
+ {
+ return CreateAsset(metaFile, "Texture2D");
+ }
+ CP_ABORT("LoadAsset : Unknown Asset type: %s", assetFile.GetPath().c_str());
+ }
+ CP_ABORT("LoadAsset : Asset not found with uuid=%s", uuid.ToString().c_str());
+ // TODO: Reload the assetCache to see if a new file has appeared with that uuid
+ }
+
+ void AssetManager::UnloadAsset(AssetHandle handle)
+ {
+ auto it = assets.find(handle);
+ CP_ASSERT(it != assets.end(), "UnloadAsset : Asset not loaded");
+
+ if (it->second->isRuntime())
+ nameToAssetCache.erase(it->second->GetName());
+ else
+ pathToAssetCache.erase(it->second->GetName());
+ assets.erase(it);
+ }
+
+ void AssetManager::Cleanup()
+ {
+ if (assets.empty())
+ return;
+ CP_WARN("Cleanup : Cleaning up %d loaded assets", assets.size());
+ assets.clear();
+ nameToAssetCache.clear();
+ pathToAssetCache.clear();
+ }
+
+ Asset& AssetManager::RegisterRuntimeAsset(const std::string& name, std::unique_ptr&& asset)
+ {
+ auto it = nameToAssetCache.find(name);
+ CP_ASSERT(it == nameToAssetCache.end(), "RegistedRuntimeAsset : Asset already exists: %s", name);
+
+ AssetHandle handle = runtimeAssetHandle++;
+ Asset* asset2 = assets.emplace(handle, std::move(asset)).first->second.get();
+ asset2->metaData.handle = handle;
+ asset2->metaData.name = name;
+ asset2->metaData.uuid = UUID();
+ asset2->metaData.isRuntime = true;
+ nameToAssetCache.emplace(name, handle);
+ return *asset2;
+ }
+
+ template
+ Asset& AssetManager::CreateAsset(const MetaFile& metaFile, const std::string& metaFileClass)
+ {
+ AssetHandle handle = assetHandle++;
+ pathToAssetCache.emplace(metaFile.GetFilePath(), handle);
+ Asset& asset = *assets.emplace(handle, std::make_unique(metaFile)).first->second.get();
+ asset.metaData.handle = handle;
+ asset.metaData.name = metaFile.GetFilePath();
+ asset.metaData.uuid = UUID{metaFile.GetMetaClass(metaFileClass).GetValue("uuid")};
+ asset.metaData.isRuntime = false;
+ return asset;
+ }
+}
\ No newline at end of file
diff --git a/CopiumEngine/src/copium/asset/AssetManager.h b/CopiumEngine/src/copium/asset/AssetManager.h
new file mode 100644
index 0000000..6c7cdda
--- /dev/null
+++ b/CopiumEngine/src/copium/asset/AssetManager.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "copium/asset/Asset.h"
+#include "copium/asset/AssetFile.h"
+#include "copium/util/Common.h"
+
+#include