libwinpr-utils: start implementing Publisher/Subscriber pattern

This commit is contained in:
Marc-André Moreau 2013-06-14 16:55:05 -04:00
parent 010f1dfdd9
commit 174d1bdd71
5 changed files with 200 additions and 0 deletions

View File

@ -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

View File

@ -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

View 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);
}
}

View File

@ -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

View 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;
}