From 5c6436dd180150cb8f8d0284cc4b6b02b48786e1 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 10 Mar 2023 08:35:57 -0800 Subject: [PATCH] Progress --- lib/SDL | 2 +- lib/openal-soft | 2 +- src/dawn/state/StateProvider.hpp | 37 +++-- src/dawn/time/ITimeManager.cpp | 87 ++++++++---- src/dawn/time/ITimeManager.hpp | 133 +++++++++++------- .../components/TicTacToeGame.cpp | 6 +- 6 files changed, 161 insertions(+), 106 deletions(-) diff --git a/lib/SDL b/lib/SDL index 87a83787..c9aec268 160000 --- a/lib/SDL +++ b/lib/SDL @@ -1 +1 @@ -Subproject commit 87a83787a3a0a9922b02b35ba809d9da86930fc8 +Subproject commit c9aec268fa7f892e183219683160599a4a2b86db diff --git a/lib/openal-soft b/lib/openal-soft index d66107e9..fde74453 160000 --- a/lib/openal-soft +++ b/lib/openal-soft @@ -1 +1 @@ -Subproject commit d66107e9f008770b48f0df4fce041ee3e501e1e8 +Subproject commit fde74453a62a1ce4b5efaac0ec1835b9f5731e25 diff --git a/src/dawn/state/StateProvider.hpp b/src/dawn/state/StateProvider.hpp index 6508dc2b..dfd88e9d 100644 --- a/src/dawn/state/StateProvider.hpp +++ b/src/dawn/state/StateProvider.hpp @@ -7,8 +7,6 @@ #include "state/State.hpp" namespace Dawn { - class SceneItemComponent; - template struct StateListener { std::function callback; @@ -17,37 +15,34 @@ namespace Dawn { template struct StateProviderSet { - private: + public: std::vector> listeners; - public: + /** + * Attaches an effect listener that is invoked by a provider. + * + * @tparam T Context Type, usually the state listener itself. + * @param callback Callback method to be invoked by the provider. + * @param data Data to be stored with the StateListener. + * @param context Context for the state object. + * @return The unsubscribe method, when invoked, unsubs from the provider. + */ + template std::function addEffect( std::function callback, - D data + D data, + T *context ) { struct StateListener l; l.callback = callback; l.data = data; this->listeners.push_back(l); - l.callback(); - return std::bind([&](struct StateListener listener) { - assertUnreachable(); + auto it = std::find(listeners.begin(), listeners.end(), listener); + assertFalse(it == listeners.end()); + listeners.erase(it); }, l); } }; - - class TimeProvider { - public: - StateProviderSet effect; - }; - - std::function useTimeout( - std::function someCallback, - float_t timeout, - SceneItemComponent *context - ) { - return (TimeProvider()).effect.addEffect(someCallback, timeout); - } } \ No newline at end of file diff --git a/src/dawn/time/ITimeManager.cpp b/src/dawn/time/ITimeManager.cpp index 0181f193..b6bd0113 100644 --- a/src/dawn/time/ITimeManager.cpp +++ b/src/dawn/time/ITimeManager.cpp @@ -1,32 +1,57 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "ITimeManager.hpp" - -using namespace Dawn; - -ITimeManager::ITimeManager() { - -} - -void ITimeManager::update(float_t delta) { - this->delta = delta; - this->time += delta; - if(!this->isPaused) { - this->unpausedTime += delta; - } -} - -void ITimeManager::pause() { - if(this->isPaused) return; - this->isPaused = true; - this->eventTimePaused.invoke(); -} - -void ITimeManager::resume() { - if(!this->isPaused) return; - this->isPaused = false; - this->eventTimeResumed.invoke(); +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "ITimeManager.hpp" + +using namespace Dawn; + +ITimeManager::ITimeManager() { + +} + +void ITimeManager::update(float_t delta) { + this->delta = delta; + this->time += delta; + + if(!this->isPaused) { + this->unpausedTime += delta; + + // Timeout effect provider + auto itEffect = this->timeoutProvider.listeners.begin(); + while(itEffect != this->timeoutProvider.listeners.end()) { + itEffect->data -= delta; + if(itEffect->data <= 0) { + itEffect->callback(); + itEffect = this->timeoutProvider.listeners.erase(itEffect); + continue; + } + ++itEffect; + } + + + // Interval provider + auto itInterval = this->intervalProvider.listeners.begin(); + while(itInterval != this->intervalProvider.listeners.end()) { + itInterval->data.second += delta; + if(itInterval->data.second >= itInterval->data.first) { + itInterval->callback(); + itInterval->data.second = 0; + } + ++itInterval; + } + } +} + +void ITimeManager::pause() { + if(this->isPaused) return; + this->isPaused = true; + this->eventTimePaused.invoke(); +} + +void ITimeManager::resume() { + if(!this->isPaused) return; + this->isPaused = false; + this->eventTimeResumed.invoke(); } \ No newline at end of file diff --git a/src/dawn/time/ITimeManager.hpp b/src/dawn/time/ITimeManager.hpp index 752cc4e5..03393c0e 100644 --- a/src/dawn/time/ITimeManager.hpp +++ b/src/dawn/time/ITimeManager.hpp @@ -1,50 +1,85 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "dawnlibs.hpp" -#include "event/Event.hpp" - -namespace Dawn { - class ITimeManager { - public: - float_t time = 0.0f; - float_t unpausedTime = 0.0f; - float_t delta = 0.016f; - bool_t isPaused = false; - - Event<> eventTimePaused; - Event<> eventTimeResumed; - - /** - * Constructor for the Time Manager. - */ - ITimeManager(); - - /** - * Updates / Ticks the time manager instance. - * - * @param delta Time in seconds to tick the instance by. - */ - void update(float_t delta); - - /** - * Pauses the game. - */ - void pause(); - - /** - * Resumes the game. - */ - void resume(); - - /** - * Returns the current system timestamp. - * - * @return Current timestamp. - */ - virtual int64_t getTimestamp() = 0; - }; +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" +#include "event/Event.hpp" +#include "state/StateProvider.hpp" + +namespace Dawn { + class ITimeManager { + public: + float_t time = 0.0f; + float_t unpausedTime = 0.0f; + float_t delta = 0.016f; + bool_t isPaused = false; + + StateProviderSet timeoutProvider; + StateProviderSet> intervalProvider; + + Event<> eventTimePaused; + Event<> eventTimeResumed; + + /** + * Constructor for the Time Manager. + */ + ITimeManager(); + + /** + * Updates / Ticks the time manager instance. + * + * @param delta Time in seconds to tick the instance by. + */ + void update(float_t delta); + + /** + * Pauses the game. + */ + void pause(); + + /** + * Resumes the game. + */ + void resume(); + + /** + * Returns the current system timestamp. + * + * @return Current timestamp. + */ + virtual int64_t getTimestamp() = 0; + }; + + + /** + * Use timeout provider method. Invokes your callback after some specified + * time has passed. + * + * @tparam T Your context type (usually SceneItemComponent). + * @param someCallback Callback to be invoked. + * @param timeout Timeout to wait before the method is invoked. + * @param context Context of the component, just use (this). + * @return Method that when invoked will unsubscribe from the timeout. + */ + template + std::function useTimeout( + std::function someCallback, + float_t timeout, + T *context + ) { + return context->getGame()->timeManager.timeoutProvider.addEffect(someCallback, timeout, context); + } + + template + std::function useInterval( + std::function callback, + float_t interval, + T *context + ) { + return context->getGame()->timeManager.intervalProvider.addEffect( + callback, std::pair({ interval, 0 }), context + ); + } } \ No newline at end of file diff --git a/src/dawntictactoe/components/TicTacToeGame.cpp b/src/dawntictactoe/components/TicTacToeGame.cpp index 7bc111a0..a9b22455 100644 --- a/src/dawntictactoe/components/TicTacToeGame.cpp +++ b/src/dawntictactoe/components/TicTacToeGame.cpp @@ -30,9 +30,9 @@ void TicTacToeGame::onStart() { ++itTiles; } - useTimeout([&]{ - std::cout << "Timeout" << std::endl; - }, 1000, this)(); + useInterval([&]{ + std::cout << "Interval" << std::endl; + }, 1.0f, this); useEffect([&]{ if(!gameOver) return;