mirror of https://github.com/deavmi/eventy.git
first commit
This commit is contained in:
commit
7e5e13a7de
|
@ -0,0 +1,15 @@
|
||||||
|
.dub
|
||||||
|
docs.json
|
||||||
|
__dummy.html
|
||||||
|
docs/
|
||||||
|
/eventdisp
|
||||||
|
eventdisp.so
|
||||||
|
eventdisp.dylib
|
||||||
|
eventdisp.dll
|
||||||
|
eventdisp.a
|
||||||
|
eventdisp.lib
|
||||||
|
eventdisp-test-*
|
||||||
|
*.exe
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.lst
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"authors": [
|
||||||
|
"Tristan B. Kildaire"
|
||||||
|
],
|
||||||
|
"copyright": "Copyright © 2020, Tristan B. Kildaire",
|
||||||
|
"description": "A minimal D application.",
|
||||||
|
"license": "proprietary",
|
||||||
|
"name": "eventdisp",
|
||||||
|
"targetType": "library"
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"fileVersion": 1,
|
||||||
|
"versions": {
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,181 @@
|
||||||
|
module eventy;
|
||||||
|
|
||||||
|
import core.thread : Thread;
|
||||||
|
import std.container.dlist : DList;
|
||||||
|
import core.sync.mutex : Mutex;
|
||||||
|
|
||||||
|
public class EventManager : Thread
|
||||||
|
{
|
||||||
|
/* List of signals than we can expect */
|
||||||
|
private Signal[] signals;
|
||||||
|
private Mutex signalMutex;
|
||||||
|
|
||||||
|
/* Recieved signals */
|
||||||
|
private DList!(ulong) signalInbox;
|
||||||
|
private Mutex signalInboxMutex;
|
||||||
|
|
||||||
|
this()
|
||||||
|
{
|
||||||
|
/* Initialize the signal queue */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event loop
|
||||||
|
*/
|
||||||
|
private void eventLoop()
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
/* Whether or not there is anything to process */
|
||||||
|
bool isEmpty;
|
||||||
|
|
||||||
|
/* The signal ID to be processed */
|
||||||
|
ulong currentID;
|
||||||
|
|
||||||
|
/* Lock the signal inbox */
|
||||||
|
signalInboxMutex.lock();
|
||||||
|
|
||||||
|
/* Check whether or not it is empty */
|
||||||
|
isEmpty = signalInbox.empty();
|
||||||
|
|
||||||
|
/* If it is not empty then dequeue a signal */
|
||||||
|
if(!isEmpty)
|
||||||
|
{
|
||||||
|
currentID = signalInbox.front();
|
||||||
|
signalInbox.removeFront(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the signal inbox */
|
||||||
|
signalInboxMutex.unlock();
|
||||||
|
|
||||||
|
/* Only process if we got something */
|
||||||
|
if(!isEmpty)
|
||||||
|
{
|
||||||
|
/* Find the matching Signal */
|
||||||
|
Signal matchingSignal = findSignal(currentID);
|
||||||
|
|
||||||
|
/* Get the Signal's Event(s) */
|
||||||
|
Event[] signalHandlers = matchingSignal.getEvents();
|
||||||
|
|
||||||
|
/* Dispatch all events */
|
||||||
|
foreach(Event signalHandler; signalHandlers)
|
||||||
|
{
|
||||||
|
/* Dispatch the current signal handler */
|
||||||
|
signalHandler.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a new Signal to the event loop that
|
||||||
|
* can then be triggered with signal(ulong id)
|
||||||
|
*/
|
||||||
|
public void attachSignal(Signal signal)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Signal findSignal(ulong id)
|
||||||
|
{
|
||||||
|
/* The matching Signal */
|
||||||
|
Signal matchingSignal;
|
||||||
|
|
||||||
|
/* Lock the signal registry */
|
||||||
|
signalMutex.lock();
|
||||||
|
|
||||||
|
/* Find the matching Signal */
|
||||||
|
foreach(Signal signal; signals)
|
||||||
|
{
|
||||||
|
if(signal.getID() == id)
|
||||||
|
{
|
||||||
|
matchingSignal = signal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unllcok the signal registry */
|
||||||
|
signalMutex.unlock();
|
||||||
|
|
||||||
|
return matchingSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends a signal by putting it in the signal queue
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void signal(ulong id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal
|
||||||
|
*
|
||||||
|
* A signal is associates a unique number (used to trigger
|
||||||
|
* the signal) with an event to be run on reception of the
|
||||||
|
* signal
|
||||||
|
*/
|
||||||
|
public final class Signal
|
||||||
|
{
|
||||||
|
/* The Event to trigger on reception of this signal */
|
||||||
|
private Event[] triggerEvents;
|
||||||
|
|
||||||
|
/* Unique signal ID */
|
||||||
|
private ulong ID;
|
||||||
|
|
||||||
|
/* Get the events */
|
||||||
|
public Event[] getEvents()
|
||||||
|
{
|
||||||
|
return triggerEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get this Signal's unique identifier */
|
||||||
|
public ulong getID()
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Event
|
||||||
|
{
|
||||||
|
/* The function to call when this event is ran */
|
||||||
|
private void function() handler;
|
||||||
|
|
||||||
|
/* Whether or not a new thread should be spwaned for running this event */
|
||||||
|
private bool spawnThread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new Event with the given function to be
|
||||||
|
* run, `handler`, and whether or not a new thread should
|
||||||
|
* be spawned to run the handler, `spawnThread`, which
|
||||||
|
* is `false` by default
|
||||||
|
*/
|
||||||
|
this(void function() handler, bool spawnThread = false)
|
||||||
|
{
|
||||||
|
this.handler = handler;
|
||||||
|
|
||||||
|
/* TODO: Handle `spwanThread` = true */
|
||||||
|
this.spawnThread = spawnThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
/* Call on this thread if spawnThread = false */
|
||||||
|
if(!spawnThread)
|
||||||
|
{
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
/* Call on a new thread if spawnThread = true */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Create the new thread with the handler function */
|
||||||
|
Thread eventHandlerThread = new Thread(handler);
|
||||||
|
|
||||||
|
/* Start the thread */
|
||||||
|
eventHandlerThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue