Scene context improving but not finished.
This commit is contained in:
@@ -9,7 +9,7 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
TextureLoader.cpp
|
||||
JSONLoader.cpp
|
||||
TrueTypeLoader.cpp
|
||||
SceneLoader.cpp
|
||||
LoaderForSceneItems.cpp
|
||||
PrefabLoader.cpp
|
||||
)
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(scene)
|
||||
12
src/dawn/asset/loader/scene/CMakeLists.txt
Normal file
12
src/dawn/asset/loader/scene/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2025 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
SceneLoader.cpp
|
||||
LoaderForSceneItems.cpp
|
||||
PrefabLoader.cpp
|
||||
)
|
||||
@@ -5,17 +5,24 @@
|
||||
|
||||
#include "LoaderForSceneItems.hpp"
|
||||
#include "asset/loader/TextureLoader.hpp"
|
||||
#include "asset/loader/PrefabLoader.hpp"
|
||||
#include "asset/loader/scene/PrefabLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
LoaderForSceneItems::LoaderForSceneItems(
|
||||
const std::shared_ptr<AssetManager> assetManager,
|
||||
const std::string name
|
||||
) : AssetLoader(assetManager, name) {
|
||||
) :
|
||||
AssetLoader(assetManager, name),
|
||||
ctx(std::make_shared<SceneLoadContext>())
|
||||
{
|
||||
}
|
||||
|
||||
void LoaderForSceneItems::setupDependencies() {
|
||||
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
|
||||
assertNotNull(ctx, "SceneLoadContext is NULL?");
|
||||
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
|
||||
|
||||
// Begin loading dependencies.
|
||||
auto &data = this->jsonLoader->data;
|
||||
if(data.contains("assets")) {
|
||||
@@ -27,6 +34,18 @@ void LoaderForSceneItems::setupDependencies() {
|
||||
auto type = assetData["type"].get<std::string>();
|
||||
auto path = assetData["path"].get<std::string>();
|
||||
|
||||
// Is this asset already named?
|
||||
if(ctx->assets.find(assetName) != ctx->assets.end()) {
|
||||
// Check if path and type already the same.
|
||||
auto &existing = ctx->assets[assetName];
|
||||
assertTrue(
|
||||
existing->name == path && existing->getAssetType() == type,
|
||||
"Asset already exists with different path or type: %s",
|
||||
assetName.c_str()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<AssetLoader> loader;
|
||||
if(type == "texture") {
|
||||
loader = getAssetManager()->get<TextureLoader>(path);
|
||||
@@ -36,24 +55,18 @@ void LoaderForSceneItems::setupDependencies() {
|
||||
|
||||
} else if(type == "prefab") {
|
||||
auto prefabLoader = getAssetManager()->get<PrefabLoader>(path);
|
||||
prefabLoader->parentLoader = weak_from_this();
|
||||
prefabLoader->ctx->parent = ctx;
|
||||
loader = prefabLoader;
|
||||
|
||||
} else {
|
||||
assertUnreachable("Unknown asset type: %s", type.c_str());
|
||||
}
|
||||
|
||||
assertMapNotHasKey(
|
||||
ctx.assets,
|
||||
assetName,
|
||||
"Asset already exists: %s", assetName.c_str()
|
||||
);
|
||||
|
||||
ctx.assets[assetName] = loader;
|
||||
ctx->assets[assetName] = loader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoaderForSceneItems::~LoaderForSceneItems() {
|
||||
|
||||
jsonLoader = nullptr;
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "JSONLoader.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "asset/loader/JSONLoader.hpp"
|
||||
#include "SceneLoadContext.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class LoaderForSceneitems;
|
||||
@@ -24,7 +24,7 @@ namespace Dawn {
|
||||
void setupDependencies();
|
||||
|
||||
public:
|
||||
struct SceneComponentLoadContext ctx;
|
||||
const std::shared_ptr<SceneLoadContext> ctx;
|
||||
|
||||
LoaderForSceneItems(
|
||||
const std::shared_ptr<AssetManager> assetManager,
|
||||
@@ -42,7 +42,7 @@ void PrefabLoader::updateSync() {
|
||||
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
|
||||
|
||||
// Check if all dependencies are loaded.
|
||||
for(auto &asset : ctx.assets) {
|
||||
for(auto &asset : ctx->assets) {
|
||||
if(!asset.second->loaded) return;
|
||||
}
|
||||
|
||||
@@ -65,14 +65,10 @@ std::string PrefabLoader::getAssetType() const {
|
||||
void PrefabLoader::stagePrefab(std::shared_ptr<SceneItem> item) {
|
||||
assertTrue(this->loaded, "Prefab not loaded");
|
||||
|
||||
// Can we merge with the parent context?
|
||||
auto parentLoaderLock = this->parentLoader.lock();
|
||||
if(parentLoaderLock) this->ctx.merge(parentLoaderLock->ctx);
|
||||
|
||||
// Force-set new context values
|
||||
ctx.scene = item->getScene();
|
||||
ctx.data = this->jsonLoader->data;
|
||||
|
||||
ctx->data = this->jsonLoader->data;
|
||||
|
||||
// Load the scene item.
|
||||
item->load(ctx);
|
||||
|
||||
auto &itemData = this->jsonLoader->data;
|
||||
@@ -90,8 +86,8 @@ void PrefabLoader::stagePrefab(std::shared_ptr<SceneItem> item) {
|
||||
auto cmp = SceneComponentRegistry::createComponent(
|
||||
cmpType, item
|
||||
);
|
||||
ctx.data = cmpData;
|
||||
ctx.components[cmpName] = cmp;
|
||||
ctx->data = cmpData;
|
||||
ctx->components[cmpName] = cmp;
|
||||
cmp->load(ctx);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ namespace Dawn {
|
||||
|
||||
public:
|
||||
const static std::string ASSET_TYPE;
|
||||
std::weak_ptr<LoaderForSceneItems> parentLoader;
|
||||
|
||||
PrefabLoader(
|
||||
const std::shared_ptr<AssetManager> assetManager,
|
||||
6
src/dawn/asset/loader/scene/SceneLoadContext.cpp
Normal file
6
src/dawn/asset/loader/scene/SceneLoadContext.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneLoadContext.hpp"
|
||||
51
src/dawn/asset/loader/scene/SceneLoadContext.hpp
Normal file
51
src/dawn/asset/loader/scene/SceneLoadContext.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Scene;
|
||||
class SceneItem;
|
||||
class SceneComponent;
|
||||
class AssetLoader;
|
||||
class SceneLoadContext;
|
||||
|
||||
class SceneLoadContext {
|
||||
public:
|
||||
std::weak_ptr<SceneLoadContext> parent;
|
||||
std::unordered_map<std::string, std::shared_ptr<SceneItem>> items;
|
||||
std::unordered_map<std::string, std::shared_ptr<SceneComponent>> components;
|
||||
std::unordered_map<std::string, std::shared_ptr<AssetLoader>> assets;
|
||||
|
||||
json data;
|
||||
|
||||
std::shared_ptr<Scene> currentScene;
|
||||
std::shared_ptr<SceneItem> currentItem;
|
||||
std::shared_ptr<SceneComponent> currentComponent;
|
||||
|
||||
/**
|
||||
* Gets an asset from the context.
|
||||
*
|
||||
* @param j Name of the asset to get.
|
||||
* @return Asset from the context.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getAsset(const std::string &j) const {
|
||||
auto it = assets.find(j);
|
||||
if(it == assets.end()) {
|
||||
auto parent = this->parent.lock();
|
||||
assertNotNull(parent, "Couldn't find asset.");
|
||||
return parent->getAsset<T>(j);
|
||||
}
|
||||
auto asset = std::dynamic_pointer_cast<T>(it->second);
|
||||
assertNotNull(asset, "Asset is not of the correct type.");
|
||||
return asset;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
@@ -33,6 +33,7 @@ void SceneLoader::updateAsync() {
|
||||
case SceneLoaderState::LOADING_JSON:
|
||||
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
|
||||
if(!this->jsonLoader->loaded) return;
|
||||
this->ctx->data = this->jsonLoader->data;
|
||||
this->setupDependencies();
|
||||
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
|
||||
break;
|
||||
@@ -40,10 +41,12 @@ void SceneLoader::updateAsync() {
|
||||
case SceneLoaderState::LOADING_DEPENDENCIES:
|
||||
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
|
||||
// Check if all dependencies are loaded.
|
||||
for(auto &asset : ctx.assets) {
|
||||
for(auto &asset : ctx->assets) {
|
||||
if(!asset.second->loaded) return;
|
||||
}
|
||||
ctx.scene = std::make_shared<Scene>(this->getAssetManager()->getGame());
|
||||
ctx->currentScene = std::make_shared<Scene>(
|
||||
this->getAssetManager()->getGame()
|
||||
);
|
||||
this->state = SceneLoaderState::PENDING_STAGE;
|
||||
break;
|
||||
|
||||
@@ -54,6 +57,8 @@ void SceneLoader::updateAsync() {
|
||||
|
||||
void SceneLoader::updateSync() {
|
||||
if(this->state != SceneLoaderState::PENDING_STAGE) return;
|
||||
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
|
||||
assertNotNull(ctx, "SceneLoadContext is NULL?");
|
||||
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
|
||||
|
||||
auto &data = this->jsonLoader->data;
|
||||
@@ -62,17 +67,17 @@ void SceneLoader::updateSync() {
|
||||
for(auto &item : data["items"].items()) {
|
||||
auto &itemName = item.key();
|
||||
auto &itemData = item.value();
|
||||
auto sceneItem = ctx.scene->createSceneItem();
|
||||
ctx.items[itemName] = sceneItem;
|
||||
auto sceneItem = ctx->currentScene->createSceneItem();
|
||||
ctx->items[itemName] = sceneItem;
|
||||
}
|
||||
|
||||
// Add components to each scene item
|
||||
for(auto &item : data["items"].items()) {
|
||||
auto &itemName = item.key();
|
||||
auto &itemData = item.value();
|
||||
auto sceneItem = ctx.items[itemName];
|
||||
auto sceneItem = ctx->items[itemName];
|
||||
|
||||
ctx.data = itemData;
|
||||
ctx->data = itemData;
|
||||
sceneItem->load(ctx);
|
||||
|
||||
if(itemData.contains("components")) {
|
||||
@@ -89,8 +94,8 @@ void SceneLoader::updateSync() {
|
||||
auto cmp = SceneComponentRegistry::createComponent(
|
||||
cmpType, sceneItem
|
||||
);
|
||||
ctx.data = cmpData;
|
||||
ctx.components[cmpName] = cmp;
|
||||
ctx->data = cmpData;
|
||||
ctx->components[cmpName] = cmp;
|
||||
cmp->load(ctx);
|
||||
}
|
||||
}
|
||||
@@ -100,11 +105,6 @@ void SceneLoader::updateSync() {
|
||||
this->jsonLoader = nullptr;
|
||||
this->state = SceneLoaderState::DONE;
|
||||
this->loaded = true;
|
||||
|
||||
ctx.assets.clear();
|
||||
ctx.components.clear();
|
||||
ctx.items.clear();
|
||||
ctx.data = {};
|
||||
}
|
||||
|
||||
std::string SceneLoader::getAssetType() const {
|
||||
@@ -112,10 +112,10 @@ std::string SceneLoader::getAssetType() const {
|
||||
}
|
||||
|
||||
std::shared_ptr<Scene> SceneLoader::getScene() {
|
||||
return ctx.scene;
|
||||
assertNotNull(ctx, "Context is NULL?");
|
||||
assertNotNull(ctx->currentScene, "Scene not loaded?");
|
||||
return ctx->currentScene;
|
||||
}
|
||||
|
||||
SceneLoader::~SceneLoader() {
|
||||
ctx = {};
|
||||
jsonLoader = nullptr;
|
||||
}
|
||||
Reference in New Issue
Block a user