Made scenes, items and components a lot cleaner, asset manager also cleans up properly.
This commit is contained in:
@ -6,6 +6,7 @@
|
|||||||
"path": "rosa.texture"
|
"path": "rosa.texture"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"items": {
|
"items": {
|
||||||
"camera": {
|
"camera": {
|
||||||
"lookAt": {
|
"lookAt": {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dawn.hpp"
|
#include "util/Flag.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that a given statement must evaluate to true or the assertion fails
|
* Asserts that a given statement must evaluate to true or the assertion fails
|
||||||
@ -104,7 +104,7 @@ void assertTrueImplement(
|
|||||||
* @param args Optional TParam args for the sprintf message to accept.
|
* @param args Optional TParam args for the sprintf message to accept.
|
||||||
*/
|
*/
|
||||||
#define assertFlagOff(value, flag, ...) assertTrue( \
|
#define assertFlagOff(value, flag, ...) assertTrue( \
|
||||||
(value & flag) == 0, __VA_ARGS__ \
|
Flag::isOff(value, flag), __VA_ARGS__ \
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +116,7 @@ void assertTrueImplement(
|
|||||||
* @param args Optional TParam args for the sprintf message to accept.
|
* @param args Optional TParam args for the sprintf message to accept.
|
||||||
*/
|
*/
|
||||||
#define assertFlagOn(value, flag, ...) assertTrue( \
|
#define assertFlagOn(value, flag, ...) assertTrue( \
|
||||||
(value & flag) == flag, __VA_ARGS__ \
|
Flag::isOn(value, flag), __VA_ARGS__ \
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,44 +30,27 @@ void AssetManager::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::remove(const std::shared_ptr<AssetLoader> loader) {
|
void AssetManager::remove(const std::shared_ptr<AssetLoader> loader) {
|
||||||
auto existing = std::find(
|
for(
|
||||||
pendingAssetLoaders.begin(), pendingAssetLoaders.end(), loader
|
auto it = pendingAssetLoaders.begin();
|
||||||
);
|
it != pendingAssetLoaders.end();
|
||||||
if(existing != pendingAssetLoaders.end()) {
|
it++
|
||||||
pendingAssetLoaders.erase(existing);
|
) {
|
||||||
|
if(*it != loader) continue;
|
||||||
|
pendingAssetLoaders.erase(it);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
existing = std::find(
|
for(
|
||||||
finishedAssetLoaders.begin(), finishedAssetLoaders.end(), loader
|
auto it = finishedAssetLoaders.begin();
|
||||||
);
|
it != finishedAssetLoaders.end();
|
||||||
if(existing != finishedAssetLoaders.end()) {
|
it++
|
||||||
finishedAssetLoaders.erase(existing);
|
) {
|
||||||
|
if(it->lock() != loader) continue;
|
||||||
|
finishedAssetLoaders.erase(it);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabled because it does not respect scopes
|
|
||||||
// void AssetManager::removeExisting(const std::string &filename) {
|
|
||||||
// auto existing = std::find_if(
|
|
||||||
// pendingAssetLoaders.begin(), pendingAssetLoaders.end(),
|
|
||||||
// [&](auto &loader) {
|
|
||||||
// return loader->name == filename;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// if(existing != pendingAssetLoaders.end()) {
|
|
||||||
// pendingAssetLoaders.erase(existing);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// existing = std::find_if(
|
|
||||||
// finishedAssetLoaders.begin(), finishedAssetLoaders.end(),
|
|
||||||
// [&](auto &loader) {
|
|
||||||
// return loader->name == filename;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// if(existing != finishedAssetLoaders.end()) {
|
|
||||||
// finishedAssetLoaders.erase(existing);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool_t AssetManager::isEverythingLoaded() {
|
bool_t AssetManager::isEverythingLoaded() {
|
||||||
return pendingAssetLoaders.size() == 0;
|
return pendingAssetLoaders.size() == 0;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ namespace Dawn {
|
|||||||
private:
|
private:
|
||||||
std::weak_ptr<Game> game;
|
std::weak_ptr<Game> game;
|
||||||
std::vector<std::shared_ptr<AssetLoader>> pendingAssetLoaders;
|
std::vector<std::shared_ptr<AssetLoader>> pendingAssetLoaders;
|
||||||
std::vector<std::shared_ptr<AssetLoader>> finishedAssetLoaders;
|
std::vector<std::weak_ptr<AssetLoader>> finishedAssetLoaders;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an existing asset loader if it exists.
|
* Returns an existing asset loader if it exists.
|
||||||
@ -24,32 +24,21 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
std::shared_ptr<T> getExisting(const std::string &filename) {
|
std::shared_ptr<T> getExisting(const std::string &filename) {
|
||||||
auto existing = std::find_if(
|
for(auto &loader : pendingAssetLoaders) {
|
||||||
pendingAssetLoaders.begin(),
|
if(loader->name != filename) continue;
|
||||||
pendingAssetLoaders.end(),
|
if(loader->getAssetType() != T::ASSET_TYPE) continue;
|
||||||
[&](auto &loader) {
|
return std::static_pointer_cast<T>(loader);
|
||||||
return (
|
|
||||||
loader->name == filename &&
|
|
||||||
loader->getAssetType() == T::ASSET_TYPE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if(existing == pendingAssetLoaders.end()) {
|
|
||||||
existing = std::find_if(
|
|
||||||
finishedAssetLoaders.begin(), finishedAssetLoaders.end(),
|
|
||||||
[&](auto &loader) {
|
|
||||||
return (
|
|
||||||
loader->name == filename &&
|
|
||||||
loader->getAssetType() == T::ASSET_TYPE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if(existing == finishedAssetLoaders.end()) return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::static_pointer_cast<T>(*existing);
|
for(auto &wLoader : finishedAssetLoaders) {
|
||||||
|
auto loader = wLoader.lock();
|
||||||
|
if(!loader) continue;
|
||||||
|
if(loader->name != filename) continue;
|
||||||
|
if(loader->getAssetType() != T::ASSET_TYPE) continue;
|
||||||
|
return std::static_pointer_cast<T>(loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +57,40 @@ void SceneLoader::setupDependencies() {
|
|||||||
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
|
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneLoader::sceneInitializer(Scene &scene) {
|
void SceneLoader::updateAsync() {
|
||||||
std::cout << "Initializing scene" << std::endl;
|
switch(this->state) {
|
||||||
|
case SceneLoaderState::INITIAL:
|
||||||
|
this->jsonLoader = getAssetManager()->get<JSONLoader>(this->name);
|
||||||
|
this->state = SceneLoaderState::LOADING_JSON;
|
||||||
|
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;
|
||||||
|
ctx.scene = std::make_shared<Scene>(this->getAssetManager()->getGame());
|
||||||
|
this->state = SceneLoaderState::PENDING_STAGE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneLoader::updateSync() {
|
||||||
|
if(this->state != SceneLoaderState::PENDING_STAGE) return;
|
||||||
|
|
||||||
auto &data = this->jsonLoader->data;
|
auto &data = this->jsonLoader->data;
|
||||||
if(data.contains("items")) {
|
if(data.contains("items")) {
|
||||||
@ -66,7 +98,7 @@ void SceneLoader::sceneInitializer(Scene &scene) {
|
|||||||
for(auto &item : data["items"].items()) {
|
for(auto &item : data["items"].items()) {
|
||||||
auto &itemName = item.key();
|
auto &itemName = item.key();
|
||||||
auto &itemData = item.value();
|
auto &itemData = item.value();
|
||||||
auto sceneItem = scene.createSceneItem();
|
auto sceneItem = ctx.scene->createSceneItem();
|
||||||
ctx.items[itemName] = sceneItem;
|
ctx.items[itemName] = sceneItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,51 +129,7 @@ void SceneLoader::sceneInitializer(Scene &scene) {
|
|||||||
|
|
||||||
this->jsonLoader = nullptr;
|
this->jsonLoader = nullptr;
|
||||||
this->state = SceneLoaderState::DONE;
|
this->state = SceneLoaderState::DONE;
|
||||||
getAssetManager()->remove(shared_from_this());
|
this->loaded = true;
|
||||||
}
|
|
||||||
|
|
||||||
void SceneLoader::updateAsync() {
|
|
||||||
switch(this->state) {
|
|
||||||
case SceneLoaderState::INITIAL:
|
|
||||||
this->jsonLoader = getAssetManager()->get<JSONLoader>(this->name);
|
|
||||||
this->state = SceneLoaderState::LOADING_JSON;
|
|
||||||
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:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SceneLoader::updateSync() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SceneLoader::getAssetType() const {
|
std::string SceneLoader::getAssetType() const {
|
||||||
|
@ -31,13 +31,6 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
void setupDependencies();
|
void setupDependencies();
|
||||||
|
|
||||||
/**
|
|
||||||
* Scene intializer function to stage the loaded scene.
|
|
||||||
*
|
|
||||||
* @param scene Scene that is being staged.
|
|
||||||
*/
|
|
||||||
void sceneInitializer(Scene &scene);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const static std::string ASSET_TYPE;
|
const static std::string ASSET_TYPE;
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ IGame::IGame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IGame::init() {
|
void IGame::init() {
|
||||||
assertFlagOff(state, GAME_STATE_INITIALIZED, "Game already initialized?");
|
assertFlagOff(state, GameState::INITIALIZED, "Game already initialized?");
|
||||||
Flag::turnOn<uint8_t>(state, GAME_STATE_INITIALIZED);
|
Flag::turnOn(state, GameState::INITIALIZED);
|
||||||
|
|
||||||
auto selfAsGame = this->getSelfAsGame();
|
auto selfAsGame = this->getSelfAsGame();
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ void IGame::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IGame::deinit() {
|
void IGame::deinit() {
|
||||||
assertFlagOn(state, GAME_STATE_INITIALIZED, "Game not initialized?");
|
assertFlagOn(state, GameState::INITIALIZED, "Game not initialized?");
|
||||||
|
|
||||||
if(currentScene) currentScene->deinit();
|
if(currentScene) currentScene->deinit();
|
||||||
currentScene = nullptr;
|
currentScene = nullptr;
|
||||||
@ -67,7 +67,7 @@ void IGame::deinit() {
|
|||||||
assetManager = nullptr;
|
assetManager = nullptr;
|
||||||
renderHost = nullptr;
|
renderHost = nullptr;
|
||||||
|
|
||||||
Flag::turnOff<uint8_t>(state, GAME_STATE_INITIALIZED);
|
Flag::turnOff(state, GameState::INITIALIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IGame::update() {
|
void IGame::update() {
|
||||||
@ -106,5 +106,5 @@ std::shared_ptr<Game> IGame::getSelfAsGame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IGame::~IGame() {
|
IGame::~IGame() {
|
||||||
assertFlagOff(state, GAME_STATE_INITIALIZED, "Game not deinited properly?");
|
assertFlagOff(state, GameState::INITIALIZED, "Game not deinited properly?");
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dawn.hpp"
|
#include "dawn.hpp"
|
||||||
|
#include "util/Flag.hpp"
|
||||||
#include "display/RenderHost.hpp"
|
#include "display/RenderHost.hpp"
|
||||||
#include "input/InputManager.hpp"
|
#include "input/InputManager.hpp"
|
||||||
#include "time/TimeManager.hpp"
|
#include "time/TimeManager.hpp"
|
||||||
@ -13,17 +14,20 @@
|
|||||||
#include "save/SaveManager.hpp"
|
#include "save/SaveManager.hpp"
|
||||||
#include "physics/PhysicsManager.hpp"
|
#include "physics/PhysicsManager.hpp"
|
||||||
|
|
||||||
#define GAME_STATE_INITIALIZED 0x01
|
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Scene;
|
class Scene;
|
||||||
class Game;
|
class Game;
|
||||||
|
|
||||||
|
enum class GameState : flag_t {
|
||||||
|
INITIAL = FLAG(0),
|
||||||
|
INITIALIZED = FLAG(1),
|
||||||
|
};
|
||||||
|
|
||||||
class IGame : public std::enable_shared_from_this<IGame> {
|
class IGame : public std::enable_shared_from_this<IGame> {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Scene> currentScene = nullptr;
|
std::shared_ptr<Scene> currentScene = nullptr;
|
||||||
std::shared_ptr<Scene> nextFrameScene = nullptr;
|
std::shared_ptr<Scene> nextFrameScene = nullptr;
|
||||||
uint8_t state = 0;
|
flag_t state = (flag_t)GameState::INITIAL;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -32,7 +36,7 @@ namespace Dawn {
|
|||||||
*
|
*
|
||||||
* @return The initial scene.
|
* @return The initial scene.
|
||||||
*/
|
*/
|
||||||
virtual std::function<void(Scene&)> getInitialScene() = 0;
|
// virtual std::function<void(Scene&)> getInitialScene() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the game managers.
|
* Initializes the game managers.
|
||||||
|
@ -4,45 +4,41 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
#include "Scene.hpp"
|
#include "Scene.hpp"
|
||||||
|
#include "assert/assert.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
Scene::Scene(
|
Scene::Scene(const std::shared_ptr<Game> &game) : game(game) {
|
||||||
const std::weak_ptr<Game> game,
|
assertNotNull(game, "Game cannot be NULL");
|
||||||
const std::function<void(Scene&)> sceneInitializer
|
|
||||||
) :
|
|
||||||
game(game),
|
|
||||||
sceneInitializer(sceneInitializer)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::init() {
|
void Scene::init() {
|
||||||
Scene &selfReference = *this;
|
assertFlagOff(state, SceneState::INITIALIZED, "Scene already initialized");
|
||||||
sceneInitializer(selfReference);
|
Flag::turnOn(state, SceneState::INITIALIZED);
|
||||||
sceneInitializer = [](Scene &scene) -> void {
|
|
||||||
|
for(auto &item : sceneItems) {
|
||||||
};
|
item->init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::deinit() {
|
void Scene::deinit() {
|
||||||
if(!this->hasInitialized) return;
|
assertFlagOn(state, SceneState::INITIALIZED, "Scene not initialized");
|
||||||
this->hasInitialized = false;
|
assertFlagOff(state, SceneState::DEINITIALIZED,"Scene already deinitialized");
|
||||||
|
|
||||||
auto items = this->sceneItems;
|
auto items = this->sceneItems;
|
||||||
for(auto &item : items) {
|
for(auto &item : items) {
|
||||||
item->deinit();
|
item->deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
sceneItems.clear();
|
sceneItems.clear();
|
||||||
|
sceneItemsToRemove.clear();
|
||||||
|
|
||||||
|
Flag::turnOn(state, SceneState::DEINITIALIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::update() {
|
void Scene::update() {
|
||||||
// Initialize new scene items
|
// Initialize new scene items
|
||||||
if(!hasInitialized) {
|
assertFlagOn(state, SceneState::INITIALIZED, "Scene not initialized");
|
||||||
hasInitialized = true;
|
|
||||||
for(auto &item : sceneItems) {
|
|
||||||
item->init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove stale scene items.
|
// Remove stale scene items.
|
||||||
auto itRemove = sceneItemsToRemove.begin();
|
auto itRemove = sceneItemsToRemove.begin();
|
||||||
@ -70,16 +66,22 @@ void Scene::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Game> Scene::getGame() {
|
std::shared_ptr<Game> Scene::getGame() {
|
||||||
return game.lock();
|
auto game = this->game.lock();
|
||||||
|
assertNotNull(game, "Game is NULL");
|
||||||
|
return game;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
||||||
|
assertFlagOff(state, SceneState::DEINITIALIZED, "Scene deinitialized");
|
||||||
auto item = std::make_shared<SceneItem>(shared_from_this());
|
auto item = std::make_shared<SceneItem>(shared_from_this());
|
||||||
sceneItems.push_back(item);
|
sceneItems.push_back(item);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::removeItem(const std::shared_ptr<SceneItem> item) {
|
void Scene::removeItem(const std::shared_ptr<SceneItem> item) {
|
||||||
|
assertFlagOn(state, SceneState::INITIALIZED, "Scene not initialized");
|
||||||
|
assertFlagOff(state, SceneState::DEINITIALIZED, "Scene deinitialized");
|
||||||
|
|
||||||
auto index = std::find(sceneItems.begin(), sceneItems.end(), item);
|
auto index = std::find(sceneItems.begin(), sceneItems.end(), item);
|
||||||
if(index == sceneItems.end()) return;
|
if(index == sceneItems.end()) return;
|
||||||
|
|
||||||
@ -87,5 +89,7 @@ void Scene::removeItem(const std::shared_ptr<SceneItem> item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
this->deinit();
|
if(Flag::isOn(state, SceneState::INITIALIZED)) {
|
||||||
|
assertFlagOn(state, SceneState::DEINITIALIZED, "Scene not deinitialized!");
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,21 +9,27 @@
|
|||||||
#include "event/Event.hpp"
|
#include "event/Event.hpp"
|
||||||
#include "time/event/IntervalEvent.hpp"
|
#include "time/event/IntervalEvent.hpp"
|
||||||
#include "time/event/TimeoutEvent.hpp"
|
#include "time/event/TimeoutEvent.hpp"
|
||||||
|
#include "util/Flag.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
struct IntervalData {
|
// struct IntervalData {
|
||||||
float_t frequency;
|
// float_t frequency;
|
||||||
float_t nextInvoke;
|
// float_t nextInvoke;
|
||||||
|
// };
|
||||||
|
|
||||||
|
enum class SceneState : flag_t {
|
||||||
|
INITIAL = FLAG(0),
|
||||||
|
INITIALIZED = FLAG(1),
|
||||||
|
DEINITIALIZED = FLAG(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
class Scene final : public std::enable_shared_from_this<Scene> {
|
class Scene final : public std::enable_shared_from_this<Scene> {
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Game> game;
|
std::weak_ptr<Game> game;
|
||||||
std::function<void(Scene&)> sceneInitializer;
|
|
||||||
std::vector<std::shared_ptr<SceneItem>> sceneItems;
|
std::vector<std::shared_ptr<SceneItem>> sceneItems;
|
||||||
std::vector<std::shared_ptr<SceneItem>> sceneItemsToRemove;
|
std::vector<std::shared_ptr<SceneItem>> sceneItemsToRemove;
|
||||||
bool_t paused = false;
|
bool_t paused = false;
|
||||||
bool_t hasInitialized = false;
|
flag_t state = (flag_t)SceneState::INITIAL;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Event<float_t> onUnpausedUpdate;
|
Event<float_t> onUnpausedUpdate;
|
||||||
@ -36,10 +42,7 @@ namespace Dawn {
|
|||||||
*
|
*
|
||||||
* @param game Game that initialized this scene.
|
* @param game Game that initialized this scene.
|
||||||
*/
|
*/
|
||||||
Scene(
|
Scene(const std::shared_ptr<Game> &game);
|
||||||
const std::weak_ptr<Game> game,
|
|
||||||
const std::function<void(Scene&)> sceneInitializer
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stages all of the scene items on the scene.
|
* Stages all of the scene items on the scene.
|
||||||
|
@ -12,14 +12,13 @@ using namespace Dawn;
|
|||||||
|
|
||||||
void SceneComponent::init(const std::shared_ptr<SceneItem> item) {
|
void SceneComponent::init(const std::shared_ptr<SceneItem> item) {
|
||||||
assertFlagOff(
|
assertFlagOff(
|
||||||
sceneComponentState,
|
state,
|
||||||
SCENE_COMPONENT_STATE_INIT,
|
SceneComponentState::INITIALIZED,
|
||||||
"SceneComponent is already initialized!"
|
"Component already initialized before"
|
||||||
);
|
|
||||||
Flag::turnOn<uint_fast8_t>(
|
|
||||||
sceneComponentState,
|
|
||||||
SCENE_COMPONENT_STATE_INIT
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Flag::turnOn(state, SceneComponentState::INITIALIZED);
|
||||||
|
|
||||||
this->events.clear();
|
this->events.clear();
|
||||||
this->item = item;
|
this->item = item;
|
||||||
this->onInit();
|
this->onInit();
|
||||||
@ -27,33 +26,23 @@ void SceneComponent::init(const std::shared_ptr<SceneItem> item) {
|
|||||||
|
|
||||||
void SceneComponent::dispose() {
|
void SceneComponent::dispose() {
|
||||||
assertFlagOn(
|
assertFlagOn(
|
||||||
sceneComponentState,
|
state,
|
||||||
SCENE_COMPONENT_STATE_INIT,
|
SceneComponentState::INITIALIZED,
|
||||||
"SceneComponent is not initialized!"
|
"Component not initialized"
|
||||||
);
|
|
||||||
assertFlagOff(
|
|
||||||
sceneComponentState,
|
|
||||||
SCENE_COMPONENT_STATE_DISPOSED,
|
|
||||||
"SceneComponent is already disposed!"
|
|
||||||
);
|
|
||||||
Flag::turnOn<uint_fast8_t>(
|
|
||||||
sceneComponentState,
|
|
||||||
SCENE_COMPONENT_STATE_DISPOSED
|
|
||||||
);
|
);
|
||||||
|
Flag::turnOn(state, SceneComponentState::DISPOSED);
|
||||||
|
|
||||||
for(auto &event : this->events) {
|
for(auto &event : this->events) {
|
||||||
event();
|
event();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->events.clear();
|
this->events.clear();
|
||||||
this->onDispose();
|
this->onDispose();
|
||||||
this->item.reset();
|
this->item.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t SceneComponent::isInitialized() {
|
bool_t SceneComponent::isInitialized() {
|
||||||
return Flag::isOn<uint_fast8_t>(
|
return Flag::isOn(state, SceneComponentState::INITIALIZED);
|
||||||
sceneComponentState,
|
|
||||||
SCENE_COMPONENT_STATE_INIT
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SceneItem> SceneComponent::getItem() {
|
std::shared_ptr<SceneItem> SceneComponent::getItem() {
|
||||||
@ -75,14 +64,11 @@ void SceneComponent::load(const SceneComponentLoadContext &context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneComponent::~SceneComponent() {
|
SceneComponent::~SceneComponent() {
|
||||||
if(Flag::isOn<uint_fast8_t>(
|
if(Flag::isOn(state, SceneComponentState::INITIALIZED)) {
|
||||||
sceneComponentState,
|
|
||||||
SCENE_COMPONENT_STATE_INIT
|
|
||||||
)) {
|
|
||||||
assertFlagOn(
|
assertFlagOn(
|
||||||
sceneComponentState,
|
state,
|
||||||
SCENE_COMPONENT_STATE_DISPOSED,
|
SceneComponentState::DISPOSED,
|
||||||
"SceneComponent is initialized but was not properly disposed!"
|
"Component not disposed before destruction"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,9 +7,6 @@
|
|||||||
#include "dawn.hpp"
|
#include "dawn.hpp"
|
||||||
#include "assert/assert.hpp"
|
#include "assert/assert.hpp"
|
||||||
|
|
||||||
#define SCENE_COMPONENT_STATE_INIT 0x01
|
|
||||||
#define SCENE_COMPONENT_STATE_DISPOSED 0x02
|
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Game;
|
class Game;
|
||||||
class Scene;
|
class Scene;
|
||||||
@ -17,6 +14,12 @@ namespace Dawn {
|
|||||||
class SceneComponent;
|
class SceneComponent;
|
||||||
class AssetLoader;
|
class AssetLoader;
|
||||||
|
|
||||||
|
enum class SceneComponentState : flag_t {
|
||||||
|
INITIAL = FLAG(0),
|
||||||
|
INITIALIZED = FLAG(1),
|
||||||
|
DISPOSED = FLAG(2)
|
||||||
|
};
|
||||||
|
|
||||||
struct SceneComponentLoadContext {
|
struct SceneComponentLoadContext {
|
||||||
json data;
|
json data;
|
||||||
std::shared_ptr<Scene> scene;
|
std::shared_ptr<Scene> scene;
|
||||||
@ -37,7 +40,7 @@ namespace Dawn {
|
|||||||
class SceneComponent : std::enable_shared_from_this<SceneComponent> {
|
class SceneComponent : std::enable_shared_from_this<SceneComponent> {
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<SceneItem> item;
|
std::weak_ptr<SceneItem> item;
|
||||||
uint_fast8_t sceneComponentState = 0;
|
flag_t state = (flag_t)SceneComponentState::INITIAL;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::function<void()>> events;
|
std::vector<std::function<void()>> events;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "scene/SceneItem.hpp"
|
#include "scene/SceneItem.hpp"
|
||||||
#include "scene/Scene.hpp"
|
#include "scene/Scene.hpp"
|
||||||
#include "util/JSON.hpp"
|
#include "util/JSON.hpp"
|
||||||
|
#include "assert/assert.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
@ -27,12 +28,16 @@ std::shared_ptr<Scene> SceneItem::getScene() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SceneItem::init() {
|
void SceneItem::init() {
|
||||||
|
assertFlagOff(state, SceneItemState::INITIALIZED, "Already initialized.");
|
||||||
|
assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited.");
|
||||||
|
Flag::turnOn(state, SceneItemState::INITIALIZED);
|
||||||
|
|
||||||
auto sharedThis = shared_from_this();
|
auto sharedThis = shared_from_this();
|
||||||
|
|
||||||
// Loop until all components initialized...
|
// Loop until all components initialized...
|
||||||
while(true) {
|
while(true) {
|
||||||
// Create copy of the components, components may chose to add more components
|
// Create copy of the components, components may chose to add more
|
||||||
// but those sub components will not be initialized at this time.
|
// components but those sub components will not be initialized at this time.
|
||||||
auto components = this->components;
|
auto components = this->components;
|
||||||
for(auto &component : components) {
|
for(auto &component : components) {
|
||||||
if(component->isInitialized()) continue;
|
if(component->isInitialized()) continue;
|
||||||
@ -54,6 +59,10 @@ void SceneItem::init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SceneItem::deinit() {
|
void SceneItem::deinit() {
|
||||||
|
assertFlagOn(state, SceneItemState::INITIALIZED, "SceneItem not ready.");
|
||||||
|
assertFlagOff(state, SceneItemState::DEINITIALIZED, "Already deinited");
|
||||||
|
Flag::turnOn(state, SceneItemState::DEINITIALIZED);
|
||||||
|
|
||||||
// Create copy of the components, components may chose to add more components
|
// Create copy of the components, components may chose to add more components
|
||||||
// but those sub components will not be disposed at this time.
|
// but those sub components will not be disposed at this time.
|
||||||
auto components = this->components;
|
auto components = this->components;
|
||||||
@ -96,5 +105,7 @@ void SceneItem::remove() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SceneItem::~SceneItem() {
|
SceneItem::~SceneItem() {
|
||||||
this->deinit();
|
if(Flag::isOn(state, SceneItemState::INITIALIZED)) {
|
||||||
|
assertFlagOn(state, SceneItemState::DEINITIALIZED, "Not deinited");
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,6 +10,12 @@
|
|||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Scene;
|
class Scene;
|
||||||
|
|
||||||
|
enum class SceneItemState : flag_t {
|
||||||
|
INITIAL = FLAG(0),
|
||||||
|
INITIALIZED = FLAG(1),
|
||||||
|
DEINITIALIZED = FLAG(2),
|
||||||
|
};
|
||||||
|
|
||||||
class SceneItem final :
|
class SceneItem final :
|
||||||
public SceneItemTransform,
|
public SceneItemTransform,
|
||||||
public SceneItemComponents,
|
public SceneItemComponents,
|
||||||
@ -17,6 +23,7 @@ namespace Dawn {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<Scene> scene;
|
std::weak_ptr<Scene> scene;
|
||||||
|
flag_t state = (flag_t)SceneItemState::INITIAL;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<SceneItem> sceneItemComponentsSelf() override;
|
std::shared_ptr<SceneItem> sceneItemComponentsSelf() override;
|
||||||
|
@ -7,26 +7,30 @@
|
|||||||
#include "dawn.hpp"
|
#include "dawn.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
|
typedef uint_fast32_t flag_t;
|
||||||
|
|
||||||
class Flag final {
|
class Flag final {
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T, typename J>
|
||||||
static void turnOn(T &flag, const T check) {
|
static void turnOn(T &flag, const J check) {
|
||||||
flag |= check;
|
flag |= (T)check;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename J>
|
||||||
static void turnOff(T &flag, const T check) {
|
static void turnOff(T &flag, const J check) {
|
||||||
flag &= ~check;
|
flag &= ~((T)check);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename J>
|
||||||
static bool_t isOn(const T flag, const T check) {
|
static bool_t isOn(const T flag, const J check) {
|
||||||
return (flag & check) == check;
|
return (flag & (T)check) == (T)check;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename J>
|
||||||
static bool_t isOff(const T flag, const T check) {
|
static bool_t isOff(const T flag, const J check) {
|
||||||
return (flag & check) == 0;
|
return (flag & (T)check) == 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FLAG(i) ((flag_t)1 << (flag_t)i)
|
||||||
}
|
}
|
@ -21,9 +21,10 @@ glm::vec3 JSON::vec3(const json &j) {
|
|||||||
j["y"].get<float_t>(),
|
j["y"].get<float_t>(),
|
||||||
j["z"].get<float_t>()
|
j["z"].get<float_t>()
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
assertUnreachable("Invalid JSON type for vec3");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertUnreachable("Invalid JSON type for vec3");
|
||||||
|
return glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Color JSON::color(const json &j) {
|
struct Color JSON::color(const json &j) {
|
||||||
@ -71,7 +72,8 @@ struct Color JSON::color(const json &j) {
|
|||||||
return { r, g, b, a };
|
return { r, g, b, a };
|
||||||
} else if(j.type() == json::value_t::string) {
|
} else if(j.type() == json::value_t::string) {
|
||||||
return Color::fromString(j.get<std::string>());
|
return Color::fromString(j.get<std::string>());
|
||||||
} else {
|
|
||||||
assertUnreachable("Invalid JSON type for color");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertUnreachable("Invalid JSON type for color");
|
||||||
|
return COLOR_WHITE;
|
||||||
}
|
}
|
@ -12,9 +12,9 @@ Game::Game() : IGame() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void(Scene&)> Game::getInitialScene() {
|
// std::function<void(Scene&)> Game::getInitialScene() {
|
||||||
return rpgScene;
|
// return rpgScene;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void Game::initManagers() {
|
void Game::initManagers() {
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Game : public IGame {
|
class Game : public IGame {
|
||||||
protected:
|
protected:
|
||||||
std::function<void(Scene&)> getInitialScene() override;
|
// std::function<void(Scene&)> getInitialScene() override;
|
||||||
void initManagers() override;
|
void initManagers() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user