From 4dbd9c45212d161df2525ff9330c6dadcb0f933d Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 27 Feb 2023 23:36:03 -0800 Subject: [PATCH] Started upgrading things to new state --- src/dawn/display/RenderPipeline.cpp | 2 +- src/dawn/scene/components/display/Camera.cpp | 117 +++++++----- src/dawn/scene/components/display/Camera.hpp | 41 ++--- .../components/display/PixelPerfectCamera.cpp | 131 +++++++------ .../components/display/PixelPerfectCamera.hpp | 65 ++++--- .../display/SimpleRenderTargetQuad.cpp | 70 ++++--- .../display/SimpleRenderTargetQuad.hpp | 73 ++++---- .../scene/components/display/TiledSprite.hpp | 174 +++++++++--------- src/dawn/scene/debug/SceneDebugLine.cpp | 2 +- src/dawn/state/CMakeLists.txt | 5 - src/dawn/state/State.hpp | 52 +++++- src/dawn/state/StateEvent.hpp | 29 ++- src/dawn/state/StateOwner.cpp | 8 - src/dawn/state/StateOwner.hpp | 114 ------------ src/dawn/state/StateProperty.cpp | 8 - src/dawn/state/StateProperty.hpp | 47 +++-- .../display/shader/SimpleTexturedShader.cpp | 2 +- .../components/TicTacToeTile.cpp | 9 +- src/dawntictactoe/scenes/TicTacToeScene.hpp | 2 +- 19 files changed, 456 insertions(+), 495 deletions(-) delete mode 100644 src/dawn/state/StateOwner.cpp delete mode 100644 src/dawn/state/StateOwner.hpp delete mode 100644 src/dawn/state/StateProperty.cpp diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp index 46c593ed..83807ed6 100644 --- a/src/dawn/display/RenderPipeline.cpp +++ b/src/dawn/display/RenderPipeline.cpp @@ -138,7 +138,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) { switch(canvas->drawType) { case UI_DRAW_TYPE_WORLD_ABSOLUTE: - projection = camera->projection; + projection = camera->getProjection(); view = camera->transform->getWorldTransform(); model = canvas->transform->getWorldTransform(); break; diff --git a/src/dawn/scene/components/display/Camera.cpp b/src/dawn/scene/components/display/Camera.cpp index 3985899f..d1228660 100644 --- a/src/dawn/scene/components/display/Camera.cpp +++ b/src/dawn/scene/components/display/Camera.cpp @@ -9,57 +9,54 @@ using namespace Dawn; Camera::Camera(SceneItem *item) : - SceneItemComponent(item) + SceneItemComponent(item), + renderTarget(nullptr), + fov(0.785398f),// 45 degrees, + type(CAMERA_TYPE_PERSPECTIVE), + orthoLeft(0.0f), + orthoRight(1.0f), + orthoBottom(0.0f), + orthoTop(1.0f), + clipNear(0.001f), + clipFar(50.0f) { - this->getRenderTarget()->eventRenderTargetResized.addListener( - this, &Camera::onRenderTargetResize - ); } -void Camera::updateProjection() { - switch(this->type) { - case CAMERA_TYPE_ORTHONOGRAPHIC: - this->projection = glm::ortho( - this->orthoLeft, - this->orthoRight, - this->orthoBottom, - this->orthoTop, - this->clipNear, - this->clipFar - ); - break; +glm::mat4 Camera::getProjection() { + if(this->projectionNeedsUpdating) { + switch(this->type) { + case CAMERA_TYPE_ORTHONOGRAPHIC: + this->projection = glm::ortho( + (float_t)this->orthoLeft, + (float_t)this->orthoRight, + (float_t)this->orthoBottom, + (float_t)this->orthoTop, + (float_t)this->clipNear, + (float_t)this->clipFar + ); + break; - case CAMERA_TYPE_PERSPECTIVE: - this->projection = glm::perspective( - this->fov, - this->getAspect(), - this->clipNear, - this->clipFar - ); - break; + case CAMERA_TYPE_PERSPECTIVE: + this->projection = glm::perspective( + (float_t)this->fov, + this->getAspect(), + (float_t)this->clipNear, + (float_t)this->clipFar + ); + break; + } + this->projectionNeedsUpdating = false; } + + return this->projection; } RenderTarget * Camera::getRenderTarget() { - if(this->target == nullptr) { + auto v = this->renderTarget; + if(this->renderTarget == nullptr) { return this->getGame()->renderManager.getBackBuffer(); } - return this->target; -} - -void Camera::setRenderTarget(RenderTarget *renderTarget) { - if(renderTarget == this->target) return; - this->getRenderTarget()->eventRenderTargetResized.removeListener( - this, &Camera::onRenderTargetResize - ); - this->target = renderTarget; - this->getRenderTarget()->eventRenderTargetResized.addListener( - this, &Camera::onRenderTargetResize - ); - this->updateProjection(); - this->eventRenderTargetResized.invoke( - renderTarget->getWidth(), renderTarget->getHeight() - ); + return (RenderTarget*)this->renderTarget; } float_t Camera::getAspect() { @@ -80,12 +77,46 @@ glm::vec3 Camera::getRayDirectionFromScreenSpace(glm::vec2 screenSpace) { } void Camera::onStart() { - this->updateProjection(); + // Render Target + useEffect(renderTarget, [&]{ + if(renderTarget.previous != nullptr) { + renderTarget.previous->eventRenderTargetResized.removeListener( + this, &Camera::onRenderTargetResize + ); + } + + this->projectionNeedsUpdating = true; + auto rt = this->getRenderTarget(); + rt->eventRenderTargetResized.addListener( + this, &Camera::onRenderTargetResize + ); + this->eventRenderTargetResized.invoke( + rt->getWidth(), rt->getHeight() + ); + this->event2RenderTargetResized.invoke(rt->getWidth(), rt->getHeight()); + }); + + // All regular properties. + auto cbUpdateProj = [&]{ + this->projectionNeedsUpdating = true; + }; + + useEffect(fov, cbUpdateProj); + useEffect(type, cbUpdateProj); + useEffect(orthoLeft, cbUpdateProj); + useEffect(orthoRight, cbUpdateProj); + useEffect(orthoBottom, cbUpdateProj); + useEffect(orthoTop, cbUpdateProj); + useEffect(clipNear, cbUpdateProj); + useEffect(clipFar, cbUpdateProj); + + getRenderTarget()->eventRenderTargetResized.addListener(this, &Camera::onRenderTargetResize); } void Camera::onRenderTargetResize(RenderTarget *target, float_t w, float_t h) { - this->updateProjection(); + this->projectionNeedsUpdating = true; this->eventRenderTargetResized.invoke(w, h); + this->event2RenderTargetResized.invoke(w, h); } void Camera::onDispose() { diff --git a/src/dawn/scene/components/display/Camera.hpp b/src/dawn/scene/components/display/Camera.hpp index 61a01a2a..0afdc432 100644 --- a/src/dawn/scene/components/display/Camera.hpp +++ b/src/dawn/scene/components/display/Camera.hpp @@ -17,34 +17,32 @@ namespace Dawn { class Camera : public SceneItemComponent { protected: - RenderTarget *target = nullptr; + bool_t projectionNeedsUpdating = true; + glm::mat4 projection; void onRenderTargetResize(RenderTarget *target, float_t w, float_t h); public: - Event eventRenderTargetResized; - static Camera * create(Scene *scene) { auto item = scene->createSceneItem(); auto cam = item->addComponent(); return cam; } - glm::mat4 projection; + StateProperty renderTarget; + StateProperty fov; + StateProperty type; - // Perspective - enum CameraType type = CAMERA_TYPE_PERSPECTIVE; - float_t fov = 0.785398f;// 45 degrees + StateProperty orthoLeft; + StateProperty orthoRight; + StateProperty orthoBottom; + StateProperty orthoTop; - // Ortho - float_t orthoLeft = 0.0f; - float_t orthoRight = 1.0f; - float_t orthoBottom = 0.0f; - float_t orthoTop = 1.0f; + StateProperty clipNear; + StateProperty clipFar; - // Shared - float_t clipNear = 0.001f; - float_t clipFar = 50.0f; + Event eventRenderTargetResized; + StateEvent event2RenderTargetResized; /** * Create a new Camera Component. @@ -54,9 +52,11 @@ namespace Dawn { Camera(SceneItem *item); /** - * Updates the projection matrix. + * Returns the current projection matrix. + * + * @return Projection matrix for this camera. */ - void updateProjection(); + glm::mat4 getProjection(); /** * Returns the intended render target for this camera to render to, will @@ -66,13 +66,6 @@ namespace Dawn { */ RenderTarget * getRenderTarget(); - /** - * Updates the render target for the camera to use. - * - * @param renderTarget Render target for this camera to draw to. - */ - void setRenderTarget(RenderTarget *renderTarget); - /** * Returs the aspect ratio of the camera. * diff --git a/src/dawn/scene/components/display/PixelPerfectCamera.cpp b/src/dawn/scene/components/display/PixelPerfectCamera.cpp index 5bb372a9..8edc8139 100644 --- a/src/dawn/scene/components/display/PixelPerfectCamera.cpp +++ b/src/dawn/scene/components/display/PixelPerfectCamera.cpp @@ -1,68 +1,65 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "PixelPerfectCamera.hpp" -#include "game/DawnGame.hpp" - -using namespace Dawn; - -PixelPerfectCamera::PixelPerfectCamera(SceneItem *i) : SceneItemComponent(i) { - -} - -std::vector PixelPerfectCamera::getDependencies() { - return std::vector{ - (this->camera = this->item->getComponent()) - }; -} - -void PixelPerfectCamera::onRenderTargetResized(float_t w, float_t h) { - this->updateDimensions(); -} - -void PixelPerfectCamera::updateDimensions() { - float_t w, h; - assertNotNull(this->camera); - - auto target = this->camera->getRenderTarget(); - switch(this->camera->type) { - case CAMERA_TYPE_ORTHONOGRAPHIC: - w = target->getWidth() / 2.0f / this->scale; - h = target->getHeight() / 2.0f / this->scale; - camera->orthoLeft = -w; - camera->orthoRight = w; - camera->orthoTop = h; - camera->orthoBottom = -h; - camera->updateProjection(); - break; - - case CAMERA_TYPE_PERSPECTIVE: - this->transform->lookAtPixelPerfect( - glm::vec3(0, 0, 0), - glm::vec3(0, 0, 0), - target->getHeight() / this->scale, - this->camera->fov - ); - // this->transform->lookAt(glm::vec3(360, 360, 360), glm::vec3(0, 0, 0)); - break; - - default: - assertUnreachable(); - } -} - -void PixelPerfectCamera::onStart() { - assertNotNull(this->camera); - this->updateDimensions(); - camera->eventRenderTargetResized.addListener( - this, &PixelPerfectCamera::onRenderTargetResized - ); -} - -void PixelPerfectCamera::onDispose() { - camera->eventRenderTargetResized.removeListener( - this, &PixelPerfectCamera::onRenderTargetResized - ); +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "PixelPerfectCamera.hpp" +#include "game/DawnGame.hpp" + +using namespace Dawn; + +PixelPerfectCamera::PixelPerfectCamera(SceneItem *i) : + SceneItemComponent(i), + scale(1.0f) +{ + +} + +std::vector PixelPerfectCamera::getDependencies() { + return std::vector{ + (this->camera = this->item->getComponent()) + }; +} + +void PixelPerfectCamera::updateDimensions() { + float_t w, h; + assertNotNull(this->camera); + + auto target = this->camera->getRenderTarget(); + switch(this->camera->type) { + case CAMERA_TYPE_ORTHONOGRAPHIC: + w = target->getWidth() / 2.0f / (float_t)this->scale; + h = target->getHeight() / 2.0f / (float_t)this->scale; + camera->orthoLeft = -w; + camera->orthoRight = w; + camera->orthoTop = h; + camera->orthoBottom = -h; + break; + + case CAMERA_TYPE_PERSPECTIVE: + this->transform->lookAtPixelPerfect( + glm::vec3(0, 0, 0), + glm::vec3(0, 0, 0), + target->getHeight() / this->scale, + this->camera->fov + ); + // this->transform->lookAt(glm::vec3(360, 360, 360), glm::vec3(0, 0, 0)); + break; + + default: + assertUnreachable(); + } +} + +void PixelPerfectCamera::onStart() { + assertNotNull(this->camera); + this->updateDimensions(); + + useEvent(this->camera->event2RenderTargetResized, [&](float_t w, float_t h){ + this->updateDimensions(); + }); + + useEffect(scale, [&]{ + this->updateDimensions(); + }); } \ No newline at end of file diff --git a/src/dawn/scene/components/display/PixelPerfectCamera.hpp b/src/dawn/scene/components/display/PixelPerfectCamera.hpp index 42cdd588..4da075e3 100644 --- a/src/dawn/scene/components/display/PixelPerfectCamera.hpp +++ b/src/dawn/scene/components/display/PixelPerfectCamera.hpp @@ -1,35 +1,32 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "Camera.hpp" - -namespace Dawn { - class PixelPerfectCamera : public SceneItemComponent { - protected: - Camera *camera = nullptr; - /** Event for when the render target is resized. */ - void onRenderTargetResized(float_t w, float_t h); - - /** - * Updates the underlying camera's projection information. - */ - void updateDimensions(); - - public: - float_t scale = 1.0f; - - /** - * Create a new PixelPerfectCamera Component. - * - * @param item Item that this component belongs to. - */ - PixelPerfectCamera(SceneItem *item); - - std::vector getDependencies() override; - void onStart() override; - void onDispose() override; - }; +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "Camera.hpp" + +namespace Dawn { + class PixelPerfectCamera : public SceneItemComponent { + protected: + Camera *camera = nullptr; + + /** + * Updates the underlying camera's projection information. + */ + void updateDimensions(); + + public: + StateProperty scale; + + /** + * Create a new PixelPerfectCamera Component. + * + * @param item Item that this component belongs to. + */ + PixelPerfectCamera(SceneItem *item); + + std::vector getDependencies() override; + void onStart() override; + }; } \ No newline at end of file diff --git a/src/dawn/scene/components/display/SimpleRenderTargetQuad.cpp b/src/dawn/scene/components/display/SimpleRenderTargetQuad.cpp index 42c8ce8f..94373399 100644 --- a/src/dawn/scene/components/display/SimpleRenderTargetQuad.cpp +++ b/src/dawn/scene/components/display/SimpleRenderTargetQuad.cpp @@ -8,7 +8,8 @@ using namespace Dawn; SimpleRenderTargetQuad::SimpleRenderTargetQuad(SceneItem *i) : - SceneItemComponent(i) + SceneItemComponent(i), + renderTarget(nullptr) { } @@ -16,36 +17,19 @@ void SimpleRenderTargetQuad::onRenderTargetResized( RenderTarget *target, float_t w, float_t h ) { assertTrue(target == this->renderTarget); - // Update mesh + QuadMesh::bufferQuadMesh( &this->meshHost->mesh, glm::vec2(0, 0), glm::vec2(0, 0), - glm::vec2(w, h), glm::vec2(1, 1), + glm::vec2( + ((RenderTarget*)this->renderTarget)->getWidth(), + ((RenderTarget*)this->renderTarget)->getHeight() + ), + glm::vec2(1, 1), 0, 0 ); } - -void SimpleRenderTargetQuad::setRenderTarget(RenderTarget *rt) { - assertTrue(rt != this->renderTarget); - - // Remove old event listener - if(this->renderTarget != nullptr) { - this->renderTarget->eventRenderTargetResized.removeListener( - this, &SimpleRenderTargetQuad::onRenderTargetResized - ); - } - - this->renderTarget = rt; - - // Add new event listener. - if(rt != nullptr) { - rt->eventRenderTargetResized.addListener( - this, &SimpleRenderTargetQuad::onRenderTargetResized - ); - } -} - std::vector SimpleRenderTargetQuad::getDependencies() { return std::vector{ (this->meshHost = this->item->getComponent()) @@ -57,15 +41,43 @@ void SimpleRenderTargetQuad::onStart() { // Create quad mesh this->meshHost->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); + + useEffect(this->renderTarget, [&]{ + if(this->renderTarget.previous != nullptr) { + this->renderTarget.previous->eventRenderTargetResized.addListener( + this, &SimpleRenderTargetQuad::onRenderTargetResized + ); + } + + if(this->renderTarget == nullptr) return; + + // Update mesh + QuadMesh::bufferQuadMesh( + &this->meshHost->mesh, + glm::vec2(0, 0), glm::vec2(0, 0), + glm::vec2( + ((RenderTarget*)this->renderTarget)->getWidth(), + ((RenderTarget*)this->renderTarget)->getHeight() + ), + glm::vec2(1, 1), + 0, 0 + ); + + ((RenderTarget*)this->renderTarget)->eventRenderTargetResized.addListener( + this, &SimpleRenderTargetQuad::onRenderTargetResized + ); + }); // Perform first resize. if(this->renderTarget != nullptr) { QuadMesh::bufferQuadMesh( &this->meshHost->mesh, - glm::vec2(0, 0), - glm::vec2(0, 0), - glm::vec2(this->renderTarget->getWidth(), this->renderTarget->getHeight()), - glm::vec2(1,1), + glm::vec2(0, 0), glm::vec2(0, 0), + glm::vec2( + ((RenderTarget*)this->renderTarget)->getWidth(), + ((RenderTarget*)this->renderTarget)->getHeight() + ), + glm::vec2(1, 1), 0, 0 ); } @@ -73,7 +85,7 @@ void SimpleRenderTargetQuad::onStart() { void SimpleRenderTargetQuad::onDispose() { if(this->renderTarget != nullptr) { - this->renderTarget->eventRenderTargetResized.removeListener( + ((RenderTarget*)this->renderTarget)->eventRenderTargetResized.removeListener( this, &SimpleRenderTargetQuad::onRenderTargetResized ); } diff --git a/src/dawn/scene/components/display/SimpleRenderTargetQuad.hpp b/src/dawn/scene/components/display/SimpleRenderTargetQuad.hpp index 8ba55352..d0c2535b 100644 --- a/src/dawn/scene/components/display/SimpleRenderTargetQuad.hpp +++ b/src/dawn/scene/components/display/SimpleRenderTargetQuad.hpp @@ -1,41 +1,34 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "scene/components/display/MeshHost.hpp" -#include "display/RenderTarget.hpp" -#include "display/mesh/QuadMesh.hpp" - -namespace Dawn { - class SimpleRenderTargetQuad : public SceneItemComponent { - protected: - MeshHost *meshHost = nullptr; - RenderTarget *renderTarget = nullptr; - - void onRenderTargetResized(RenderTarget *target, float_t w, float_t h); - - public: - /** - * Creates a SimpleRenderTargetQuad scene item component. This component - * will update the attached MeshHost any time the render target provided - * is updated / resized. - * - * @param item Item that this component is attached to. - */ - SimpleRenderTargetQuad(SceneItem *item); - - /** - * Sets the render target to use for this quad. Can be set to nullptr when - * you no longer wish to listen for resize events. - * - * @param rt Render target to attach to. - */ - void setRenderTarget(RenderTarget *rt); - - std::vector getDependencies() override; - void onStart() override; - void onDispose() override; - }; +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/components/display/MeshHost.hpp" +#include "display/RenderTarget.hpp" +#include "display/mesh/QuadMesh.hpp" + +namespace Dawn { + class SimpleRenderTargetQuad : public SceneItemComponent { + protected: + MeshHost *meshHost = nullptr; + + void onRenderTargetResized(RenderTarget *target, float_t w, float_t h); + + public: + StateProperty renderTarget; + + /** + * Creates a SimpleRenderTargetQuad scene item component. This component + * will update the attached MeshHost any time the render target provided + * is updated / resized. + * + * @param item Item that this component is attached to. + */ + SimpleRenderTargetQuad(SceneItem *item); + + std::vector getDependencies() override; + void onStart() override; + void onDispose() override; + }; } \ No newline at end of file diff --git a/src/dawn/scene/components/display/TiledSprite.hpp b/src/dawn/scene/components/display/TiledSprite.hpp index e61aa4c7..1022c9c4 100644 --- a/src/dawn/scene/components/display/TiledSprite.hpp +++ b/src/dawn/scene/components/display/TiledSprite.hpp @@ -1,88 +1,88 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "scene/SceneItemComponent.hpp" -#include "scene/components/display/MeshRenderer.hpp" -#include "scene/components/display/MeshHost.hpp" -#include "display/mesh/QuadMesh.hpp" -#include "display/Tileset.hpp" - -#define TILED_SPRITE_FLIP_Y FLAG_DEFINE(0) -#define TILED_SPRITE_FLIP_X FLAG_DEFINE(1) - -namespace Dawn { - class TiledSprite : public SceneItemComponent { - protected: - MeshHost *host = nullptr; - Tileset *tileset = nullptr; - flag_t flipState = TILED_SPRITE_FLIP_Y; - int32_t tileIndex = -1; - glm::vec2 xy0 = glm::vec2(0, 0); - glm::vec2 xy1 = glm::vec2(1, 1); - - glm::vec2 getUV0(); - glm::vec2 getUV1(); - - public: - TiledSprite(SceneItem *item); - - std::vector getDependencies() override; - void onStart() override; - - /** - * Sets which tileset to use for this sprite. - * - * @param tileset Tileset to use. - */ - void setTileset(Tileset *tileset); - - /** - * Sets the tileset for the sprite, and autosizes the sprite based on - * this tileset. - * - * @param gridTileset Tileset to use. - * @param center The center offset of the sprite. - */ - void setTilesetAndSize(TilesetGrid *gridTileset, glm::vec2 center); - - /** - * Sets the tileset for the sprite, and autosizes the sprite based on - * this tileset. This will put the sprite centered on its origin. - * - * @param gridTileset Tileset to use. - */ - void setTilesetAndSize(TilesetGrid *gridTileset); - - /** - * Updates the selected tile. - * - * @param tile Tile to use. - */ - void setTile(int32_t tile); - - /** - * Adjust how the sprite is flippxed. - * - * @param flippedState Flipped axis flags. - */ - void setFlippedState(flag_t flippedState); - - /** - * Sets the dimensions of this tiled sprite. - * - * @param size Size of the sprite. - * @param center Negative center offset. - */ - void setSize(glm::vec2 size, glm::vec2 center); - - /** - * Sets the size of this sprite. This will center the sprite on its origin - * - * @param size Size of the sprite. - */ - void setSize(glm::vec2 size); - }; +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/SceneItemComponent.hpp" +#include "scene/components/display/MeshRenderer.hpp" +#include "scene/components/display/MeshHost.hpp" +#include "display/mesh/QuadMesh.hpp" +#include "display/Tileset.hpp" + +#define TILED_SPRITE_FLIP_Y FLAG_DEFINE(0) +#define TILED_SPRITE_FLIP_X FLAG_DEFINE(1) + +namespace Dawn { + class TiledSprite : public SceneItemComponent { + protected: + MeshHost *host = nullptr; + Tileset *tileset = nullptr; + flag_t flipState = TILED_SPRITE_FLIP_Y; + int32_t tileIndex = -1; + glm::vec2 xy0 = glm::vec2(0, 0); + glm::vec2 xy1 = glm::vec2(1, 1); + + glm::vec2 getUV0(); + glm::vec2 getUV1(); + + public: + TiledSprite(SceneItem *item); + + std::vector getDependencies() override; + void onStart() override; + + /** + * Sets which tileset to use for this sprite. + * + * @param tileset Tileset to use. + */ + void setTileset(Tileset *tileset); + + /** + * Sets the tileset for the sprite, and autosizes the sprite based on + * this tileset. + * + * @param gridTileset Tileset to use. + * @param center The center offset of the sprite. + */ + void setTilesetAndSize(TilesetGrid *gridTileset, glm::vec2 center); + + /** + * Sets the tileset for the sprite, and autosizes the sprite based on + * this tileset. This will put the sprite centered on its origin. + * + * @param gridTileset Tileset to use. + */ + void setTilesetAndSize(TilesetGrid *gridTileset); + + /** + * Updates the selected tile. + * + * @param tile Tile to use. + */ + void setTile(int32_t tile); + + /** + * Adjust how the sprite is flippxed. + * + * @param flippedState Flipped axis flags. + */ + void setFlippedState(flag_t flippedState); + + /** + * Sets the dimensions of this tiled sprite. + * + * @param size Size of the sprite. + * @param center Negative center offset. + */ + void setSize(glm::vec2 size, glm::vec2 center); + + /** + * Sets the size of this sprite. This will center the sprite on its origin + * + * @param size Size of the sprite. + */ + void setSize(glm::vec2 size); + }; } \ No newline at end of file diff --git a/src/dawn/scene/debug/SceneDebugLine.cpp b/src/dawn/scene/debug/SceneDebugLine.cpp index e3c71fbc..b543d6a4 100644 --- a/src/dawn/scene/debug/SceneDebugLine.cpp +++ b/src/dawn/scene/debug/SceneDebugLine.cpp @@ -25,7 +25,7 @@ struct ShaderPassItem SceneDebugLine::createShaderItem( item.colorValues[shader->program.paramColor] = this->color; item.matrixValues[shader->program.paramModel] = this->transform; item.matrixValues[shader->program.paramView] = camera->transform->getWorldTransform(); - item.matrixValues[shader->program.paramProjection] = camera->projection; + item.matrixValues[shader->program.paramProjection] = camera->getProjection(); item.boolValues[shader->program.paramHasTexture] = false; auto i = *lineIndex; diff --git a/src/dawn/state/CMakeLists.txt b/src/dawn/state/CMakeLists.txt index b109d2e8..8a3c0aee 100644 --- a/src/dawn/state/CMakeLists.txt +++ b/src/dawn/state/CMakeLists.txt @@ -4,8 +4,3 @@ # https://opensource.org/licenses/MIT # Sources -target_sources(${DAWN_TARGET_NAME} - PRIVATE - StateOwner.cpp - StateProperty.cpp -) \ No newline at end of file diff --git a/src/dawn/state/State.hpp b/src/dawn/state/State.hpp index 41a88719..b6308caf 100644 --- a/src/dawn/state/State.hpp +++ b/src/dawn/state/State.hpp @@ -4,7 +4,53 @@ // https://opensource.org/licenses/MIT #pragma once - #include "StateEvent.hpp" -#include "StateOwner.hpp" -#include "StateProperty.hpp" \ No newline at end of file +#include "StateProperty.hpp" + +namespace Dawn { + class StateOwner { + private: + std::vector eventsSubscribed; + + public: + /** + * Listen for changees to a state property and involke the provided func + * when the value is changed. + * + * @tparam V The type of the state property. + * @param property Property to listen for affect changees to. + * @param fn The callback to be invoked when the state value changes. + */ + template + void useEffect( + StateProperty &property, + const std::function &fn + ) { + property._effectListners.push_back(fn); + } + + /** + * Listen for when an event is invoked by a state event. This is intended + * to allow for cross-state-owner communication in a simple and effective + * way. + * + * @tparam F The type of the callback function. + * @tparam A The arguments from the state event that are calledback. + * @param event The event that is being subscribed to. + * @param fn The function to be inokved on event trigger. + */ + template + void useEvent(StateEvent &event, F fn) { + event._eventListeners[this].push_back(fn); + this->eventsSubscribed.push_back(&event); + } + + ~StateOwner() { + auto it = this->eventsSubscribed.begin(); + while(it != this->eventsSubscribed.end()) { + (*it)->_stateOwnerDestroyed(this); + ++it; + } + } + }; +} \ No newline at end of file diff --git a/src/dawn/state/StateEvent.hpp b/src/dawn/state/StateEvent.hpp index 6aa72dff..753b5ba6 100644 --- a/src/dawn/state/StateEvent.hpp +++ b/src/dawn/state/StateEvent.hpp @@ -9,25 +9,38 @@ namespace Dawn { class StateOwner; + class IStateEvent { + protected: + virtual void _stateOwnerDestroyed(StateOwner *owner) = 0; + + friend class StateOwner; + }; + template - class StateEvent { - private: - std::vector> listeners; + class StateEvent : public IStateEvent { + protected: + void _stateOwnerDestroyed(StateOwner *owner) override { + this->_eventListeners.erase(owner); + } public: + std::map>> _eventListeners; + /** * Invokes the event and emits to all of the listeners. * * @param args Arguments for this event to pass to the listeners. */ void invoke(A... args) { - auto itListeners = this->listeners.begin(); - while(itListeners != this->listeners.end()) { - (*itListeners)(args...); + auto itListeners = this->_eventListeners.begin(); + while(itListeners != this->_eventListeners.end()) { + auto itLists = itListeners->second.begin(); + while(itLists != itListeners->second.end()) { + (*itLists)(args...); + ++itLists; + } ++itListeners; } } - - friend class StateOwner; }; } \ No newline at end of file diff --git a/src/dawn/state/StateOwner.cpp b/src/dawn/state/StateOwner.cpp deleted file mode 100644 index b519d69f..00000000 --- a/src/dawn/state/StateOwner.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "State.hpp" - -using namespace Dawn; diff --git a/src/dawn/state/StateOwner.hpp b/src/dawn/state/StateOwner.hpp deleted file mode 100644 index 8668e402..00000000 --- a/src/dawn/state/StateOwner.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "StateEvent.hpp" - -namespace Dawn { - template - class StateProperty; - - class StateOwner { - private: - std::map>> effectListeners; - std::vector> stateUpdateListeners; - - public: - /** - * Creates a new state property and listens for its change. - * - * @tparam V The type of the state that is held. - * @param initial The initial value of this state. - * @return The state that can then be listened for. - */ - template - StateProperty useState(V initial) { - auto property = StateProperty(); - property.value = initial; - property.owner = this; - return property; - } - - /** - * Listen for changees to a state property and involke the provided func - * when the value is changed. - * - * @tparam V The type of the state property. - * @param property Property to listen for affect changees to. - * @param fn The callback to be invoked when the state value changes. - */ - template - void useEffect(StateProperty &property, const std::function &fn) { - assertFalse(property.owner == this); - this->effectListeners[(void*)&property].push_back(fn); - } - - /** - * Listen for changes to any single state property managed by this state - * owner. - * - * @param fn Function to be invoked when any state property is updated. - */ - void useStateUpdated(const std::function &fn) { - this->stateUpdateListeners.push_back(fn); - } - - /** - * Listen for when an event is invoked by a state event. This is intended - * to allow for cross-state-owner communication in a simple and effective - * way. - * - * @tparam A The arguments from the state event that are calledback. - * @param event The event that is being subscribed to. - * @param fn The function to be inokved on event trigger. - */ - template - void useEvent(StateEvent &event, const std::function &fn) { - event.listeners.push_back(fn); - } - - /** - * Internal method (that has to be exposed) to listen for changes for when - * a state property that belongs to this state owner is updated. - * - * @tparam V The value type of the state property. - * @param prop The property that has its value changed in question. - * @param n The new, current value of the property. - * @param o The old, previous value of the property. - */ - template - void _statePropertyUpdated(StateProperty *prop, V n, V o) { - auto eff = &this->effectListeners[prop]; - - auto itEff = eff->begin(); - while(itEff != eff->end()) { - (*itEff)(); - ++itEff; - } - - auto itUpdate = this->stateUpdateListeners.begin(); - while(itUpdate != this->stateUpdateListeners.end()) { - (*itUpdate)(); - ++itUpdate; - } - } - - /** - * Internal method to listen for when a state property is disposed or - * destroyed so that it can be completely removed from this state owner. - * - * @tparam V Value type. - * @param prop Property that was destroyed. - */ - template - void _statePropertyDestroyed(StateProperty *prop) { - this->effectListeners.erase((void*)prop); - } - - virtual ~StateOwner() { - - } - }; -} \ No newline at end of file diff --git a/src/dawn/state/StateProperty.cpp b/src/dawn/state/StateProperty.cpp deleted file mode 100644 index 4a2c1df7..00000000 --- a/src/dawn/state/StateProperty.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "State.hpp" - -using namespace Dawn; \ No newline at end of file diff --git a/src/dawn/state/StateProperty.hpp b/src/dawn/state/StateProperty.hpp index f41bbaf6..3b83c319 100644 --- a/src/dawn/state/StateProperty.hpp +++ b/src/dawn/state/StateProperty.hpp @@ -7,14 +7,9 @@ #include "assert/assert.hpp" namespace Dawn { - class StateOwner; - template class StateProperty { private: - StateOwner *owner; - V value; - /** * Method that is invoked every time that the value of this state property * is updated. @@ -22,25 +17,45 @@ namespace Dawn { * @param val Value that is to be used for this property. */ void setInternal(V val) { - if(val == this->value) return;// TODO: can I omit this? kinda bad tbh. - assertNotNull(this->owner); - auto old = this->value; - this->value = val; - this->owner->_statePropertyUpdated(this, val, old); + if(val == this->_realValue) return;// TODO: can I omit this? kinda bad tbh. + this->previous = this->_realValue; + this->_realValue = val; + + // Notify the effect listeners + auto itEffect = this->_effectListners.begin(); + while(itEffect != this->_effectListners.end()) { + (*itEffect)(); + ++itEffect; + } } public: + V _realValue; + std::vector> _effectListners; + V previous; + + /** + * Creates a new state property and listens for its change. + */ + StateProperty() {} + + /** + * Creates a new state property and listens for its change. + * @param initial The initial value of this state. + */ + StateProperty(V initial) : _realValue(initial) {} + const StateProperty& operator += (const V &value) { - this->setInternal(this->value + value); + this->setInternal(this->_realValue + value); return *this; } const bool_t operator != (const V &value) { - return value != this->value; + return value != this->_realValue; } const bool_t operator == (const V &value) { - return value == this->value; + return value == this->_realValue; } const StateProperty& operator = (const V &val) { @@ -49,15 +64,13 @@ namespace Dawn { } operator V() const { - return this->value; + return this->_realValue; } /** * Destructor for StateProperty. */ - ~StateProperty() { - this->owner->_statePropertyDestroyed(this); - } + ~StateProperty() {} friend class StateOwner; }; diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.cpp b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp index 2a9acd49..b3941761 100644 --- a/src/dawnopengl/display/shader/SimpleTexturedShader.cpp +++ b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp @@ -27,7 +27,7 @@ std::vector SimpleTexturedShader::getPassItems( onlyPass.colorValues[program.paramColor] = simpleMaterial->color; onlyPass.matrixValues[program.paramModel] = material->transform->getWorldTransform(); onlyPass.matrixValues[program.paramView] = camera->transform->getWorldTransform(); - onlyPass.matrixValues[program.paramProjection] = camera->projection; + onlyPass.matrixValues[program.paramProjection] = camera->getProjection(); onlyPass.renderFlags = ( RENDER_MANAGER_RENDER_FLAG_BLEND | RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST diff --git a/src/dawntictactoe/components/TicTacToeTile.cpp b/src/dawntictactoe/components/TicTacToeTile.cpp index af33c2b8..e733eba5 100644 --- a/src/dawntictactoe/components/TicTacToeTile.cpp +++ b/src/dawntictactoe/components/TicTacToeTile.cpp @@ -8,13 +8,14 @@ using namespace Dawn; -TicTacToeTile::TicTacToeTile(SceneItem *item) : SceneItemComponent(item) { +TicTacToeTile::TicTacToeTile(SceneItem *item) : + SceneItemComponent(item), + tileState(TIC_TAC_TOE_EMPTY), + hovered(false) +{ } void TicTacToeTile::onStart() { - tileState = useState(TIC_TAC_TOE_EMPTY); - hovered = useState(false); - auto cb = [&]{ auto sprite = this->item->getComponent(); if(this->hovered) { diff --git a/src/dawntictactoe/scenes/TicTacToeScene.hpp b/src/dawntictactoe/scenes/TicTacToeScene.hpp index 008cc5ad..e02dc11d 100644 --- a/src/dawntictactoe/scenes/TicTacToeScene.hpp +++ b/src/dawntictactoe/scenes/TicTacToeScene.hpp @@ -14,7 +14,7 @@ namespace Dawn { - class TicTacToeScene : public Scene, public StateOwner { + class TicTacToeScene : public Scene { protected: Camera *camera;