Shkyera Engine
Easy to use, game engine for Python
Loading...
Searching...
No Matches
AssetUtils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <filesystem>
4
6#include <Common/Assert.hpp>
7#include <Common/Types.hpp>
11#include <ECS/Registry.hpp>
13
14namespace shkyera::utils::assets {
15
16template <typename AssetType>
17class PathAssetLoader : public AssetLoader<AssetType> {
18 public:
19 PathAssetLoader(std::filesystem::path path_) : path(std::move(path_)) {}
20
21 ~PathAssetLoader() = default;
22
23 AssetType operator()() override { return AssetType(path); }
24
25 std::filesystem::path path;
26};
27
28template <typename AssetType>
29class FactoryAssetLoader : public AssetLoader<AssetType> {
30 public:
31 using Factory = typename AssetType::Factory;
32
33 FactoryAssetLoader(Factory::Type type_) : type(type_) {}
34
36
37 AssetType operator()() override { return Factory::create(type); }
38
39 Factory::Type type;
40};
41
51std::optional<AssetHandle> registerSingle(std::filesystem::path path, Registry* registry);
52
61std::optional<AssetHandle> registerAll(std::filesystem::path path, Registry* registry);
62
70std::vector<AssetHandle> getSubdirectories(AssetHandle directory, Registry const* registry);
71
80template <typename AssetType>
82 if (auto asset = assetComponent.assetPtr.lock()) {
83 return asset;
84 }
85
86 auto asset = std::make_shared<AssetType>((*assetComponent.constructionFunction)());
87 assetComponent.assetPtr = asset;
88 return asset;
89}
90
91template <typename AssetType>
93 if (const auto assetRef = std::get<AssetRef<AssetType>>(handleAndAsset)) {
94 return assetRef;
95 }
96
97 if (const auto assetHandleOpt = std::get<OptionalAssetHandle>(handleAndAsset)) {
99 "{} does not have an associated Asset Component for {}", *assetHandleOpt, typeid(AssetType).name());
101 }
102
103 return nullptr;
104}
105
115template <typename AssetType, typename... Args>
116AssetRef<AssetType> read(const std::filesystem::path& path, Args&&... args) {
117 return std::make_shared<AssetType>(path, std::forward<Args>(args)...);
118}
119
120template <typename AssetType>
121AssetRef<AssetType> read(typename AssetType::Factory::Type type) {
122 auto component = std::make_shared<AssetType>(AssetType::Factory::create(type));
123 return component;
124}
125
136template <typename AssetType>
142
153template <typename AssetType>
154HandleAndAsset<AssetType> add(Registry* registry, std::filesystem::path&& path) {
155 return add<AssetType>(registry, std::make_unique<PathAssetLoader<AssetType>>(path));
156}
157
164template <typename AssetType>
165HandleAndAsset<AssetType> add(Registry* registry, typename AssetType::Factory::Type type) {
166 return add<AssetType>(registry, std::make_unique<FactoryAssetLoader<AssetType>>(type));
167}
168
181template <typename AssetType, typename... Args>
182AssetRef<AssetType> readPermanent(const std::filesystem::path& path, Args&&... args) {
183 namespace fs = std::filesystem;
184 static std::unordered_map<fs::path, AssetRef<AssetType>, GlobalPathHash, GlobalPathEqual> permanentAssets;
185
186 if (!permanentAssets.contains(path)) {
187 const auto assetPtr = std::make_shared<AssetType>(path, args...);
188 permanentAssets[path] = assetPtr;
189 return assetPtr;
190 }
191
192 return permanentAssets.at(path);
193}
194
195template <typename AssetType>
196AssetRef<AssetType> readPermanent(typename AssetType::Factory::Type type) {
197 static std::unordered_map<int, AssetRef<AssetType>> permanentAssets;
198
199 const auto typeInt = static_cast<int>(type);
200 if (!permanentAssets.contains(typeInt)) {
201 const auto assetPtr = std::make_shared<AssetType>(AssetType::Factory::create(type));
202 permanentAssets[typeInt] = assetPtr;
203 return assetPtr;
204 }
205
206 return permanentAssets.at(typeInt);
207}
208
209} // namespace shkyera::utils::assets
#define SHKYERA_ASSERT(predicate,...)
Definition Assert.hpp:7
Definition AssetLoader.hpp:6
Definition Registry.hpp:28
Definition AssetUtils.hpp:29
AssetType operator()() override
Definition AssetUtils.hpp:37
typename AssetType::Factory Factory
Definition AssetUtils.hpp:31
FactoryAssetLoader(Factory::Type type_)
Definition AssetUtils.hpp:33
Factory::Type type
Definition AssetUtils.hpp:39
Definition AssetUtils.hpp:17
std::filesystem::path path
Definition AssetUtils.hpp:25
AssetType operator()() override
Definition AssetUtils.hpp:23
PathAssetLoader(std::filesystem::path path_)
Definition AssetUtils.hpp:19
Definition AssetLoaders.hpp:17
std::optional< AssetHandle > registerAll(std::filesystem::path path, Registry *registry)
Definition AssetUtils.cpp:49
std::optional< AssetHandle > registerSingle(std::filesystem::path path, Registry *registry)
Definition AssetUtils.cpp:22
std::vector< AssetHandle > getSubdirectories(AssetHandle directory, Registry const *registry)
Definition AssetUtils.cpp:67
HandleAndAsset< AssetType > add(Registry *registry, std::unique_ptr< AssetLoader< AssetType > > loader)
Definition AssetUtils.hpp:137
AssetRef< AssetType > read(AssetComponent< AssetType > &assetComponent)
Definition AssetUtils.hpp:81
AssetRef< AssetType > readPermanent(const std::filesystem::path &path, Args &&... args)
Definition AssetUtils.hpp:182
Entity AssetHandle
Definition Asset.hpp:8
Definition Mesh.cpp:16
Definition Clock.hpp:9
Definition Types.hpp:22
Definition Types.hpp:15