Example scene loading
This commit is contained in:
@@ -4,11 +4,13 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void AssetManager::init() {
|
||||
|
||||
void AssetManager::init(const std::shared_ptr<Game> &game) {
|
||||
assertNotNull(game, "Game is NULL?");
|
||||
this->game = game;
|
||||
}
|
||||
|
||||
void AssetManager::update() {
|
||||
@@ -27,6 +29,22 @@ void AssetManager::update() {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetManager::remove(const std::shared_ptr<AssetLoader> loader) {
|
||||
auto existing = std::find(
|
||||
pendingAssetLoaders.begin(), pendingAssetLoaders.end(), loader
|
||||
);
|
||||
if(existing != pendingAssetLoaders.end()) {
|
||||
pendingAssetLoaders.erase(existing);
|
||||
}
|
||||
|
||||
existing = std::find(
|
||||
finishedAssetLoaders.begin(), finishedAssetLoaders.end(), loader
|
||||
);
|
||||
if(existing != finishedAssetLoaders.end()) {
|
||||
finishedAssetLoaders.erase(existing);
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled because it does not respect scopes
|
||||
// void AssetManager::removeExisting(const std::string &filename) {
|
||||
// auto existing = std::find_if(
|
||||
@@ -54,6 +72,12 @@ bool_t AssetManager::isEverythingLoaded() {
|
||||
return pendingAssetLoaders.size() == 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<Game> AssetManager::getGame() {
|
||||
auto g = game.lock();
|
||||
assertNotNull(g, "Game is NULL?");
|
||||
return g;
|
||||
}
|
||||
|
||||
AssetManager::~AssetManager() {
|
||||
|
||||
}
|
||||
@@ -8,8 +8,11 @@
|
||||
#include "asset/AssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Game;
|
||||
|
||||
class AssetManager final : public std::enable_shared_from_this<AssetManager> {
|
||||
private:
|
||||
std::weak_ptr<Game> game;
|
||||
std::vector<std::shared_ptr<AssetLoader>> pendingAssetLoaders;
|
||||
std::vector<std::shared_ptr<AssetLoader>> finishedAssetLoaders;
|
||||
|
||||
@@ -59,8 +62,10 @@ namespace Dawn {
|
||||
public:
|
||||
/**
|
||||
* Initializes this asset manager so it can begin accepting assets.
|
||||
*
|
||||
* @param game Game context that this asset manager is attached to.
|
||||
*/
|
||||
void init();
|
||||
void init(const std::shared_ptr<Game> &game);
|
||||
|
||||
/**
|
||||
* Updates the asset manager.
|
||||
@@ -96,6 +101,22 @@ namespace Dawn {
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the game context that this asset manager is attached to.
|
||||
*
|
||||
* @return The game context.
|
||||
*/
|
||||
std::shared_ptr<Game> getGame();
|
||||
|
||||
/**
|
||||
* Removes the given asset loader from the asset manager, assumes that
|
||||
* nothing else needs to access it and any dangling shared_ptrs will have
|
||||
* to remain in memory.
|
||||
*
|
||||
* @param loader The asset loader to remove.
|
||||
*/
|
||||
void remove(const std::shared_ptr<AssetLoader> loader);
|
||||
|
||||
/**
|
||||
* Dispose the asset manager, and all attached assets.
|
||||
*/
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
#pragma once
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "asset/AssetDataLoader.hpp"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace Dawn {
|
||||
enum class JSONLoaderState {
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneLoader.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;
|
||||
|
||||
@@ -18,6 +23,83 @@ SceneLoader::SceneLoader(
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void SceneLoader::sceneInitializer(Scene &scene) {
|
||||
std::cout << "Initializing scene" << std::endl;
|
||||
|
||||
auto &data = this->jsonLoader->data;
|
||||
if(data.contains("items")) {
|
||||
// Create the scene items
|
||||
for(auto &item : data["items"].items()) {
|
||||
auto &itemName = item.key();
|
||||
auto &itemData = item.value();
|
||||
auto sceneItem = scene.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];
|
||||
|
||||
ctx.data = itemData;
|
||||
sceneItem->load(ctx);
|
||||
|
||||
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", itemName.c_str());
|
||||
|
||||
auto cmpType = cmpData["type"].get<std::string>();
|
||||
auto cmp = SceneComponentRegistry::createComponent(cmpType, sceneItem);
|
||||
ctx.data = cmpData;
|
||||
ctx.components[cmpName] = cmp;
|
||||
cmp->load(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->jsonLoader = nullptr;
|
||||
this->state = SceneLoaderState::DONE;
|
||||
getAssetManager()->remove(shared_from_this());
|
||||
}
|
||||
|
||||
void SceneLoader::updateAsync() {
|
||||
switch(this->state) {
|
||||
case SceneLoaderState::INITIAL:
|
||||
@@ -26,6 +108,31 @@ void SceneLoader::updateAsync() {
|
||||
break;
|
||||
|
||||
case SceneLoaderState::LOADING_JSON:
|
||||
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
|
||||
if(!this->jsonLoader->loaded) return;
|
||||
this->setupDependencies();
|
||||
break;
|
||||
|
||||
case SceneLoaderState::LOADING_DEPENDENCIES:
|
||||
// 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;
|
||||
this->loaded = true;
|
||||
ctx.scene = std::make_shared<Scene>(
|
||||
this->getAssetManager()->getGame(),
|
||||
[this](Scene &scene) -> void {
|
||||
this->sceneInitializer(scene);
|
||||
}
|
||||
);
|
||||
this->state = SceneLoaderState::PENDING_STAGE;
|
||||
this->loaded = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -42,9 +149,11 @@ std::string SceneLoader::getAssetType() const {
|
||||
}
|
||||
|
||||
std::shared_ptr<Scene> SceneLoader::getScene() {
|
||||
return scene;
|
||||
return ctx.scene;
|
||||
}
|
||||
|
||||
SceneLoader::~SceneLoader() {
|
||||
|
||||
ctx = {};
|
||||
jsonLoader = nullptr;
|
||||
std::cout << "Scene Loader removed" << std::endl;
|
||||
}
|
||||
@@ -11,14 +11,32 @@ namespace Dawn {
|
||||
enum class SceneLoaderState {
|
||||
INITIAL,
|
||||
LOADING_JSON,
|
||||
LOADING_DEPENDENCIES,
|
||||
DEPENDENCIES_LOADED,
|
||||
PENDING_STAGE,
|
||||
DONE
|
||||
};
|
||||
|
||||
class SceneLoader : public AssetLoader {
|
||||
class SceneLoader :
|
||||
public AssetLoader,
|
||||
public std::enable_shared_from_this<SceneLoader>
|
||||
{
|
||||
protected:
|
||||
SceneLoaderState state;
|
||||
|
||||
std::shared_ptr<JSONLoader> jsonLoader;
|
||||
std::shared_ptr<Scene> scene;
|
||||
struct SceneComponentLoadContext ctx;
|
||||
|
||||
/**
|
||||
* Loads the dependencies of the scene.
|
||||
*/
|
||||
void setupDependencies();
|
||||
|
||||
/**
|
||||
* Scene intializer function to stage the loaded scene.
|
||||
*
|
||||
* @param scene Scene that is being staged.
|
||||
*/
|
||||
void sceneInitializer(Scene &scene);
|
||||
|
||||
public:
|
||||
const static std::string ASSET_TYPE;
|
||||
|
||||
Reference in New Issue
Block a user