Added prefabs

This commit is contained in:
2024-12-02 20:00:54 -06:00
parent 9fd4c2399f
commit e660fade95
28 changed files with 332 additions and 268 deletions

View File

@@ -14,6 +14,7 @@ namespace Dawn {
std::weak_ptr<AssetManager> assetManager;
public:
std::string typetest;
const static std::string ASSET_TYPE;
const std::string name;

View File

@@ -14,18 +14,29 @@ void AssetManager::init(const std::shared_ptr<Game> &game) {
}
void AssetManager::update() {
auto itPending = pendingAssetLoaders.begin();
while(itPending != pendingAssetLoaders.end()) {
auto copyPendingAssets = pendingAssetLoaders;
auto itPending = copyPendingAssets.begin();
while(itPending != copyPendingAssets.end()) {
auto loader = *itPending;
loader->updateSync();
loader->updateAsync();
loader->updateSync();
if(loader->loaded) {
finishedAssetLoaders.push_back(loader);
itPending = pendingAssetLoaders.erase(itPending);
} else {
itPending++;
if(!loader->loaded) {
++itPending;
continue;
}
finishedAssetLoaders.push_back(loader);
auto it = std::find(
pendingAssetLoaders.begin(),
pendingAssetLoaders.end(),
loader
);
assertTrue(it != pendingAssetLoaders.end(), "Loader not found?");
pendingAssetLoaders.erase(it);
++itPending;
}
}

View File

@@ -10,4 +10,6 @@ target_sources(${DAWN_TARGET_NAME}
JSONLoader.cpp
TrueTypeLoader.cpp
SceneLoader.cpp
LoaderForSceneItems.cpp
PrefabLoader.cpp
)

View File

@@ -17,6 +17,7 @@ JSONLoader::JSONLoader(
loader(name),
state(JSONLoaderState::INITIAL)
{
this->typetest = this->getAssetType();
}
void JSONLoader::updateAsync() {

View File

@@ -0,0 +1,57 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "LoaderForSceneItems.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "asset/loader/PrefabLoader.hpp"
using namespace Dawn;
LoaderForSceneItems::LoaderForSceneItems(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) : AssetLoader(assetManager, name) {
}
void LoaderForSceneItems::setupDependencies() {
// Begin loading dependencies.
auto &data = this->jsonLoader->data;
if(data.contains("assets")) {
for(auto &asset : data["assets"].items()) {
auto &assetName = asset.key();
auto &assetData = asset.value();
assertTrue(assetData.contains("type"), "Asset missing type");
assertTrue(assetData.contains("path"), "Asset missing path");
auto type = assetData["type"].get<std::string>();
auto path = assetData["path"].get<std::string>();
std::shared_ptr<AssetLoader> loader;
if(type == "texture") {
loader = getAssetManager()->get<TextureLoader>(path);
} else if(type == "json") {
loader = getAssetManager()->get<JSONLoader>(path);
} else if(type == "prefab") {
loader = getAssetManager()->get<PrefabLoader>(path);
} else {
assertUnreachable("Unknown asset type: %s", type.c_str());
}
assertMapNotHasKey(
ctx.assets,
assetName,
"Asset already exists: %s", assetName.c_str()
);
ctx.assets[assetName] = loader;
}
}
}
LoaderForSceneItems::~LoaderForSceneItems() {
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "JSONLoader.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
class LoaderForSceneItems : public AssetLoader {
protected:
std::shared_ptr<JSONLoader> jsonLoader;
struct SceneComponentLoadContext ctx;
/**
* Loads the dependencies into the context for the data available in
* the jsonLoader.
*/
void setupDependencies();
public:
LoaderForSceneItems(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
~LoaderForSceneItems();
};
}

View File

@@ -0,0 +1,97 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "PrefabLoader.hpp"
#include "game/Game.hpp"
#include "assert/assert.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "scene/Scene.hpp"
#include "component/SceneComponentRegistry.hpp"
using namespace Dawn;
const std::string PrefabLoader::ASSET_TYPE = "prefab";
PrefabLoader::PrefabLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
LoaderForSceneItems(assetManager, name)
{
this->typetest = this->getAssetType();
}
void PrefabLoader::updateSync() {
switch(this->state) {
case PrefabLoaderState::INITIAL:
jsonLoader = getAssetManager()->get<JSONLoader>(this->name);
this->state = PrefabLoaderState::LOADING_JSON;
break;
case PrefabLoaderState::LOADING_JSON:
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
if(!this->jsonLoader->loaded) return;
this->state = PrefabLoaderState::LOADING_DEPENDENCIES;
break;
case PrefabLoaderState::LOADING_DEPENDENCIES:
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
// Check if all dependencies are loaded.
for(auto &asset : ctx.assets) {
if(!asset.second->loaded) return;
}
this->state = PrefabLoaderState::DEPENDENCIES_LOADED;
this->loaded = true;
break;
default:
break;
}
}
void PrefabLoader::updateAsync() {
}
std::string PrefabLoader::getAssetType() const {
return PrefabLoader::ASSET_TYPE;
}
void PrefabLoader::stagePrefab(std::shared_ptr<SceneItem> item) {
assertTrue(this->loaded, "Prefab not loaded");
ctx.scene = item->getScene();
ctx.data = this->jsonLoader->data;
item->load(ctx);
auto &itemData = this->jsonLoader->data;
if(itemData.contains("components")) {
for(auto &cmpItem : itemData["components"].items()) {
auto &cmpName = cmpItem.key();
auto &cmpData = cmpItem.value();
assertTrue(
cmpData.contains("type"),
"Component missing type in %s",
cmpName.c_str()
);
auto cmpType = cmpData["type"].get<std::string>();
auto cmp = SceneComponentRegistry::createComponent(
cmpType, item
);
ctx.data = cmpData;
ctx.components[cmpName] = cmp;
cmp->load(ctx);
}
}
}
PrefabLoader::~PrefabLoader() {
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "LoaderForSceneItems.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
enum class PrefabLoaderState {
INITIAL,
LOADING_JSON,
LOADING_DEPENDENCIES,
DEPENDENCIES_LOADED,
DONE
};
class PrefabLoader : public LoaderForSceneItems {
protected:
PrefabLoaderState state = PrefabLoaderState::INITIAL;
std::shared_ptr<SceneItem> item;
public:
const static std::string ASSET_TYPE;
PrefabLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
/**
* Stages this prefab onto a scene item.
*
* @param item The scene item to stage.
*/
void stagePrefab(std::shared_ptr<SceneItem> item);
~PrefabLoader();
};
}

View File

@@ -6,7 +6,6 @@
#include "SceneLoader.hpp"
#include "game/Game.hpp"
#include "assert/assert.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "scene/Scene.hpp"
#include "component/SceneComponentRegistry.hpp"
@@ -18,43 +17,10 @@ SceneLoader::SceneLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
LoaderForSceneItems(assetManager, name),
state(SceneLoaderState::INITIAL)
{
}
void SceneLoader::setupDependencies() {
std::cout << "Setting up dependencies" << std::endl;
// Begin loading dependencies.
auto &data = this->jsonLoader->data;
if(data.contains("assets")) {
for(auto &asset : data["assets"].items()) {
auto &assetName = asset.key();
auto &assetData = asset.value();
assertTrue(assetData.contains("type"), "Asset missing type");
assertTrue(assetData.contains("path"), "Asset missing path");
auto type = assetData["type"].get<std::string>();
auto path = assetData["path"].get<std::string>();
std::shared_ptr<AssetLoader> loader;
if(type == "texture") {
loader = getAssetManager()->get<TextureLoader>(path);
} else if(type == "json") {
loader = getAssetManager()->get<JSONLoader>(path);
} else {
assertUnreachable("Unknown asset type: %s", type.c_str());
}
assertMapNotHasKey(
ctx.assets,
assetName,
"Asset already exists: %s", assetName.c_str()
);
ctx.assets[assetName] = loader;
}
}
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
this->typetest = this->getAssetType();
}
void SceneLoader::updateAsync() {
@@ -68,18 +34,15 @@ void SceneLoader::updateAsync() {
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
if(!this->jsonLoader->loaded) return;
this->setupDependencies();
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
break;
case SceneLoaderState::LOADING_DEPENDENCIES:
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
// Check if all dependencies are loaded.
for(auto &asset : ctx.assets) {
if(!asset.second->loaded) return;
}
this->state = SceneLoaderState::DEPENDENCIES_LOADED;
break;
case SceneLoaderState::DEPENDENCIES_LOADED:
std::cout << "Deps Loaded" << std::endl;
ctx.scene = std::make_shared<Scene>(this->getAssetManager()->getGame());
this->state = SceneLoaderState::PENDING_STAGE;
break;
@@ -91,6 +54,7 @@ void SceneLoader::updateAsync() {
void SceneLoader::updateSync() {
if(this->state != SceneLoaderState::PENDING_STAGE) return;
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
auto &data = this->jsonLoader->data;
if(data.contains("items")) {
@@ -115,10 +79,16 @@ void SceneLoader::updateSync() {
for(auto &cmpItem : itemData["components"].items()) {
auto &cmpName = cmpItem.key();
auto &cmpData = cmpItem.value();
assertTrue(cmpData.contains("type"), "Component missing type in %s", itemName.c_str());
assertTrue(
cmpData.contains("type"),
"Component missing type in %s",
cmpName.c_str()
);
auto cmpType = cmpData["type"].get<std::string>();
auto cmp = SceneComponentRegistry::createComponent(cmpType, sceneItem);
auto cmp = SceneComponentRegistry::createComponent(
cmpType, sceneItem
);
ctx.data = cmpData;
ctx.components[cmpName] = cmp;
cmp->load(ctx);
@@ -130,6 +100,11 @@ 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 {
@@ -143,5 +118,4 @@ std::shared_ptr<Scene> SceneLoader::getScene() {
SceneLoader::~SceneLoader() {
ctx = {};
jsonLoader = nullptr;
std::cout << "Scene Loader removed" << std::endl;
}

View File

@@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "JSONLoader.hpp"
#include "LoaderForSceneItems.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
@@ -12,24 +12,13 @@ namespace Dawn {
INITIAL,
LOADING_JSON,
LOADING_DEPENDENCIES,
DEPENDENCIES_LOADED,
PENDING_STAGE,
DONE
};
class SceneLoader :
public AssetLoader,
public std::enable_shared_from_this<SceneLoader>
{
class SceneLoader : public LoaderForSceneItems {
protected:
SceneLoaderState state;
std::shared_ptr<JSONLoader> jsonLoader;
struct SceneComponentLoadContext ctx;
/**
* Loads the dependencies of the scene.
*/
void setupDependencies();
public:
const static std::string ASSET_TYPE;
@@ -38,6 +27,7 @@ namespace Dawn {
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;

View File

@@ -18,6 +18,7 @@ TextureLoader::TextureLoader(
loader(name),
state(TextureLoaderLoadState::INITIAL)
{
this->typetest = this->getAssetType();
texture = std::make_shared<Texture>();
}

View File

@@ -17,6 +17,7 @@ TrueTypeLoader::TrueTypeLoader(
AssetLoader(assetManager, name),
loader(name)
{
this->typetest = this->getAssetType();
// Init the font.
auto ret = FT_Init_FreeType(&fontLibrary);
assertTrue(ret == 0, "Failed to initialize FreeType library.");