-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTecs_observer.hh
86 lines (72 loc) · 2.56 KB
/
Tecs_observer.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#pragma once
#include "Tecs_entity.hh"
#include "Tecs_permissions.hh"
#include <deque>
#include <memory>
#include <thread>
#include <tuple>
#include <type_traits>
namespace Tecs {
enum class EventType {
INVALID = 0,
ADDED,
REMOVED,
};
template<typename T>
struct ComponentEvent {
EventType type;
Entity entity;
T component;
ComponentEvent() : type(EventType::INVALID), entity(), component() {}
ComponentEvent(EventType type, const Entity &entity, const T &component)
: type(type), entity(entity), component(component) {}
};
struct EntityEvent {
EventType type;
Entity entity;
EntityEvent() : type(EventType::INVALID), entity() {}
EntityEvent(EventType type, const Entity &entity) : type(type), entity(entity) {}
};
/**
* An Observer is a handle to an event queue. The queue can be consumed from within any transaction. Observer
* handles should be local to a thread, and not shared.
*
* An Observer will persist until the ECS instance is decontructed, unless Observer::Stop() is called from within an
* AddRemove Transaction.
*/
template<typename ECSType, typename EventType>
class Observer {
public:
Observer() : ecs(nullptr) {}
Observer(ECSType &ecs, std::shared_ptr<std::deque<EventType>> &eventList)
: ecs(&ecs), eventListWeak(eventList) {}
/**
* Poll for the next event that occured. Returns false if there are no more events.
* Events will be returned in the order they occured, up until the start of the current transaction.
*/
bool Poll(Lock<ECSType> lock, EventType &eventOut) const {
auto eventList = eventListWeak.lock();
if (eventList && !eventList->empty()) {
eventOut = eventList->front();
eventList->pop_front();
return true;
}
return false;
}
void Stop(Lock<ECSType, AddRemove> lock) {
lock.StopWatching(*this);
}
operator bool() const {
return ecs != nullptr && !eventListWeak.expired();
}
friend bool operator==(const std::shared_ptr<std::deque<EventType>> &lhs,
const Observer<ECSType, EventType> &rhs) {
return lhs == rhs.eventListWeak.lock();
}
private:
ECSType *ecs;
std::weak_ptr<std::deque<EventType>> eventListWeak;
template<typename, typename...>
friend class Lock;
};
}; // namespace Tecs