From ba9881e39d42bc60e6ebc08d60588414fc35121d Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 1 Dec 2022 22:37:42 -0800 Subject: [PATCH] Working on assets --- src/dawn/assert/assert.hpp | 1 - src/dawn/asset/Asset.hpp | 2 + src/dawn/asset/AssetManager.cpp | 68 ++++++++++++++++----- src/dawn/asset/AssetManager.hpp | 43 +++++++++++-- src/dawn/asset/assets/TextureAsset.cpp | 1 + src/dawn/asset/assets/TrueTypeAsset.cpp | 1 + src/dawn/scene/Scene.hpp | 16 +++++ src/dawn/ui/CMakeLists.txt | 1 + src/dawn/ui/UIGrid.cpp | 35 +++++++++++ src/dawn/ui/UIGrid.hpp | 41 +++++++++++++ src/dawn/util/array.hpp | 22 +++++++ src/dawnglfw/host/DawnGLFWHost.cpp | 8 +++ src/dawnpokergame/game/DawnGame.cpp | 3 +- src/dawnpokergame/scenes/TestScene.hpp | 35 +++++++---- src/dawnpokergame/ui/CMakeLists.txt | 8 +-- src/dawnpokergame/ui/PokerGameTextbox.hpp | 18 ++++-- src/dawnpokergame/ui/PokerPlayerDisplay.cpp | 62 +++++++++++++++++++ src/dawnpokergame/ui/PokerPlayerDisplay.hpp | 32 ++++++++++ 18 files changed, 355 insertions(+), 42 deletions(-) create mode 100644 src/dawn/ui/UIGrid.cpp create mode 100644 src/dawn/ui/UIGrid.hpp create mode 100644 src/dawn/util/array.hpp create mode 100644 src/dawnpokergame/ui/PokerPlayerDisplay.cpp create mode 100644 src/dawnpokergame/ui/PokerPlayerDisplay.hpp diff --git a/src/dawn/assert/assert.hpp b/src/dawn/assert/assert.hpp index 2443beea..bb02731d 100644 --- a/src/dawn/assert/assert.hpp +++ b/src/dawn/assert/assert.hpp @@ -50,7 +50,6 @@ static inline void assertTrue(bool_t x) {} * Asserts a function as being deprecated. */ void assertDeprecated(); - #else #define assertTrue assert diff --git a/src/dawn/asset/Asset.hpp b/src/dawn/asset/Asset.hpp index 22fa437f..4975969f 100644 --- a/src/dawn/asset/Asset.hpp +++ b/src/dawn/asset/Asset.hpp @@ -6,6 +6,7 @@ #pragma once #include "dawnlibs.hpp" #include "assert/assert.hpp" +#include "event/Event.hpp" namespace Dawn { class AssetManager; @@ -16,6 +17,7 @@ namespace Dawn { std::string name; uint8_t state = 0x00; bool loaded = false; + Event<> eventLoaded; /** * Create an abstract Asset object. diff --git a/src/dawn/asset/AssetManager.cpp b/src/dawn/asset/AssetManager.cpp index 6205bce5..6d668752 100644 --- a/src/dawn/asset/AssetManager.cpp +++ b/src/dawn/asset/AssetManager.cpp @@ -15,26 +15,72 @@ void AssetManager::init() { } -void AssetManager::update() { - auto it = this->assetsNotLoaded.begin(); - while(it != this->assetsNotLoaded.end()) { - auto asset = it->second; +void AssetManager::queueLoad(std::vector assets) { + vectorAppend(&this->assetsToLoad, &assets); +} + +void AssetManager::queueUnload(std::vector assets) { + vectorAppend(&this->assetsToUnload, &assets); +} + +void AssetManager::queueSwap( + std::vector newAssets, + std::vector oldAssets +) { + std::vector unload; + std::vector load; + + // Determine assets to unload. + auto itUnload = oldAssets.begin(); + while(itUnload != oldAssets.end()) { + auto inNewAssets = std::find(newAssets.begin(), newAssets.end(), *itUnload); + if(inNewAssets == oldAssets.end()) unload.push_back(*itUnload); + ++itUnload; + } + + // Determine assets to load + auto itLoad = newAssets.begin(); + while(itLoad != newAssets.end()) { + auto inOldAssets = std::find(oldAssets.begin(), oldAssets.end(), *itLoad); + if(inOldAssets == oldAssets.end()) load.push_back(*itLoad); + ++itLoad; + } + + this->queueUnload(unload); + this->queueLoad(load); +} + +void AssetManager::syncTick() { + auto it = this->assetsToLoad.begin(); + // auto it = this->assetsNotLoaded.begin(); + while(it != this->assetsToLoad.end()) { + auto asset = *it; if(asset->loaded) { - it = this->assetsNotLoaded.erase(it); + it = this->assetsToLoad.erase(it); continue; } asset->updateSync(); - asset->updateAsync(); + asset->updateAsync();//TODO: Make Async if(asset->loaded) { - it = this->assetsNotLoaded.erase(it); - this->assets[asset->name] = asset; + it = this->assetsToLoad.erase(it); continue; } ++it; } + + // auto it2 = this->assetsToUnload.begin(); + // while(it2 != this->assetsToUnload.end()) { + // ++it2; + // } +} + +void AssetManager::syncLoad() { + while(this->assetsToLoad.size() > 0) { + this->syncTick(); + } } AssetManager::~AssetManager() { @@ -43,10 +89,4 @@ AssetManager::~AssetManager() { delete it->second; ++it; } - - auto it2 = this->assetsNotLoaded.begin(); - while(it2 != this->assetsNotLoaded.end()) { - delete it2->second; - ++it2; - } } \ No newline at end of file diff --git a/src/dawn/asset/AssetManager.hpp b/src/dawn/asset/AssetManager.hpp index 323100a8..4717db15 100644 --- a/src/dawn/asset/AssetManager.hpp +++ b/src/dawn/asset/AssetManager.hpp @@ -5,13 +5,15 @@ #pragma once #include "Asset.hpp" +#include "util/array.hpp" namespace Dawn { class AssetManager { private: /** List of pointers to assets, mapped by their asset key. */ std::map assets; - std::map assetsNotLoaded; + std::vector assetsToLoad; + std::vector assetsToUnload; public: /** @@ -20,9 +22,41 @@ namespace Dawn { void init(); /** - * Ticks the asset manager for a single frame, synchronously. + * Queue a loading of a list of assets. Does not actually begin loading. + * + * @param assets Assets to load. */ - void update(); + void queueLoad(std::vector assets); + + /** + * Takes a list of lists to queue to unload. Does not immediately unload. + * + * @param assets Assets to unload. + */ + void queueUnload(std::vector assets); + + /** + * Queues load and unload based on the difference between two sets of + * assets. This is mostly used to perform a scene change. + * + * @param newAssets New list of assets to maintain. + * @param oldAssets Old list of assets to no longer maintain. + */ + void queueSwap( + std::vector newAssets, + std::vector oldAssets + ); + + /** + * Ticks the asset manager, synchronously. + */ + void syncTick(); + + /** + * Loads everything that isn't loaded, blocks the current thread until + * that has finished. + */ + void syncLoad(); /** * Creates and queue an asset to load. @@ -31,7 +65,7 @@ namespace Dawn { * @return The asset element to be loaded. */ template - T * load(std::string name) { + T * get(std::string name) { assertTrue(name.size() > 0); auto existing = this->assets.find(name); @@ -40,7 +74,6 @@ namespace Dawn { } auto asset = new T(this, name); this->assets[name] = asset; - this->assetsNotLoaded[name] = asset; return asset; } diff --git a/src/dawn/asset/assets/TextureAsset.cpp b/src/dawn/asset/assets/TextureAsset.cpp index cf882c2a..5c61e0da 100644 --- a/src/dawn/asset/assets/TextureAsset.cpp +++ b/src/dawn/asset/assets/TextureAsset.cpp @@ -24,6 +24,7 @@ void TextureAsset::updateSync() { this->texture.buffer(this->colors); this->state = 0x05; this->loaded = true; + this->eventLoaded.invoke(); } void TextureAsset::updateAsync() { diff --git a/src/dawn/asset/assets/TrueTypeAsset.cpp b/src/dawn/asset/assets/TrueTypeAsset.cpp index 73ccd8c9..18ec7cf8 100644 --- a/src/dawn/asset/assets/TrueTypeAsset.cpp +++ b/src/dawn/asset/assets/TrueTypeAsset.cpp @@ -29,6 +29,7 @@ void TrueTypeAsset::updateSync() { this->state = 0x05; this->loaded = true; + this->eventLoaded.invoke(); } void TrueTypeAsset::updateAsync() { diff --git a/src/dawn/scene/Scene.hpp b/src/dawn/scene/Scene.hpp index b99e615e..271da62a 100644 --- a/src/dawn/scene/Scene.hpp +++ b/src/dawn/scene/Scene.hpp @@ -6,6 +6,7 @@ #pragma once #include "SceneItem.hpp" #include "event/Event.hpp" +#include "asset/Asset.hpp" namespace Dawn { class DawnGame; @@ -41,6 +42,21 @@ namespace Dawn { */ SceneItem * createSceneItem(); + /** + * Returns the required assets for this scene. Assets required are meant + * to be referenced back to the loader so that special loading actions can + * be performed against them. + * + * @return List of assets required by this scene. + */ + virtual std::vector getRequiredAssets() = 0; + + /** + * Method to begin the actual staging of the scene, typically called after + * the scene has finished loading. + */ + virtual void stage() = 0; + /** * Finds an existing component on the scene (Root Level Only) that has a * component matching the given component type. Returns nullptr if no item diff --git a/src/dawn/ui/CMakeLists.txt b/src/dawn/ui/CMakeLists.txt index 247b5cad..3ae4ab2d 100644 --- a/src/dawn/ui/CMakeLists.txt +++ b/src/dawn/ui/CMakeLists.txt @@ -11,4 +11,5 @@ target_sources(${DAWN_TARGET_NAME} UILabel.cpp UISprite.cpp UIEmpty.cpp + UIGrid.cpp ) \ No newline at end of file diff --git a/src/dawn/ui/UIGrid.cpp b/src/dawn/ui/UIGrid.cpp new file mode 100644 index 00000000..0451eae7 --- /dev/null +++ b/src/dawn/ui/UIGrid.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "UIGrid.hpp" + +using namespace Dawn; + +UIGrid::UIGrid(UICanvas *canvas) : UIComponent(canvas) { +} + +void UIGrid::setSize(int32_t rows, int32_t columns) { + this->gridArea.clear(); + + this->rows = rows; + this->columns = columns; + + int32_t i, l; + l = rows * columns; + for(i = 0; i < l; i++) { + struct GridArea area; + area.uiComponent = nullptr; + this->gridArea.push_back(area); + } +} + +void UIGrid::setItem(int32_t x, int32_t y, UIComponent *comp) { + auto item = &this->gridArea[(y * this->rows) + x]; + + //Too lazy to support re setting. Need to mod setSize too + assertNull(item->uiComponent); + + item->uiComponent = comp; +} diff --git a/src/dawn/ui/UIGrid.hpp b/src/dawn/ui/UIGrid.hpp new file mode 100644 index 00000000..d596f585 --- /dev/null +++ b/src/dawn/ui/UIGrid.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "UIComponent.hpp" + +namespace Dawn { + enum GridAlign { + ALIGN_GROW, + ALIGN_CONTENT, + ALIGN_FIXED + }; + + struct GridArea { + enum GridAlignment xAlign; + enum GridAlignment yAlign; + float_t width, height; + float_t x, y; + UIComponent *uiComponent; + }; + + class UIGrid : public UIComponent { + protected: + void alignChildren(); + + public: + glm::vec2 cellPadding; + glm::vec2 cellMargin; + int32_t rows = 1; + int32_t columns = 1; + std::vector gridArea; + + UIGrid(UICanvas *canvas); + + void setSize(int32_t rows, int32_t columns); + + void setItem(int32_t row, int32_t col, UIComponent *comp); + }; +} \ No newline at end of file diff --git a/src/dawn/util/array.hpp b/src/dawn/util/array.hpp new file mode 100644 index 00000000..168905c2 --- /dev/null +++ b/src/dawn/util/array.hpp @@ -0,0 +1,22 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" +#include "assert/assert.hpp" + +namespace Dawn { + template + void vectorAppend(std::vector *list, std::vector *append) { + assertNotNull(list); + assertNotNull(append); + + auto it = append->begin(); + while(it != append->end()) { + list->push_back(*it); + ++it; + } + } +} diff --git a/src/dawnglfw/host/DawnGLFWHost.cpp b/src/dawnglfw/host/DawnGLFWHost.cpp index f5dd66d9..e4b20f96 100644 --- a/src/dawnglfw/host/DawnGLFWHost.cpp +++ b/src/dawnglfw/host/DawnGLFWHost.cpp @@ -65,6 +65,14 @@ int32_t DawnHost::init(DawnGame *game) { auto result = game->init(); if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result; + // Hard-Load the first scene assets. + if(game->scene != nullptr) { + auto assets = game->scene->getRequiredAssets(); + game->assetManager.queueLoad(assets); + game->assetManager.syncLoad(); + game->scene->stage(); + } + // Set up event listeners glfwSetWindowSizeCallback(this->data->window, &glfwOnResize); glfwSetKeyCallback(this->data->window, &glfwOnKey); diff --git a/src/dawnpokergame/game/DawnGame.cpp b/src/dawnpokergame/game/DawnGame.cpp index bb22fe5e..bf062a82 100644 --- a/src/dawnpokergame/game/DawnGame.cpp +++ b/src/dawnpokergame/game/DawnGame.cpp @@ -22,13 +22,12 @@ int32_t DawnGame::init() { this->assetManager.init(); this->renderManager.init(); - this->scene = TestScene::create(this); + this->scene = new TestScene(this); return DAWN_GAME_INIT_RESULT_SUCCESS; } int32_t DawnGame::update(float_t delta) { - this->assetManager.update(); this->inputManager.update(); this->timeManager.update(delta); diff --git a/src/dawnpokergame/scenes/TestScene.hpp b/src/dawnpokergame/scenes/TestScene.hpp index 4e979ff6..667e4f28 100644 --- a/src/dawnpokergame/scenes/TestScene.hpp +++ b/src/dawnpokergame/scenes/TestScene.hpp @@ -6,6 +6,7 @@ #pragma once #include "scene/Scene.hpp" #include "game/DawnGame.hpp" +#include "util/array.hpp" #include "scene/components/Components.hpp" #include "ui/PokerGameTextbox.hpp" #include "visualnovel/VisualNovelManager.hpp" @@ -14,34 +15,48 @@ #include "visualnovel/events/PokerBetLoopEvent.hpp" #include "visualnovel/events/PokerInitialEvent.hpp" #include "visualnovel/events/SimpleLoopEvent.hpp" +#include "ui/PokerPlayerDisplay.hpp" namespace Dawn { - class TestScene { + class TestScene : public Scene { public: - static Scene * create(DawnGame *game) { - Scene *scene; + TestScene(DawnGame *game) : Scene(game) { - scene = new Scene(game); + } + std::vector getRequiredAssets() override { + auto assMan = &this->game->assetManager; + std::vector assets; + + vectorAppend(&assets, &PokerGameTextbox::getAssets(assMan)); + + return assets; + } + + void stage() override { // Camera - auto camera = Camera::create(scene); + auto camera = Camera::create(this); camera->transform->lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0)); // UI - auto canvas = UICanvas::createCanvas(scene); + auto canvas = UICanvas::createCanvas(this); auto textbox = PokerGameTextbox::create(canvas); // VN Manager - auto vnManagerItem = scene->createSceneItem(); + auto vnManagerItem = this->createSceneItem(); auto vnManager = vnManagerItem->addComponent(); // Poker Test - auto pokerGameItem = scene->createSceneItem(); + auto pokerGameItem = this->createSceneItem(); auto pokerGame = pokerGameItem->addComponent(); for(int32_t i = 0; i < 4; i++) { - auto pokerPlayerInstance = scene->createSceneItem(); + auto pokerPlayerInstance = this->createSceneItem(); auto pokerPlayer = pokerPlayerInstance->addComponent(); + + auto uiPlayer = canvas->addElement(); + uiPlayer->setTransform(UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, glm::vec4(0, 0, 0, 0), 0); + uiPlayer->setPlayer(pokerPlayer); } auto betting = vnManager @@ -50,8 +65,6 @@ namespace Dawn { ->then(new VisualNovelTextboxEvent(vnManager, "Game Started")) ->then(new PokerInitialEvent(vnManager)) ; - - return scene; } }; } \ No newline at end of file diff --git a/src/dawnpokergame/ui/CMakeLists.txt b/src/dawnpokergame/ui/CMakeLists.txt index f6c594ab..13715854 100644 --- a/src/dawnpokergame/ui/CMakeLists.txt +++ b/src/dawnpokergame/ui/CMakeLists.txt @@ -4,7 +4,7 @@ # https://opensource.org/licenses/MIT # Sources -# target_sources(${DAWN_TARGET_NAME} -# PRIVATE -# PokerGameTextbox.cpp -# ) \ No newline at end of file +target_sources(${DAWN_TARGET_NAME} + PRIVATE + PokerPlayerDisplay.cpp +) \ No newline at end of file diff --git a/src/dawnpokergame/ui/PokerGameTextbox.hpp b/src/dawnpokergame/ui/PokerGameTextbox.hpp index ddf1624c..48de8546 100644 --- a/src/dawnpokergame/ui/PokerGameTextbox.hpp +++ b/src/dawnpokergame/ui/PokerGameTextbox.hpp @@ -11,12 +11,20 @@ namespace Dawn { class PokerGameTextbox { public: - static VisualNovelTextbox * create(UICanvas *canvas) { - auto textbox = canvas->addElement(); - - auto assetFont = canvas->getGame()->assetManager.load("truetype_ark"); - auto assetTexture = canvas->getGame()->assetManager.load("texture_test"); + static std::vector getAssets(AssetManager *man) { + return std::vector{ + man->get("truetype_ark"), + man->get("texture_test") + }; + } + static VisualNovelTextbox * create(UICanvas *canvas) { + auto assMan = &canvas->getGame()->assetManager; + + auto assetFont = assMan->get("truetype_ark"); + auto assetTexture = assMan->get("texture_test"); + + auto textbox = canvas->addElement(); textbox->setBorder(&assetTexture->texture, glm::vec2(16, 16)); textbox->setFont(&assetFont->font); textbox->setFontSize(40); diff --git a/src/dawnpokergame/ui/PokerPlayerDisplay.cpp b/src/dawnpokergame/ui/PokerPlayerDisplay.cpp new file mode 100644 index 00000000..3340f192 --- /dev/null +++ b/src/dawnpokergame/ui/PokerPlayerDisplay.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "PokerPlayerDisplay.hpp" +#include "game/DawnGame.hpp" + +using namespace Dawn; + +void PokerPlayerDisplay::updatePositions() { + UIEmpty::updatePositions(); + + this->labelChips.setTransform( + UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_START, + glm::vec4(0, this->labelName.getHeight(), 0, 0), + 0 + ); +} + +PokerPlayerDisplay::PokerPlayerDisplay(UICanvas *canvas) : + UIEmpty(canvas), + labelName(canvas), + labelChips(canvas) +{ + this->font = canvas->getGame()->assetManager.get("truetype_ark"); + + this->addChild(&this->labelName); + this->labelName.setFont(&this->font->font); + this->labelName.setFontSize(40); + this->labelName.setTransform( + UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_START, + glm::vec4(0, 0, 0, 0), + 0.0f + ); + + this->addChild(&this->labelChips); + this->labelChips.setFont(&this->font->font); + this->labelChips.setFontSize(40); + + this->font->eventLoaded.addListener(this, &PokerPlayerDisplay::onFontLoaded); +} + +void PokerPlayerDisplay::setPlayer(PokerPlayer *player) { + assertNull(this->player); + this->player = player; + + this->labelName.setText("Player"); + this->labelChips.setText("Chips"); + this->updatePositions(); +} + +void PokerPlayerDisplay::onFontLoaded() { + this->labelName.setFont(&this->font->font); + this->labelChips.setFont(&this->font->font); + + this->updatePositions(); +} + +PokerPlayerDisplay::~PokerPlayerDisplay() { + this->font->eventLoaded.removeListener(this, &PokerPlayerDisplay::onFontLoaded); +} \ No newline at end of file diff --git a/src/dawnpokergame/ui/PokerPlayerDisplay.hpp b/src/dawnpokergame/ui/PokerPlayerDisplay.hpp new file mode 100644 index 00000000..64346f5a --- /dev/null +++ b/src/dawnpokergame/ui/PokerPlayerDisplay.hpp @@ -0,0 +1,32 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "ui/UILabel.hpp" +#include "ui/UIEmpty.hpp" +#include "poker/PokerPlayer.hpp" +#include "asset/assets/TrueTypeAsset.hpp" + +namespace Dawn { + class PokerPlayerDisplay : public UIEmpty { + private: + void onFontLoaded(); + + protected: + PokerPlayer *player = nullptr; + UILabel labelName; + UILabel labelChips; + TrueTypeAsset *font; + + void updatePositions() override; + + public: + PokerPlayerDisplay(UICanvas *canvas); + + void setPlayer(PokerPlayer *player); + + ~PokerPlayerDisplay(); + }; +} \ No newline at end of file