11#pragma once
2- #ifndef _PURE_H_AAA_
3- #define _PURE_H_AAA_
42#include " xrCommon/xr_vector.h"
53
64// messages
108#define REG_PRIORITY_CAPTURE 0x7ffffffful
119#define REG_PRIORITY_INVALID 0xfffffffful
1210
13- typedef void __fastcall RP_FUNC (void * obj);
11+ using MessageFunction = void __fastcall (void * obj);
1412#define DECLARE_MESSAGE (name ) \
15- extern ENGINE_API RP_FUNC rp_##name; \
13+ extern ENGINE_API MessageFunction rp_##name; \
1614 struct ENGINE_API pure##name \
1715 { \
1816 virtual void On##name() = 0 ; \
1917 }
2018
2119#define DECLARE_RP (name ) \
2220 void __fastcall rp_##name(void * p) { ((pure##name*)p)->On ##name (); }
21+
2322DECLARE_MESSAGE (Frame); // XXX: rename to FrameStart
2423DECLARE_MESSAGE (FrameEnd);
2524DECLARE_MESSAGE (Render);
@@ -30,100 +29,101 @@ DECLARE_MESSAGE(AppEnd);
3029DECLARE_MESSAGE (DeviceReset);
3130DECLARE_MESSAGE (ScreenResolutionChanged);
3231
33- // -----------------------------------------------------------------------------
34- struct _REG_INFO
32+ struct MessageObject
3533{
3634 void * Object;
3735 int Prio;
3836 u32 Flags;
3937};
4038
41- // ENGINE_API extern int __cdecl _REG_Compare(const void *, const void *);
42-
43- template <class T >
44- class CRegistrator // the registrator itself
39+ template <class T >
40+ class MessageRegistry
4541{
46- // friend ENGINE_API int __cdecl _REG_Compare(const void *, const void *);
47- static int __cdecl _REG_Compare (const void * e1 , const void * e2 )
42+ bool changed, inProcess;
43+ xr_vector<MessageObject> messages;
44+
45+ static int __cdecl compare (const void * e1 , const void * e2 )
4846 {
49- _REG_INFO * p1 = (_REG_INFO *)e1 ;
50- _REG_INFO * p2 = (_REG_INFO *)e2 ;
51- return ( p2->Prio - p1->Prio ) ;
47+ MessageObject * p1 = (MessageObject *)e1 ;
48+ MessageObject * p2 = (MessageObject *)e2 ;
49+ return p2->Prio - p1->Prio ;
5250 }
5351
5452public:
55- xr_vector<_REG_INFO> R;
56- // constructor
57- struct
58- {
59- u32 in_process : 1 ;
60- u32 changed : 1 ;
61- };
62- CRegistrator ()
53+ MessageRegistry () : changed(false ), inProcess(false ) {}
54+
55+ void Clear () { messages.clear (); }
56+
57+ void Add (T* object, const int priority = REG_PRIORITY_NORMAL, const u32 flags = 0 )
6358 {
64- in_process = false ;
65- changed = false ;
59+ Add ({ object, priority, flags });
6660 }
6761
68- //
69- void Add (T* obj, int priority = REG_PRIORITY_NORMAL, u32 flags = 0 )
62+ void Add (MessageObject newMessage)
7063 {
7164#ifdef DEBUG
72- VERIFY (priority != REG_PRIORITY_INVALID);
73- VERIFY (obj);
74- for (u32 i = 0 ; i < R.size (); i++)
75- VERIFY (!((R[i].Prio != REG_PRIORITY_INVALID) && (R[i].Object == (void *)obj)));
65+ VERIFY (newMessage.Object );
66+ VERIFY (newMessage.Prio != REG_PRIORITY_INVALID);
67+
68+ // Verify that we don't already have the same object with valid priority
69+ for (auto & message : messages)
70+ VERIFY (!(message.Prio != REG_PRIORITY_INVALID && message.Object == newMessage.Object ));
7671#endif
77- _REG_INFO I;
78- I.Object = obj;
79- I.Prio = priority;
80- I.Flags = flags;
81- R.push_back (I);
72+ messages.emplace_back (newMessage);
8273
83- if (in_process )
74+ if (inProcess )
8475 changed = true ;
8576 else
8677 Resort ();
87- };
88- void Remove (T* obj)
78+ }
79+
80+ void Remove (T* object)
8981 {
90- for (u32 i = 0 ; i < R. size (); i++ )
82+ for (auto & it : messages )
9183 {
92- if (R[i] .Object == obj )
93- R[i] .Prio = REG_PRIORITY_INVALID;
84+ if (it .Object == object )
85+ it .Prio = REG_PRIORITY_INVALID;
9486 }
95- if (in_process)
87+
88+ if (inProcess)
9689 changed = true ;
9790 else
9891 Resort ();
99- };
100- void Process (RP_FUNC* f)
92+ }
93+
94+ void Process (MessageFunction* func)
10195 {
102- in_process = true ;
103- if (R.empty ())
96+ if (messages.empty ())
10497 return ;
105- if (R[0 ].Prio == REG_PRIORITY_CAPTURE)
106- f (R[0 ].Object );
98+
99+ inProcess = true ;
100+
101+ if (messages[0 ].Prio == REG_PRIORITY_CAPTURE)
102+ func (messages[0 ].Object );
107103 else
108104 {
109- for (u32 i = 0 ; i < R. size (); i++ )
110- if (R[i] .Prio != REG_PRIORITY_INVALID)
111- f (R[i] .Object );
105+ for (auto & message : messages )
106+ if (message .Prio != REG_PRIORITY_INVALID)
107+ func (message .Object );
112108 }
109+
113110 if (changed)
114111 Resort ();
115- in_process = false ;
116- };
117- void Resort (void )
112+
113+ inProcess = false ;
114+ }
115+
116+ void Resort ()
118117 {
119- if (R.size ())
120- qsort (&*R.begin (), R.size (), sizeof (_REG_INFO), _REG_Compare);
121- while ((R.size ()) && (R[R.size () - 1 ].Prio == REG_PRIORITY_INVALID))
122- R.pop_back ();
123- if (R.empty ())
124- R.clear ();
118+ if (!messages.empty ())
119+ qsort (&messages.front (), messages.size (), sizeof (MessageObject), compare);
120+
121+ while (!messages.empty () && messages.back ().Prio == REG_PRIORITY_INVALID)
122+ messages.pop_back ();
123+
124+ if (messages.empty ())
125+ messages.clear ();
126+
125127 changed = false ;
126- };
128+ }
127129};
128-
129- #endif
0 commit comments