Skip to content

Commit 7ec24a9

Browse files
committed
Add event set in Messenger
1 parent f38870a commit 7ec24a9

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

render_pipeline/rppanda/showbase/messenger.hpp

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include <list>
4343
#include <unordered_map>
44+
#include <unordered_set>
4445
#include <functional>
4546

4647
#include <render_pipeline/rpcore/config.hpp>
@@ -65,6 +66,9 @@ class RENDER_PIPELINE_DECL Messenger : public TypedObject
6566
using AcceptorMap = std::unordered_map<const DirectObject*, AcceptorType>;
6667
using CallbacksType = std::unordered_map<EventName, AcceptorMap>;
6768

69+
using EventSetType = std::unordered_set<EventName>;
70+
using ObjectEventsType = std::unordered_map<const DirectObject*, EventSetType>;
71+
6872
public:
6973
static Messenger* get_global_instance();
7074

@@ -74,13 +78,16 @@ class RENDER_PIPELINE_DECL Messenger : public TypedObject
7478

7579
size_t get_num_listners() const;
7680
size_t get_num_listners(const EventName& event_name) const;
81+
size_t get_num_listners(const DirectObject* object) const;
7782

83+
/**
84+
* Returns a future that is triggered by the given event name. This
85+
* will function only once.
86+
*/
7887
AsyncFuture* get_future(const EventName& event_name) const;
7988

8089
/**
8190
* Add the method to hook with given event name.
82-
*
83-
* @return Iterator of callbacks.
8491
*/
8592
void accept(const EventName& event_name, const EventFunction& method, const DirectObject* object,
8693
bool persistent = true);
@@ -97,7 +104,7 @@ class RENDER_PIPELINE_DECL Messenger : public TypedObject
97104
void ignore_all(const DirectObject* object);
98105

99106
/** Returns the list of all events accepted by the indicated object. */
100-
std::vector<EventName> get_all_accepting(const DirectObject* object) const;
107+
const EventSetType& get_all_accepting(const DirectObject* object) const;
101108

102109
/** Is this object accepting this event? */
103110
bool is_accepting(const EventName& event_name, const DirectObject* object) const;
@@ -137,8 +144,10 @@ class RENDER_PIPELINE_DECL Messenger : public TypedObject
137144

138145
EventHandler* handler_;
139146
CallbacksType callbacks_;
147+
ObjectEventsType object_events_;
140148

141149
static const AcceptorMap empty_acceptor_;
150+
static const EventSetType empty_events_;
142151

143152
public:
144153
static TypeHandle get_class_type();
@@ -169,6 +178,15 @@ inline size_t Messenger::get_num_listners(const EventName& event_name) const
169178
return 0;
170179
}
171180

181+
inline size_t Messenger::get_num_listners(const DirectObject* object) const
182+
{
183+
const auto found = object_events_.find(object);
184+
if (found != object_events_.end())
185+
return found->second.size();
186+
else
187+
return 0;
188+
}
189+
172190
inline AsyncFuture* Messenger::get_future(const EventName& event_name) const
173191
{
174192
return handler_->get_future(event_name);
@@ -183,8 +201,15 @@ inline void Messenger::ignore(const EventName& event_name, const DirectObject* o
183201
auto& acceptor_map = found->second;
184202
auto acceptor_map_found = acceptor_map.find(object);
185203
if (acceptor_map_found != acceptor_map.end())
204+
{
186205
acceptor_map.erase(acceptor_map_found);
187206

207+
auto& event_set = object_events_.at(object);
208+
event_set.erase(event_name);
209+
if (event_set.empty())
210+
object_events_.erase(object);
211+
}
212+
188213
if (acceptor_map.empty())
189214
remove_hook(event_name);
190215
}
@@ -200,33 +225,28 @@ inline void Messenger::ignore_all(const EventName& event_name)
200225

201226
inline void Messenger::ignore_all(const DirectObject* object)
202227
{
203-
auto iter = callbacks_.begin();
204-
const auto iter_end = callbacks_.end();
205-
while (iter != iter_end)
228+
auto found = object_events_.find(object);
229+
if (found == object_events_.end())
230+
return;
231+
232+
for (const auto& event_name: found->second)
206233
{
207-
auto& acceptor_map = iter->second;
208-
auto found = acceptor_map.find(object);
209-
if (found != acceptor_map.end())
210-
acceptor_map.erase(found);
211-
212-
// iterator becomes invalidated after erase.
213-
auto iter_tmp = iter;
214-
++iter;
215-
if (iter_tmp->second.empty())
216-
remove_hook(iter_tmp->first);
234+
auto callback_found = callbacks_.find(event_name);
235+
callback_found->second.erase(object);
236+
if (callback_found->second.empty())
237+
remove_hook(event_name);
217238
}
239+
240+
object_events_.erase(object);
218241
}
219242

220-
inline auto Messenger::get_all_accepting(const DirectObject* object) const -> std::vector<EventName>
243+
inline auto Messenger::get_all_accepting(const DirectObject* object) const -> const EventSetType&
221244
{
222-
std::vector<EventName> events;
223-
for (const auto& kv : callbacks_)
224-
{
225-
const auto& acceptor_map = kv.second;
226-
if (acceptor_map.find(object) != acceptor_map.end())
227-
events.push_back(kv.first);
228-
}
229-
return events;
245+
auto found = object_events_.find(object);
246+
if (found == object_events_.end())
247+
return empty_events_;
248+
else
249+
return found->second;
230250
}
231251

232252
inline bool Messenger::is_accepting(const EventName& event_name, const DirectObject* object) const
@@ -298,6 +318,7 @@ inline void Messenger::clear()
298318
for (auto&& kv : callbacks_)
299319
handler_->remove_hook(kv.first, process_event, this);
300320
callbacks_.clear();
321+
object_events_.clear();
301322
}
302323

303324
inline bool Messenger::is_empty() const

src/rppanda/showbase/messenger.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
namespace rppanda {
4343

4444
const Messenger::AcceptorMap Messenger::empty_acceptor_;
45+
const Messenger::EventSetType Messenger::empty_events_;
4546

4647
TypeHandle Messenger::type_handle_;
4748

@@ -85,6 +86,8 @@ void Messenger::accept(const EventName& event_name, const EventFunction& method,
8586

8687
found->second = AcceptorType{ method, persistent };
8788
}
89+
90+
object_events_[object].insert(event_name);
8891
}
8992

9093
auto Messenger::who_accepts(const EventName& event_name) const -> const AcceptorMap&

0 commit comments

Comments
 (0)