@@ -16,6 +16,16 @@ class CEventNotifierCallback
1616 virtual ~CEventNotifierCallback (){};
1717};
1818
19+ class CEventNotifierCallbackWithCid : public CEventNotifierCallback
20+ {
21+ private:
22+ const CID m_cid;
23+
24+ public:
25+ CEventNotifierCallbackWithCid (CID cid) : m_cid(cid), CEventNotifierCallback(){};
26+ CID GetCid () const { return m_cid; }
27+ };
28+
1929template <unsigned int CNT>
2030class CEventNotifier
2131{
@@ -41,6 +51,14 @@ class CEventNotifier
4151 xr_vector<CCallbackWrapper> m_callbacks;
4252 Lock m_lock;
4353
54+ CEventNotifierCallback::CID FindFreeCid ()
55+ {
56+ ScopeLock lock (&m_lock);
57+ auto it = std::find (m_callbacks.begin (), m_callbacks.end (), nullptr );
58+ return (it == m_callbacks.end ()) ? CEventNotifierCallback::INVALID_CID :
59+ std::distance (m_callbacks.begin (), it);
60+ }
61+
4462 public:
4563 CEventNotifierCallback::CID RegisterCallback (CEventNotifierCallback* cb)
4664 {
@@ -50,6 +68,28 @@ class CEventNotifier
5068 (it->callback .reset (cb), std::distance (m_callbacks.begin (), it));
5169 }
5270
71+ template <class CB , class ... Args>
72+ CEventNotifierCallback::CID CreateRegisteredCallback (Args&&... args)
73+ {
74+ static_assert (std::is_base_of<CEventNotifierCallbackWithCid, CB>::value);
75+
76+ ScopeLock lock (&m_lock);
77+
78+ auto cid = FindFreeCid ();
79+ CB* cb = new CB ((cid == CEventNotifierCallback::INVALID_CID) ? m_callbacks.size () : cid, args...);
80+
81+ if (cid == CEventNotifierCallback::INVALID_CID)
82+ {
83+ m_callbacks.emplace_back (cb);
84+ }
85+ else
86+ {
87+ m_callbacks[cid].callback .reset (cb);
88+ }
89+
90+ return cb->GetCid ();
91+ }
92+
5393 bool UnregisterCallback (CEventNotifierCallback::CID cid)
5494 {
5595 bool result = false ;
@@ -100,6 +140,13 @@ class CEventNotifier
100140 return m_callbacks[event_id].RegisterCallback (cb);
101141 }
102142
143+ template <class CB , class ... Args>
144+ CEventNotifierCallback::CID CreateRegisteredCallback (unsigned int event_id, Args&&... args)
145+ {
146+ R_ASSERT (event_id < CNT);
147+ return m_callbacks[event_id].CreateRegisteredCallback <CB>(args...);
148+ }
149+
103150 bool UnregisterCallback (CEventNotifierCallback::CID cid, unsigned int event_id)
104151 {
105152 R_ASSERT (event_id < CNT);
0 commit comments