1#include "AssetManager.h"
5#include "Services/Variables.h"
6#include "Services/TaskManager.h"
7#include "Services/Services.h"
8#include "Services/Features.h"
10#include "Generators/TextureGenerator.h"
12#include "DataFetcherManager.h"
13#include "ModelManager.h"
14#include "MaterialManager.h"
15#include "TextureManager.h"
16#include "ResourceStore.h"
18#include "Foundation/Logging/Logger.h"
19#include "Foundation/Platform/FileContents.h"
20#include "Foundation/Platform/IO.h"
25 const std::string zstdExtension =
".zst";
33void Cogs::Core::AssetManager::initialize()
35 defaultResource = create();
36 defaultResource->setName(
"Global");
37 defaultResource->setActive();
42 AssetLoadInfo & loadInfo = *createLoadInfo();
43 loadInfo.resourceId = resourceId;
44 loadInfo.resourcePath = path.to_string();
47 if (context->variables->get(
"resources.assets.autoReload",
false)) {
48 loadInfo.loadFlags |= ResourceLoadFlags::AutoReload;
51 return loadResource(&loadInfo);
54void Cogs::Core::AssetManager::reloadAsset(AssetHandle & asset)
59void Cogs::Core::AssetManager::handleReload(ResourceHandleBase handle)
61 AssetHandle asset(handle);
63 AssetLoadInfo & loadInfo = *createLoadInfo();
64 loadInfo.resourceId = asset->getId();
65 loadInfo.resourcePath = asset->getSource().to_string();
67 loadInfo.handle = asset;
69 loadResource(&loadInfo);
74 const auto ext = Cogs::IO::extension(loadInfo->
resourcePath);
75 auto compressed = (ext.compare(zstdExtension) == 0);
78 if (!loadInfo->loadSync() && context->features->prefers(PlatformPreference::AsyncFetch) &&
79 !context->resourceStore->hasResource(loadInfo->
resourcePath)) {
81 auto handleResult = [that =
this, ctx = context, loadInfo, compressed](std::unique_ptr<FileContents> data)
84 if (data && readAssetDefinitionFromFileContents(ctx, std::move(data), definition, compressed)) {
85 if (loadInfo->loadSync()) {
86 AssetHandle(loadInfo->handle)->definition = std::move(definition);
89 auto asset = that->lock(loadInfo->handle);
90 asset->definition = std::move(definition);
94 LOG_WARNING(logger,
"Could not %sload asset definition.", loadInfo->isReload() ?
"re" :
"");
95 auto asset = that->lock(loadInfo->handle);
96 asset->setFailedLoad();
98 that->setProcessed(loadInfo, !loadInfo->loadSync());
101 DataFetcherManager::fetchAsync(context, loadInfo->resourcePath, handleResult);
106 auto loadResource = [=,
this]()
109 if (readAssetDefinitionFromFile(context, loadInfo->
resourcePath, definition, compressed)) {
110 if (loadInfo->loadSync()) {
114 auto asset = lock(loadInfo->
handle);
115 asset->definition = std::move(definition);
119 if (loadInfo->isReload()) {
120 LOG_WARNING(logger,
"Could not reload asset definition.");
123 LOG_WARNING(logger,
"Could not load asset definition.");
127 setProcessed(loadInfo, !loadInfo->loadSync());
130 if (loadInfo->loadSync() || !context->features->prefers(PlatformPreference::BackgroundTasks)) {
141 switch (resourceDefinition.type) {
142 case ResourceTypes::MaterialInstance:
144 instantiateMaterialInstance(asset, resourceDefinition);
147 case ResourceTypes::Model:
149 instantiateModel(asset, resourceDefinition);
152 case ResourceTypes::Texture:
154 instantiateTexture(asset, resourceDefinition);
158 LOG_ERROR(logger,
"Unknown resource type for asset resource %s", resourceDefinition.name.c_str());
163Cogs::Core::AssetHandle Cogs::Core::AssetManager::instantiateAsset(AssetHandle owner,
const ResourceDefinition& assetDefinition)
165 auto assetHandle = context->assetManager->loadAsset(assetDefinition.source, NoResourceId,
AssetLoadFlags::None);
166 assetHandle->
setName(assetDefinition.name);
169 auto found = std::find_if(owner->assets.begin(), owner->assets.end(), [&](
const AssetHandle& m) { return m.resolve() == assetHandle.resolve(); });
171 if (found == owner->assets.end()) {
172 owner->assets.emplace_back(assetHandle);
179Cogs::Core::ModelHandle Cogs::Core::AssetManager::instantiateModel(AssetHandle asset,
const ResourceDefinition & modelDefinition)
181 auto model = context->modelManager->loadModel(modelDefinition.source, NoResourceId,
ModelLoadFlags::None);
182 model->
setName(modelDefinition.name);
185 auto found = std::find_if(asset->models.begin(), asset->models.end(), [&](
const ModelHandle & m) { return m.resolve() == model.resolve(); });
187 if (found == asset->models.end()) {
188 asset->models.emplace_back(model);
195Cogs::Core::TextureHandle Cogs::Core::AssetManager::instantiateTexture(AssetHandle asset,
const ResourceDefinition & textureDefinition)
197 TextureHandle texture;
199 auto existing = context->textureManager->getTexture(textureDefinition.name,
true);
204 if (!textureDefinition.source.empty() && !textureDefinition.textureGenerator) {
205 texture = context->textureManager->loadTexture(textureDefinition.source, NoResourceId, textureDefinition.loadFlags);
207 texture = context->textureManager->create();
209 texture->description = textureDefinition.textureDescription;
212 texture->setChanged();
215 if (textureDefinition.textureGenerator) {
216 auto textureGenerator = context->services->getService<TextureGenerator>();
220 auto locked = context->textureManager->lock(texture);
222 textureGenerator->getTexture(locked.operator->(), textureDefinition.imageDefinition);
227 texture->setName(textureDefinition.name);
231 auto found = std::find_if(asset->textures.begin(), asset->textures.end(), [&](
const TextureHandle & t) { return t.resolve() == texture.resolve(); });
233 if (found == asset->textures.end()) {
234 asset->textures.emplace_back(texture);
243 if (!materialInstanceDefinition.reference.empty()) {
244 auto reference = context->materialInstanceManager->getMaterialInstance(materialInstanceDefinition.reference);
249 auto material = context->materialManager->getMaterial(materialInstanceDefinition.material);
252 LOG_ERROR(logger,
"No material with name \"%s\" found.", materialInstanceDefinition.material.c_str());
256 auto materialInstance = context->materialInstanceManager->createMaterialInstance(material);
258 materialInstance->setName(materialInstanceDefinition.name);
262 return materialInstance;
void handleLoad(AssetLoadInfo *loadInfo) override
Overridden to handle loading assets.
~AssetManager()
Destructs the AssetManager.
static constexpr TaskQueueId ResourceQueue
Resource task queue.
Log implementation class.
Provides a weakly referenced view over the contents of a string.
void updateMaterialInstance(Context *context, MaterialInstance *materialInstance, const MaterialInstanceDefinition &materialInstanceValue)
Apply material instance values.
ResourceLoadFlags
Flags for describing how to load a resource.
AssetLoadFlags
Asset and Scene loading flags. May be combined with resource loading flags.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
void setName(const StringView &name)
Set the user friendly name of the resource.
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
std::string resourcePath
Resource path. Used to locate resource.
ResourceHandleBase handle
Handle to resource structure for holding actual resource data.
@ RenderTarget
The texture can be used as a render target and drawn into.