-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevent.cpp
More file actions
173 lines (149 loc) · 4.69 KB
/
Copy pathevent.cpp
File metadata and controls
173 lines (149 loc) · 4.69 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "event.h"
#include <cstring>
EventInfo::EventInfo() :
str("")
{
// clear all memory
// memset((void*)data; 0; sizeof(data));
}
EventInfo::~EventInfo()
{
}
EventReciever::EventReciever()
{
}
EventReciever::~EventReciever()
{
// unplug any EventListeners that points to this object
for(EventListener* l = _listeners.first(); _listeners.canMove(); l = _listeners.next()){
if (l != 0)
l->_unplug();
}
}
// ----------- EventListener ---------------
// this class routes the event signal to the correct reciever
EventListener::EventListener(EventReciever *obj, callback_t callback) :
DListNode<EventListener *>(this),
_reciever(obj),
_sender(0),
_recieverNode(this),
_callback(callback),
_callbackEvt(0)
{
// add this object to recievers collection
_reciever->_listeners.push(_recieverNode);
}
EventListener::EventListener(EventReciever *obj, callbackEvt_t callback) :
DListNode<EventListener *>(this),
_reciever(obj),
_sender(0),
_recieverNode(this),
_callback(0),
_callbackEvt(callback)
{
_reciever->_listeners.push(_recieverNode);
}
EventListener::EventListener() :
DListNode<EventListener *>(this),
_reciever(0),
_sender(0),
_recieverNode(this),
_callback(0),
_callbackEvt(0)
{
}
EventListener &EventListener::operator= (const EventListener &other) {
if (this != &other){
_unplug();
_reciever = other._reciever;
_callback = other._callback;
_callbackEvt = other._callbackEvt;
_reciever->_listeners.push(_recieverNode);
}
return *this;
}
EventListener::~EventListener()
{
// disconnect from all as we are being deleted
//Serial.println(String("Destructor for:") + (int)this );
_unplug();
}
void EventListener::_unplug(){
// remove ourselves from sender and reciever collections so they can die in piece if they need to ;)
if (_sender != 0){
// compare with obj and callback not pointer references, operator comparisson doesnt seem to work, cant overload pointer comparisson?
for(size_t idx = 0; idx < _sender->_listeners.length(); ++idx){
if (_sender->_listeners[idx]->_reciever == _reciever &&
_sender->_listeners[idx]->_callback == _callback &&
_sender->_listeners[idx]->_callbackEvt == _callbackEvt)
{
_sender->_listeners.remove(idx);
_sender = 0;
//Serial.println(String(" dissconnecting from sender:") + (int)_sender + " with idx:" + idx);
break;
}
}
}
// the reciever always has a pointer to this object, as its get set on construction
if (_reciever != 0){
int32_t idx = _reciever->_listeners.indexOf(this);
//Serial.println(String(" dissconnecting from reciever:") + (int)_sender + " with idx:" + idx);
if (idx > -1) {
_reciever->_listeners.remove(idx);
_reciever = 0; _callback = 0; _callbackEvt = 0; // reset it back to virgin state this object is now unusable as a eventListener but at least it wont crash your app
}
}
}
void EventListener::_send(const EventInfo *evt /* = 0*/){
if (_reciever != 0) {
if (_callbackEvt != 0) {
//Serial.println(String("sending event to :") + (int)_reciever );
(_reciever->*_callbackEvt)(evt);
} else {
//Serial.println(String("sending event to :") + (int)_reciever );
(_reciever->*_callback)();
}
}
}
// -------------- EventSender class -----------------
EventSender::EventSender()
{
}
EventSender::~EventSender()
{
for(EventListener *l = _listeners.first(); _listeners.canMove(); l = _listeners.next()){
l->_unplug();
}
}
void EventSender::addListener(EventListener &listener){
// check so we dont add a connection to same object twice, you never now….
for(auto l = _listeners.first(); _listeners.canMove(); l = _listeners.next()){
if (l->_reciever == listener._reciever &&
l->_callback == listener._callback &&
l->_callbackEvt == listener._callbackEvt)
return; // we have already added a event connection to this same object and the same callback
}
// a new event we can safely connect it
listener._sender = this;
_listeners.push(listener);
}
// removes any listeners that points to the same reciever and reciever callback method
// the Listener object created here doesn't have to be the same object that was added to addListener
// deleteObj is used if the EventListener whas created with new
void EventSender::removeListener(EventListener &listener, bool deleteObj /*= false*/) {
listener._sender = this;
int32_t idx = _listeners.indexOf(&listener);
if (idx > -1){
EventListener* l = _listeners[idx];
l->_unplug();
if (deleteObj)
delete l;
}
}
// should only be called by the owner object
void EventSender::send(const EventInfo *evt /*= 0*/) {
//Serial.println(String("EventSender send _listeners count:") + _listeners.length());
for(EventListener *l = _listeners.first(); _listeners.canMove(); l = _listeners.next()){
l->_send(evt);
}
}