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(&event->EventHandlers[index], &event->EventHandlers[index + 1],
177 (MAX_EVENT_HANDLERS - index - 1) *
sizeof(pEventHandler));
183 if (pubSub->synchronized)
184 PubSub_Unlock(pubSub);
190 int PubSub_OnEvent(wPubSub* pubSub,
const char* EventName,
void* context,
const wEventArgs* e)
199 if (pubSub->synchronized)
202 event = PubSub_FindEventType(pubSub, EventName);
204 if (pubSub->synchronized)
205 PubSub_Unlock(pubSub);
211 for (
size_t index = 0; index <
event->EventHandlerCount; index++)
213 if (event->EventHandlers[index])
215 event->EventHandlers[index](context, e);
228 wPubSub* PubSub_New(BOOL
synchronized)
230 wPubSub* pubSub = (wPubSub*)calloc(1,
sizeof(wPubSub));
235 pubSub->synchronized =
synchronized;
237 if (pubSub->synchronized && !InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000))
249 WINPR_PRAGMA_DIAG_PUSH
250 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
252 WINPR_PRAGMA_DIAG_POP
256 void PubSub_Free(wPubSub* pubSub)
260 if (pubSub->synchronized)
261 DeleteCriticalSection(&pubSub->lock);
263 free(pubSub->events);