20 #include <winpr/config.h>
22 #include <winpr/crt.h>
24 #include <winpr/collections.h>
45 wEventType* PubSub_GetEventTypes(wPubSub* pubSub,
size_t* count)
49 *count = pubSub->count;
51 return pubSub->events;
58 void PubSub_Lock(wPubSub* pubSub)
61 if (pubSub->synchronized)
62 EnterCriticalSection(&pubSub->lock);
65 void PubSub_Unlock(wPubSub* pubSub)
68 if (pubSub->synchronized)
69 LeaveCriticalSection(&pubSub->lock);
72 wEventType* PubSub_FindEventType(wPubSub* pubSub,
const char* EventName)
77 WINPR_ASSERT(EventName);
78 for (
size_t index = 0; index < pubSub->count; index++)
80 if (strcmp(pubSub->events[index].EventName, EventName) == 0)
82 event = &(pubSub->events[index]);
90 void PubSub_AddEventTypes(wPubSub* pubSub,
wEventType* events,
size_t count)
93 WINPR_ASSERT(events || (count == 0));
94 if (pubSub->synchronized)
97 while (pubSub->count + count >= pubSub->size)
102 new_size = pubSub->size * 2;
106 pubSub->size = new_size;
107 pubSub->events = new_event;
110 CopyMemory(&pubSub->events[pubSub->count], events, count *
sizeof(
wEventType));
111 pubSub->count += count;
114 if (pubSub->synchronized)
115 PubSub_Unlock(pubSub);
118 int PubSub_Subscribe(wPubSub* pubSub,
const char* EventName, ...)
122 WINPR_ASSERT(pubSub);
125 va_start(ap, EventName);
126 pEventHandler EventHandler = va_arg(ap, pEventHandler);
128 if (pubSub->synchronized)
131 event = PubSub_FindEventType(pubSub, EventName);
137 if (event->EventHandlerCount < MAX_EVENT_HANDLERS)
138 event->EventHandlers[
event->EventHandlerCount++] = EventHandler;
143 if (pubSub->synchronized)
144 PubSub_Unlock(pubSub);
150 int PubSub_Unsubscribe(wPubSub* pubSub,
const char* EventName, ...)
154 WINPR_ASSERT(pubSub);
155 WINPR_ASSERT(EventName);
158 va_start(ap, EventName);
159 pEventHandler EventHandler = va_arg(ap, pEventHandler);
161 if (pubSub->synchronized)
164 event = PubSub_FindEventType(pubSub, EventName);
170 for (
size_t index = 0; index <
event->EventHandlerCount; index++)
172 if (event->EventHandlers[index] == EventHandler)
174 event->EventHandlers[index] = NULL;
175 event->EventHandlerCount--;
176 MoveMemory((
void*)&event->EventHandlers[index],
177 (
void*)&event->EventHandlers[index + 1],
178 (MAX_EVENT_HANDLERS - index - 1) *
sizeof(pEventHandler));
184 if (pubSub->synchronized)
185 PubSub_Unlock(pubSub);
191 int PubSub_OnEvent(wPubSub* pubSub,
const char* EventName,
void* context,
const wEventArgs* e)
200 if (pubSub->synchronized)
203 event = PubSub_FindEventType(pubSub, EventName);
205 if (pubSub->synchronized)
206 PubSub_Unlock(pubSub);
212 for (
size_t index = 0; index <
event->EventHandlerCount; index++)
214 if (event->EventHandlers[index])
216 event->EventHandlers[index](context, e);
229 wPubSub* PubSub_New(BOOL
synchronized)
231 wPubSub* pubSub = (wPubSub*)calloc(1,
sizeof(wPubSub));
236 pubSub->synchronized =
synchronized;
238 if (pubSub->synchronized && !InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000))
250 WINPR_PRAGMA_DIAG_PUSH
251 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
253 WINPR_PRAGMA_DIAG_POP
257 void PubSub_Free(wPubSub* pubSub)
261 if (pubSub->synchronized)
262 DeleteCriticalSection(&pubSub->lock);
264 free(pubSub->events);