Updated more scene item coponents to state system

This commit is contained in:
2023-03-01 09:25:07 -08:00
parent 3a4c87fc37
commit 7838e1b92d
11 changed files with 256 additions and 360 deletions

View File

@ -34,7 +34,7 @@ void RenderPipeline::renderScene(Scene *scene) {
auto subSceneControllers = scene->findComponents<SubSceneController>();
auto itSubScene = subSceneControllers.begin();
while(itSubScene != subSceneControllers.end()) {
auto subScene = (*itSubScene)->getSubScene();
Scene *subScene = (Scene *)((*itSubScene)->subScene);
if(subScene == nullptr) {
++itSubScene;
continue;

View File

@ -19,24 +19,20 @@ SceneItem * ExampleSpin::create(Scene *scene) {
CubeMesh::buffer(mr->mesh, glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), 0, 0);
auto mat = item->addComponent<SimpleTexturedMaterial>();
item->addComponent<ExampleSpin>();
return item;
}
ExampleSpin::ExampleSpin(SceneItem *item) :
SceneItemComponent(item)
{
getScene()->eventSceneUnpausedUpdate.addListener(this, &ExampleSpin::onUnpausedUpdate);
}
void ExampleSpin::onUnpausedUpdate() {
auto quat = this->transform->getLocalRotation();
quat = glm::rotate(quat, getGame()->timeManager.delta, glm::vec3(0, 1, 0));
quat = glm::rotate(quat, getGame()->timeManager.delta / 2.0f, glm::vec3(1, 0, 0));
quat = glm::rotate(quat, getGame()->timeManager.delta / 4.0f, glm::vec3(0, 0, 1));
this->transform->setLocalRotation(quat);
}
void ExampleSpin::onDispose() {
getScene()->eventSceneUnpausedUpdate.removeListener(this, &ExampleSpin::onUnpausedUpdate);
void ExampleSpin::onStart() {
useEventLegacy([&]{
auto quat = this->transform->getLocalRotation();
quat = glm::rotate(quat, getGame()->timeManager.delta, glm::vec3(0, 1, 0));
quat = glm::rotate(quat, getGame()->timeManager.delta / 2.0f, glm::vec3(1, 0, 0));
quat = glm::rotate(quat, getGame()->timeManager.delta / 4.0f, glm::vec3(0, 0, 1));
this->transform->setLocalRotation(quat);
}, getScene()->eventSceneUnpausedUpdate);
}

View File

@ -1,19 +1,18 @@
// 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 "display/shader/Shader.hpp"
namespace Dawn {
class ExampleSpin : public SceneItemComponent {
public:
static SceneItem * create(Scene *scene);
ExampleSpin(SceneItem *item);
void onUnpausedUpdate();
void onDispose() override;
};
// 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 "display/shader/Shader.hpp"
namespace Dawn {
class ExampleSpin : public SceneItemComponent {
public:
static SceneItem * create(Scene *scene);
ExampleSpin(SceneItem *item);
void onStart() override;
};
}

View File

@ -7,18 +7,11 @@
using namespace Dawn;
SubSceneCameraAlign::SubSceneCameraAlign(SceneItem *i) : SceneItemComponent(i) {
}
void SubSceneCameraAlign::onRenderTargetResize(
RenderTarget *target, float_t w, float_t h
) {
this->realign();
}
void SubSceneCameraAlign::onCameraResize(float_t w, float_t h) {
this->realign();
SubSceneCameraAlign::SubSceneCameraAlign(SceneItem *i) :
SceneItemComponent(i),
camera(nullptr),
renderTarget(nullptr)
{
}
void SubSceneCameraAlign::realign() {
@ -27,7 +20,7 @@ void SubSceneCameraAlign::realign() {
if(this->renderTarget == nullptr) return;
float_t ratio = this->renderTarget->getWidth() / this->renderTarget->getHeight();
float_t myRatio = this->camera->getRenderTarget()->getWidth() / this->camera->getRenderTarget()->getHeight();
float_t myRatio = this->camera->getAspect();
this->camera->type = CAMERA_TYPE_ORTHONOGRAPHIC;
this->camera->transform->lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0));
@ -49,57 +42,27 @@ void SubSceneCameraAlign::realign() {
}
}
void SubSceneCameraAlign::setRenderTarget(TextureRenderTarget *renderTarget) {
assertTrue(this->renderTarget != renderTarget);
if(this->renderTarget != nullptr) {
this->renderTarget->eventRenderTargetResized.removeListener(
this, &SubSceneCameraAlign::onRenderTargetResize
);
}
this->renderTarget = renderTarget;
this->realign();
if(this->renderTarget != nullptr) {
this->renderTarget->eventRenderTargetResized.addListener(
this, &SubSceneCameraAlign::onRenderTargetResize
);
}
}
void SubSceneCameraAlign::setCamera(Camera *camera) {
assertTrue(this->camera != camera);
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.removeListener(
this, &SubSceneCameraAlign::onCameraResize
);
}
this->camera = camera;
this->realign();
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.addListener(
this, &SubSceneCameraAlign::onCameraResize
);
}
}
void SubSceneCameraAlign::onStart() {
this->realign();
}
auto cameraEffect = useEffectWithTeardown([&]{
if(camera == nullptr) return evtCameraResized = [&] {};
void SubSceneCameraAlign::onDispose() {
if(this->renderTarget != nullptr) {
this->renderTarget->eventRenderTargetResized.removeListener(
this, &SubSceneCameraAlign::onRenderTargetResize
);
}
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.removeListener(
this, &SubSceneCameraAlign::onCameraResize
);
}
this->realign();
return evtCameraResized = useEvent([&](float_t w, float_t h){
this->realign();
}, this->camera->event2RenderTargetResized);
}, this->camera);
auto renderEffect = useEffectWithTeardown([&]{
if(renderTarget == nullptr) return evtRenderResized = [&]{};
this->realign();
return evtRenderResized = useEventLegacy([&](RenderTarget *t, float_t w, float_t h) {
this->realign();
}, renderTarget->eventRenderTargetResized);
}, this->renderTarget);
cameraEffect();
renderEffect();
}

View File

@ -11,11 +11,8 @@
namespace Dawn {
class SubSceneCameraAlign : public SceneItemComponent {
protected:
TextureRenderTarget *renderTarget = nullptr;
Camera *camera = nullptr;
void onRenderTargetResize(RenderTarget *target, float_t w, float_t h);
void onCameraResize(float_t w, float_t h);
std::function<void()> evtCameraResized;
std::function<void()> evtRenderResized;
/**
* Realigns the camera to match the render target quad.
@ -23,6 +20,9 @@ namespace Dawn {
void realign();
public:
StateProperty<Camera*> camera;
StateProperty<TextureRenderTarget*> renderTarget;
/**
* Create the sub scene camera align component. This will align a camera
* to match a render target quad (Refer SimpleRenderTargetQuad)
@ -31,21 +31,6 @@ namespace Dawn {
*/
SubSceneCameraAlign(SceneItem *item);
/**
* Set the render target for this alignment to use.
*
* @param renderTarget Render target to align to.
*/
void setRenderTarget(TextureRenderTarget *renderTarget);
/**
* Sets the camera that will be aligned.
*
* @param camera Camera to align.
*/
void setCamera(Camera *camera);
void onStart() override;
void onDispose() override;
};
}

View File

@ -1,45 +1,28 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SubSceneController.hpp"
using namespace Dawn;
SubSceneController::SubSceneController(SceneItem *i) : SceneItemComponent(i) {
}
void SubSceneController::onSceneUpdate() {
if(this->onlyUpdateUnpaused) return;
if(this->subScene == nullptr) return;
this->subScene->update();
}
void SubSceneController::onSceneUnpausedUpdate() {
if(!this->onlyUpdateUnpaused) return;
if(this->subScene == nullptr) return;
this->subScene->update();
}
Scene * SubSceneController::getSubScene() {
return this->subScene;
}
void SubSceneController::setSubScene(Scene *scene) {
assertTrue(scene != this->subScene);
this->subScene = scene;
}
void SubSceneController::onStart() {
auto myScene = this->getScene();
myScene->eventSceneUnpausedUpdate.addListener(this, &SubSceneController::onSceneUnpausedUpdate);
myScene->eventSceneUpdate.addListener(this, &SubSceneController::onSceneUpdate);
}
void SubSceneController::onDispose() {
auto myScene = this->getScene();
myScene->eventSceneUnpausedUpdate.removeListener(this, &SubSceneController::onSceneUnpausedUpdate);
myScene->eventSceneUpdate.removeListener(this, &SubSceneController::onSceneUpdate);
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SubSceneController.hpp"
using namespace Dawn;
SubSceneController::SubSceneController(SceneItem *i) : SceneItemComponent(i) {
}
void SubSceneController::onStart() {
auto myScene = this->getScene();
useEventLegacy([&]{
if(!this->onlyUpdateUnpaused) return;
if(this->subScene == nullptr) return;
this->subScene->update();
}, myScene->eventSceneUnpausedUpdate);
useEventLegacy([&]{
if(this->onlyUpdateUnpaused) return;
if(this->subScene == nullptr) return;
this->subScene->update();
}, myScene->eventSceneUpdate);
}

View File

@ -8,21 +8,12 @@
namespace Dawn {
class SubSceneController : public SceneItemComponent {
protected:
Scene *subScene = nullptr;
void onSceneUpdate();
void onSceneUnpausedUpdate();
public:
Scene *subScene = nullptr;
bool_t onlyUpdateUnpaused = false;
SubSceneController(SceneItem *item);
Scene * getSubScene();
void setSubScene(Scene *scene);
void onStart() override;
void onDispose() override;
};
}

View File

@ -15,39 +15,11 @@ UICanvas * UICanvas::create(Scene *scene) {
return item->addComponent<UICanvas>();
}
UICanvas::UICanvas(SceneItem *item) : SceneItemComponent(item) {
}
void UICanvas::onRenderTargetResize(float_t w, float_t h){
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
}
void UICanvas::onSceneUpdate() {
if(this->currentMenu != nullptr) {
this->currentMenu->onTick();
}
}
void UICanvas::setCamera(Camera *camera) {
assertTrue(camera != this->camera);
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.removeListener(
this, &UICanvas::onRenderTargetResize
);
}
this->camera = camera;
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.addListener(
this, &UICanvas::onRenderTargetResize
);
}
UICanvas::UICanvas(SceneItem *item) :
SceneItemComponent(item),
camera(nullptr),
currentMenu(nullptr)
{
}
float_t UICanvas::getWidth() {
@ -64,34 +36,47 @@ float_t UICanvas::getHeight() {
return this->camera->getRenderTarget()->getHeight();
}
struct UIMenu * UICanvas::getCurrentMenu() {
return this->currentMenu;
}
void UICanvas::setCurrentMenu(struct UIMenu *menu) {
if(this->currentMenu != nullptr) this->currentMenu->onInactive();
this->currentMenu = menu;
if(menu != nullptr) menu->onActive();
}
void UICanvas::onStart() {
if(this->camera == nullptr) {
auto camera = this->getScene()->findComponent<Camera>();
this->setCamera(camera);
}
useEffectWithTeardown([&]{
if(this->camera == nullptr) return evtCamResize = [&]{};
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
this->getScene()->eventSceneUpdate.addListener(this, &UICanvas::onSceneUpdate);
return evtCamResize = useEvent([&](float_t w, float_t h){
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
}, camera->event2RenderTargetResized);
}, camera);
useEffectWithTeardown([&]{
if(currentMenu != nullptr) currentMenu->onActive();
return [&] {
if(currentMenu == nullptr) currentMenu->onInactive();
};
}, this->currentMenu);
// Scene Update
useEventLegacy([&]{
if(this->currentMenu == nullptr) return;
this->currentMenu->onTick();
}, getScene()->eventSceneUpdate);
// Find Camera if we need to.
if(camera == nullptr) camera = this->getScene()->findComponent<Camera>();
}
void UICanvas::onDispose() {
if(this->camera != nullptr) {
this->camera->eventRenderTargetResized.removeListener(
this, &UICanvas::onRenderTargetResize
);
}
this->getScene()->eventSceneUpdate.removeListener(this, &UICanvas::onSceneUpdate);
auto it = this->children.begin();
while(it != this->children.end()) {
delete *it;

View File

@ -20,13 +20,14 @@ namespace Dawn {
class UICanvas : public SceneItemComponent {
protected:
Camera *camera = nullptr;
struct UIMenu *currentMenu = nullptr;
std::function<void()> evtCamResize;
void onRenderTargetResize(float_t w, float_t h);
void onSceneUpdate();
public:
StateProperty<struct UIMenu*> currentMenu;
StateProperty<Camera*> camera;
/**
* Creates a UI Canvas Scene Item Element, and attaches it to the provided
* scene.
@ -47,13 +48,6 @@ namespace Dawn {
*/
UICanvas(SceneItem *item);
/**
* Sets the camera used by the UI canvas.
*
* @param camera Camera to set for the UI canvas.
*/
void setCamera(Camera *camera);
/**
* Construct and append a UI item to this UI Canvas.
*

View File

@ -18,8 +18,6 @@ namespace Dawn {
*/
void setInternal(V val) {
if(val == this->_realValue) return;// TODO: can I omit this? kinda bad tbh.
this->previous = this->_realValue;
this->_realValue = val;
// Run the teardowns
auto itTeardown = this->_effectTeardowns.begin();
@ -29,6 +27,10 @@ namespace Dawn {
}
this->_effectTeardowns.clear();
// Update the values
this->previous = this->_realValue;
this->_realValue = val;
// Notify the effect listeners
auto itEffect = this->_effectListners.begin();
while(itEffect != this->_effectListners.end()) {

View File

@ -1,127 +1,125 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIMenu.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UIMenu::UIMenu(UICanvas *canvas, int32_t columns, int32_t rows) {
assertNotNull(canvas);
assertTrue(columns > 0);
assertTrue(rows > 0);
this->canvas = canvas;
this->rows = rows;
this->columns = columns;
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
void UIMenu::setSize(int32_t cols, int32_t rows) {
assertNotNull(this->items);
assertTrue(columns > 0);
assertTrue(rows > 0);
assertTrue(columns != this->columns);
assertTrue(rows != this->rows);
memoryFree(this->items);
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
UIMenuItem * UIMenu::getItem(int32_t x, int32_t y) {
return this->items[x * this->columns + y];
}
void UIMenu::setPosition(int32_t x, int32_t y) {
assertTrue(x >= 0 && x < this->columns);
assertTrue(y >= 0 && y < this->rows);
UIMenuItem *item;
if(this->x != -1) {
assertTrue(this->y != -1);
item = this->getItem(this->x, this->y);
if(item != nullptr) {
item->onItemOff();
}
}
this->eventCursorChange.invoke(this->x, this->y, x, y);
this->x = x;
this->y = y;
item = this->getItem(x, y);
if(item != nullptr && item->canBeOvered()) {
item->onItemOver();
}
}
void UIMenu::moveRelative(int32_t x, int32_t y) {
int32_t x2 = this->x + x;
if(x2 < 0 || x2 >= this->columns) return;
int32_t y2 = this->y + y;
if(y2 < 0 || y2 >= this->rows) return;
this->setPosition(x2, y2);
}
void UIMenu::setItem(int32_t x, int32_t y, UIMenuItem *item) {
assertTrue(x >= 0);
assertTrue(y >= 0);
assertTrue(x < this->columns);
assertTrue(y < this->rows);
assertNotNull(item);
assertNotNull(this->items);
assertNull(this->getItem(x, y));
this->items[x * this->columns + y] = item;
}
void UIMenu::onInactive() {
this->eventMenuInactive.invoke();
}
void UIMenu::onActive() {
this->eventMenuActive.invoke();
}
void UIMenu::onTick() {
auto im = &this->canvas->getGame()->inputManager;
if(im->isPressed(INPUT_BIND_ACCEPT)) {
auto item = this->getItem(this->x, this->y);
if(item != nullptr && item->canBeSelected()) {
item->onItemSelected();
return;
}
}
if(im->isPressed(INPUT_BIND_NEGATIVE_Y)) {
this->moveRelative(0, 1);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_Y)) {
this->moveRelative(0, -1);
return;
}
if(im->isPressed(INPUT_BIND_NEGATIVE_X)) {
this->moveRelative(-1, 0);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_X)) {
this->moveRelative(1, 0);
return;
}
// TODO: Support more modes and holding buttons to scroll.
}
UIMenu::~UIMenu() {
if(this->canvas->getCurrentMenu() == this) {
this->canvas->setCurrentMenu(nullptr);
}
memoryFree(this->items);
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIMenu.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UIMenu::UIMenu(UICanvas *canvas, int32_t columns, int32_t rows) {
assertNotNull(canvas);
assertTrue(columns > 0);
assertTrue(rows > 0);
this->canvas = canvas;
this->rows = rows;
this->columns = columns;
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
void UIMenu::setSize(int32_t cols, int32_t rows) {
assertNotNull(this->items);
assertTrue(columns > 0);
assertTrue(rows > 0);
assertTrue(columns != this->columns);
assertTrue(rows != this->rows);
memoryFree(this->items);
this->items = (UIMenuItem**)memoryFillWithZero(sizeof(UIMenuItem*)*columns*rows);
}
UIMenuItem * UIMenu::getItem(int32_t x, int32_t y) {
return this->items[x * this->columns + y];
}
void UIMenu::setPosition(int32_t x, int32_t y) {
assertTrue(x >= 0 && x < this->columns);
assertTrue(y >= 0 && y < this->rows);
UIMenuItem *item;
if(this->x != -1) {
assertTrue(this->y != -1);
item = this->getItem(this->x, this->y);
if(item != nullptr) {
item->onItemOff();
}
}
this->eventCursorChange.invoke(this->x, this->y, x, y);
this->x = x;
this->y = y;
item = this->getItem(x, y);
if(item != nullptr && item->canBeOvered()) {
item->onItemOver();
}
}
void UIMenu::moveRelative(int32_t x, int32_t y) {
int32_t x2 = this->x + x;
if(x2 < 0 || x2 >= this->columns) return;
int32_t y2 = this->y + y;
if(y2 < 0 || y2 >= this->rows) return;
this->setPosition(x2, y2);
}
void UIMenu::setItem(int32_t x, int32_t y, UIMenuItem *item) {
assertTrue(x >= 0);
assertTrue(y >= 0);
assertTrue(x < this->columns);
assertTrue(y < this->rows);
assertNotNull(item);
assertNotNull(this->items);
assertNull(this->getItem(x, y));
this->items[x * this->columns + y] = item;
}
void UIMenu::onInactive() {
this->eventMenuInactive.invoke();
}
void UIMenu::onActive() {
this->eventMenuActive.invoke();
}
void UIMenu::onTick() {
auto im = &this->canvas->getGame()->inputManager;
if(im->isPressed(INPUT_BIND_ACCEPT)) {
auto item = this->getItem(this->x, this->y);
if(item != nullptr && item->canBeSelected()) {
item->onItemSelected();
return;
}
}
if(im->isPressed(INPUT_BIND_NEGATIVE_Y)) {
this->moveRelative(0, 1);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_Y)) {
this->moveRelative(0, -1);
return;
}
if(im->isPressed(INPUT_BIND_NEGATIVE_X)) {
this->moveRelative(-1, 0);
return;
}
if(im->isPressed(INPUT_BIND_POSITIVE_X)) {
this->moveRelative(1, 0);
return;
}
// TODO: Support more modes and holding buttons to scroll.
}
UIMenu::~UIMenu() {
if(this->canvas->currentMenu == this) this->canvas->currentMenu = nullptr;
memoryFree(this->items);
}