libwinpr-utils: start implementing Publisher/Subscriber pattern
This commit is contained in:
parent
010f1dfdd9
commit
174d1bdd71
@ -339,6 +339,26 @@ WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode);
|
||||
WINPR_API wMessagePipe* MessagePipe_New(void);
|
||||
WINPR_API void MessagePipe_Free(wMessagePipe* pipe);
|
||||
|
||||
/* Publisher/Subscriber Pattern */
|
||||
|
||||
struct _wEventArgs
|
||||
{
|
||||
DWORD size;
|
||||
};
|
||||
typedef struct _wEventArgs wEventArgs;
|
||||
|
||||
typedef void (*pEventHandler)(void* context, wEventArgs* e);
|
||||
|
||||
struct _wPubSub
|
||||
{
|
||||
HANDLE mutex;
|
||||
BOOL synchronized;
|
||||
};
|
||||
typedef struct _wPubSub wPubSub;
|
||||
|
||||
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
|
||||
WINPR_API void PubSub_Free(wPubSub* pubSub);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@ set(MODULE_PREFIX "WINPR_UTILS")
|
||||
set(${MODULE_PREFIX}_COLLECTIONS_SRCS
|
||||
collections/Queue.c
|
||||
collections/Stack.c
|
||||
collections/PubSub.c
|
||||
collections/Reference.c
|
||||
collections/ArrayList.c
|
||||
collections/Dictionary.c
|
||||
|
74
winpr/libwinpr/utils/collections/PubSub.c
Normal file
74
winpr/libwinpr/utils/collections/PubSub.c
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Publisher/Subscriber Pattern
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/collections.h>
|
||||
|
||||
/**
|
||||
* Properties
|
||||
*/
|
||||
|
||||
int PubSub_Property(wPubSub* pubSub)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods
|
||||
*/
|
||||
|
||||
void PubSub_Method(wPubSub* pubSub)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
|
||||
wPubSub* PubSub_New(BOOL synchronized)
|
||||
{
|
||||
wPubSub* pubSub = NULL;
|
||||
|
||||
pubSub = (wPubSub*) malloc(sizeof(wPubSub));
|
||||
|
||||
if (pubSub)
|
||||
{
|
||||
pubSub->synchronized = synchronized;
|
||||
|
||||
if (pubSub->synchronized)
|
||||
pubSub->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
}
|
||||
|
||||
return pubSub;
|
||||
}
|
||||
|
||||
void PubSub_Free(wPubSub* pubSub)
|
||||
{
|
||||
if (pubSub)
|
||||
{
|
||||
if (pubSub->synchronized)
|
||||
CloseHandle(pubSub->mutex);
|
||||
|
||||
free(pubSub);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
set(${MODULE_PREFIX}_TESTS
|
||||
TestQueue.c
|
||||
TestPrint.c
|
||||
TestPubSub.c
|
||||
TestArrayList.c
|
||||
TestCmdLine.c
|
||||
TestStreamPool.c
|
||||
|
104
winpr/libwinpr/utils/test/TestPubSub.c
Normal file
104
winpr/libwinpr/utils/test/TestPubSub.c
Normal file
@ -0,0 +1,104 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
typedef struct _MouseMotionEventArgs
|
||||
{
|
||||
wEventArgs e;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
|
||||
} MouseMotionEventArgs;
|
||||
|
||||
typedef void (*pMouseMotionEventHandler)(void* context, MouseMotionEventArgs* e);
|
||||
|
||||
void MouseMotionEventHandler(void* context, MouseMotionEventArgs* e)
|
||||
{
|
||||
printf("MouseMotionEvent: x: %d y: %d\n", e->x, e->y);
|
||||
}
|
||||
|
||||
struct _wEvent
|
||||
{
|
||||
const char* EventName;
|
||||
pEventHandler EventHandler;
|
||||
wEventArgs EventArgs;
|
||||
};
|
||||
typedef struct _wEvent wEvent;
|
||||
|
||||
static wEvent Events[] =
|
||||
{
|
||||
{ "MouseMotion", NULL, { sizeof(MouseMotionEventArgs) } },
|
||||
{ NULL, NULL, { 0 } },
|
||||
};
|
||||
|
||||
void ListExportedEvents(wEvent* events)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; events[i].EventName; i++)
|
||||
{
|
||||
printf("Event[%d]: %s\n", i, events[i].EventName);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterEventHandler(wEvent* events, const char* EventName, pEventHandler EventHandler)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; events[i].EventName; i++)
|
||||
{
|
||||
if (strcmp(events[i].EventName, EventName) == 0)
|
||||
{
|
||||
printf("Registering Event Handler for %s\n", EventName);
|
||||
events[i].EventHandler = EventHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerEvent(wEvent* events, const char* EventName, void* context, wEventArgs* e)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; events[i].EventName; i++)
|
||||
{
|
||||
if (strcmp(events[i].EventName, EventName) == 0)
|
||||
{
|
||||
printf("Triggering Event %s\n", EventName);
|
||||
|
||||
if (events[i].EventHandler)
|
||||
events[i].EventHandler(context, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TestPubSub(int argc, char* argv[])
|
||||
{
|
||||
wPubSub* nodeA;
|
||||
wPubSub* nodeB;
|
||||
|
||||
nodeA = PubSub_New(TRUE);
|
||||
nodeB = PubSub_New(TRUE);
|
||||
|
||||
ListExportedEvents(Events);
|
||||
|
||||
/* Register Event Handler */
|
||||
RegisterEventHandler(Events, "MouseMotion", (pEventHandler) MouseMotionEventHandler);
|
||||
|
||||
/* Call Event Handler */
|
||||
{
|
||||
MouseMotionEventArgs e;
|
||||
|
||||
e.x = 64;
|
||||
e.y = 128;
|
||||
|
||||
TriggerEvent(Events, "MouseMotion", NULL, (wEventArgs*) &e);
|
||||
}
|
||||
|
||||
PubSub_Free(nodeA);
|
||||
PubSub_Free(nodeB);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user