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+
6872public:
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
143152public:
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+
172190inline 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
201226inline 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
232252inline 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
303324inline bool Messenger::is_empty () const
0 commit comments