Updated useEvent
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
#include "asset/Asset.hpp"
|
#include "asset/Asset.hpp"
|
||||||
#include "scene/debug/SceneDebugLine.hpp"
|
#include "scene/debug/SceneDebugLine.hpp"
|
||||||
#include "physics/ScenePhysicsManager.hpp"
|
#include "physics/ScenePhysicsManager.hpp"
|
||||||
|
#include "state/State.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class DawnGame;
|
class DawnGame;
|
||||||
@ -20,7 +21,7 @@ namespace Dawn {
|
|||||||
template<class T>
|
template<class T>
|
||||||
T * _sceneForwardGetComponent(SceneItem *item);
|
T * _sceneForwardGetComponent(SceneItem *item);
|
||||||
|
|
||||||
class Scene {
|
class Scene : public StateOwner {
|
||||||
private:
|
private:
|
||||||
sceneitemid_t nextId;
|
sceneitemid_t nextId;
|
||||||
std::map<sceneitemid_t, SceneItem*> items;
|
std::map<sceneitemid_t, SceneItem*> items;
|
||||||
|
@ -76,7 +76,7 @@ namespace Dawn {
|
|||||||
/**
|
/**
|
||||||
* Cleanup the SceneItemComponent.
|
* Cleanup the SceneItemComponent.
|
||||||
*/
|
*/
|
||||||
~SceneItemComponent();
|
virtual ~SceneItemComponent();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ glm::vec3 Camera::getRayDirectionFromScreenSpace(glm::vec2 screenSpace) {
|
|||||||
|
|
||||||
void Camera::onStart() {
|
void Camera::onStart() {
|
||||||
// Render Target
|
// Render Target
|
||||||
useEffect(renderTarget, [&]{
|
useEffect([&]{
|
||||||
if(renderTarget.previous != nullptr) {
|
if(renderTarget.previous != nullptr) {
|
||||||
renderTarget.previous->eventRenderTargetResized.removeListener(
|
renderTarget.previous->eventRenderTargetResized.removeListener(
|
||||||
this, &Camera::onRenderTargetResize
|
this, &Camera::onRenderTargetResize
|
||||||
@ -94,21 +94,30 @@ void Camera::onStart() {
|
|||||||
rt->getWidth(), rt->getHeight()
|
rt->getWidth(), rt->getHeight()
|
||||||
);
|
);
|
||||||
this->event2RenderTargetResized.invoke(rt->getWidth(), rt->getHeight());
|
this->event2RenderTargetResized.invoke(rt->getWidth(), rt->getHeight());
|
||||||
});
|
}, renderTarget);
|
||||||
|
|
||||||
// All regular properties.
|
// All regular properties.
|
||||||
auto cbUpdateProj = [&]{
|
useEffect([&]{
|
||||||
this->projectionNeedsUpdating = true;
|
this->projectionNeedsUpdating = true;
|
||||||
};
|
}, {
|
||||||
|
&fov,
|
||||||
|
&type,
|
||||||
|
&orthoLeft,
|
||||||
|
&orthoRight,
|
||||||
|
&orthoBottom,
|
||||||
|
&orthoTop,
|
||||||
|
&clipNear,
|
||||||
|
&clipFar
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(fov, cbUpdateProj);
|
// useEffect(fov, cbUpdateProj);
|
||||||
useEffect(type, cbUpdateProj);
|
// useEffect(type, cbUpdateProj);
|
||||||
useEffect(orthoLeft, cbUpdateProj);
|
// useEffect(orthoLeft, cbUpdateProj);
|
||||||
useEffect(orthoRight, cbUpdateProj);
|
// useEffect(orthoRight, cbUpdateProj);
|
||||||
useEffect(orthoBottom, cbUpdateProj);
|
// useEffect(orthoBottom, cbUpdateProj);
|
||||||
useEffect(orthoTop, cbUpdateProj);
|
// useEffect(orthoTop, cbUpdateProj);
|
||||||
useEffect(clipNear, cbUpdateProj);
|
// useEffect(clipNear, cbUpdateProj);
|
||||||
useEffect(clipFar, cbUpdateProj);
|
// useEffect(clipFar, cbUpdateProj);
|
||||||
|
|
||||||
getRenderTarget()->eventRenderTargetResized.addListener(this, &Camera::onRenderTargetResize);
|
getRenderTarget()->eventRenderTargetResized.addListener(this, &Camera::onRenderTargetResize);
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,11 @@ void PixelPerfectCamera::onStart() {
|
|||||||
assertNotNull(this->camera);
|
assertNotNull(this->camera);
|
||||||
this->updateDimensions();
|
this->updateDimensions();
|
||||||
|
|
||||||
useEvent(this->camera->event2RenderTargetResized, [&](float_t w, float_t h){
|
useEvent([&](float_t w, float_t h){
|
||||||
this->updateDimensions();
|
this->updateDimensions();
|
||||||
});
|
}, this->camera->event2RenderTargetResized);
|
||||||
|
|
||||||
useEffect(scale, [&]{
|
useEffect([&]{
|
||||||
this->updateDimensions();
|
this->updateDimensions();
|
||||||
});
|
}, scale);
|
||||||
}
|
}
|
@ -42,7 +42,7 @@ void SimpleRenderTargetQuad::onStart() {
|
|||||||
// Create quad mesh
|
// Create quad mesh
|
||||||
this->meshHost->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
|
this->meshHost->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
|
||||||
|
|
||||||
useEffect(this->renderTarget, [&]{
|
useEffect([&]{
|
||||||
if(this->renderTarget.previous != nullptr) {
|
if(this->renderTarget.previous != nullptr) {
|
||||||
this->renderTarget.previous->eventRenderTargetResized.addListener(
|
this->renderTarget.previous->eventRenderTargetResized.addListener(
|
||||||
this, &SimpleRenderTargetQuad::onRenderTargetResized
|
this, &SimpleRenderTargetQuad::onRenderTargetResized
|
||||||
@ -66,7 +66,7 @@ void SimpleRenderTargetQuad::onStart() {
|
|||||||
((RenderTarget*)this->renderTarget)->eventRenderTargetResized.addListener(
|
((RenderTarget*)this->renderTarget)->eventRenderTargetResized.addListener(
|
||||||
this, &SimpleRenderTargetQuad::onRenderTargetResized
|
this, &SimpleRenderTargetQuad::onRenderTargetResized
|
||||||
);
|
);
|
||||||
});
|
}, this->renderTarget);
|
||||||
|
|
||||||
// Perform first resize.
|
// Perform first resize.
|
||||||
if(this->renderTarget != nullptr) {
|
if(this->renderTarget != nullptr) {
|
||||||
|
@ -11,24 +11,40 @@ namespace Dawn {
|
|||||||
class StateOwner {
|
class StateOwner {
|
||||||
private:
|
private:
|
||||||
std::vector<IStateEvent*> eventsSubscribed;
|
std::vector<IStateEvent*> eventsSubscribed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Listen for changees to a state property and involke the provided func
|
* Listen for changes to a state property and invoke the provided func
|
||||||
* when the value is changed.
|
* 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.
|
* @param fn The callback to be invoked when the state value changes.
|
||||||
|
* @param property Property to listen for affect changees to.
|
||||||
*/
|
*/
|
||||||
template<class V>
|
|
||||||
void useEffect(
|
void useEffect(
|
||||||
StateProperty<V> &property,
|
const std::function<void()> &fn,
|
||||||
const std::function<void()> &fn
|
IStateProperty &property
|
||||||
) {
|
) {
|
||||||
property._effectListners.push_back(fn);
|
property._effectListners.push_back(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for changes to a set of state properties and invoke the provided
|
||||||
|
* func when any of their values are changed.
|
||||||
|
*
|
||||||
|
* @param fn The callback to be invoked when the state value changes.
|
||||||
|
* @param property Vector list of properties to listen for changes to.
|
||||||
|
*/
|
||||||
|
void useEffect(
|
||||||
|
const std::function<void()> &fn,
|
||||||
|
std::vector<IStateProperty*> props
|
||||||
|
) {
|
||||||
|
auto itProp = props.begin();
|
||||||
|
while(itProp != props.end()) {
|
||||||
|
(*itProp)->_effectListners.push_back(fn);
|
||||||
|
++itProp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen for when an event is invoked by a state event. This is intended
|
* 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
|
* to allow for cross-state-owner communication in a simple and effective
|
||||||
@ -36,16 +52,38 @@ namespace Dawn {
|
|||||||
*
|
*
|
||||||
* @tparam F The type of the callback function.
|
* @tparam F The type of the callback function.
|
||||||
* @tparam A The arguments from the state event that are calledback.
|
* @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.
|
* @param fn The function to be inokved on event trigger.
|
||||||
|
* @param event The event that is being subscribed to.
|
||||||
*/
|
*/
|
||||||
template<typename F, typename... A>
|
template<typename F, typename... A>
|
||||||
void useEvent(StateEvent<A...> &event, F fn) {
|
std::function<void()> useEvent(F fn, StateEvent<A...> &event) {
|
||||||
event._eventListeners[this].push_back(fn);
|
|
||||||
this->eventsSubscribed.push_back(&event);
|
// Create a listener structure
|
||||||
|
struct StateEventListener<A...> listener;
|
||||||
|
listener.listener = fn;
|
||||||
|
listener.owner = this;
|
||||||
|
listener.event = &event;
|
||||||
|
listener.unsubWithParams = [&](struct StateEventListener<A...> listener) {
|
||||||
|
auto itFound = listener.event->_eventListeners.begin();
|
||||||
|
while(itFound != listener.event->_eventListeners.end()) {
|
||||||
|
if(itFound->id == listener.id) {
|
||||||
|
listener.event->_eventListeners.erase(itFound);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++itFound++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
listener.id = event.stateEventId++;
|
||||||
|
listener.unsub = std::bind(listener.unsubWithParams, listener);
|
||||||
|
|
||||||
|
// Put that listener structure on to the event stack
|
||||||
|
event._eventListeners.push_back(listener);
|
||||||
|
this->eventsSubscribed.push_back(&event);
|
||||||
|
|
||||||
|
return listener.unsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
~StateOwner() {
|
virtual ~StateOwner() {
|
||||||
auto it = this->eventsSubscribed.begin();
|
auto it = this->eventsSubscribed.begin();
|
||||||
while(it != this->eventsSubscribed.end()) {
|
while(it != this->eventsSubscribed.end()) {
|
||||||
(*it)->_stateOwnerDestroyed(this);
|
(*it)->_stateOwnerDestroyed(this);
|
||||||
|
@ -9,8 +9,28 @@
|
|||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class StateOwner;
|
class StateOwner;
|
||||||
|
|
||||||
|
template<typename...A>
|
||||||
|
class StateEvent;
|
||||||
|
|
||||||
|
template<typename...A>
|
||||||
|
struct StateEventListener {
|
||||||
|
uint32_t id;
|
||||||
|
StateOwner *owner;
|
||||||
|
std::function<void(A...)> listener;
|
||||||
|
std::function<void(StateEventListener<A...>)> unsubWithParams;
|
||||||
|
std::function<void()> unsub;
|
||||||
|
StateEvent<A...> *event;
|
||||||
|
};
|
||||||
|
|
||||||
class IStateEvent {
|
class IStateEvent {
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Received notification from a state owner to let this state event know
|
||||||
|
* that it wishes to unsubscribe all the event listeners that it may have
|
||||||
|
* attached to this event.
|
||||||
|
*
|
||||||
|
* @param owner State owner that is being disposed.
|
||||||
|
*/
|
||||||
virtual void _stateOwnerDestroyed(StateOwner *owner) = 0;
|
virtual void _stateOwnerDestroyed(StateOwner *owner) = 0;
|
||||||
|
|
||||||
friend class StateOwner;
|
friend class StateOwner;
|
||||||
@ -19,12 +39,21 @@ namespace Dawn {
|
|||||||
template<typename...A>
|
template<typename...A>
|
||||||
class StateEvent : public IStateEvent {
|
class StateEvent : public IStateEvent {
|
||||||
protected:
|
protected:
|
||||||
|
uint32_t stateEventId = 0;
|
||||||
|
|
||||||
void _stateOwnerDestroyed(StateOwner *owner) override {
|
void _stateOwnerDestroyed(StateOwner *owner) override {
|
||||||
this->_eventListeners.erase(owner);
|
auto it = this->_eventListeners.begin();
|
||||||
|
while(it != this->_eventListeners.end()) {
|
||||||
|
if(it->owner == owner) {
|
||||||
|
it = this->_eventListeners.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::map<StateOwner*, std::vector<std::function<void(A...)>>> _eventListeners;
|
std::vector<StateEventListener<A...>> _eventListeners;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the event and emits to all of the listeners.
|
* Invokes the event and emits to all of the listeners.
|
||||||
@ -32,15 +61,22 @@ namespace Dawn {
|
|||||||
* @param args Arguments for this event to pass to the listeners.
|
* @param args Arguments for this event to pass to the listeners.
|
||||||
*/
|
*/
|
||||||
void invoke(A... args) {
|
void invoke(A... args) {
|
||||||
auto itListeners = this->_eventListeners.begin();
|
auto it = this->_eventListeners.begin();
|
||||||
while(itListeners != this->_eventListeners.end()) {
|
while(it != this->_eventListeners.end()) {
|
||||||
auto itLists = itListeners->second.begin();
|
it->listener(args...);
|
||||||
while(itLists != itListeners->second.end()) {
|
++it;
|
||||||
(*itLists)(args...);
|
|
||||||
++itLists;
|
|
||||||
}
|
|
||||||
++itListeners;
|
|
||||||
}
|
}
|
||||||
|
// 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;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,8 +7,13 @@
|
|||||||
#include "assert/assert.hpp"
|
#include "assert/assert.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
|
class IStateProperty {
|
||||||
|
public:
|
||||||
|
std::vector<std::function<void()>> _effectListners;
|
||||||
|
};
|
||||||
|
|
||||||
template<class V>
|
template<class V>
|
||||||
class StateProperty {
|
class StateProperty : public IStateProperty {
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Method that is invoked every time that the value of this state property
|
* Method that is invoked every time that the value of this state property
|
||||||
@ -31,7 +36,6 @@ namespace Dawn {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
V _realValue;
|
V _realValue;
|
||||||
std::vector<std::function<void()>> _effectListners;
|
|
||||||
V previous;
|
V previous;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@ void TicTacToeTile::onStart() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(tileState, cb);
|
useEffect(cb, { &tileState, &hovered });
|
||||||
useEffect(hovered, cb);
|
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
@ -17,6 +17,8 @@ namespace Dawn {
|
|||||||
class TicTacToeScene : public Scene {
|
class TicTacToeScene : public Scene {
|
||||||
protected:
|
protected:
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
|
StateProperty<int32_t> age;
|
||||||
|
StateEvent<int32_t> ageEvent;
|
||||||
|
|
||||||
void stage() override {
|
void stage() override {
|
||||||
camera = Camera::create(this);
|
camera = Camera::create(this);
|
||||||
|
Reference in New Issue
Block a user