tristanable/source/tristanable/manager.d

147 lines
3.3 KiB
D
Raw Normal View History

module tristanable.manager;
import tristanable.watcher : Watcher;
2020-06-22 20:48:09 +02:00
import tristanable.request : Request;
import std.socket : Socket;
2020-06-22 22:21:33 +02:00
import core.sync.mutex : Mutex;
import bmessage : bSendMessage = sendMessage;
/* TODO: Watcher class to watch for stuff, and add to manager's queues */
/* TODO: maneger class to use commands on, enqueue and wait for dequeue */
public final class Manager
{
/* TODO: Insert queues here */
2020-06-22 20:48:09 +02:00
/**
* The queue of outstanding requests
*/
private Request[] requestQueue;
/**
* The associated Watcher object for this manager.
*/
private Watcher watcher;
2020-06-22 22:21:33 +02:00
/**
* The list mutex
*/
private Mutex queueMutex;
2020-06-22 22:25:58 +02:00
/**
* The remote host
*/
private Socket socket;
this(Socket endpoint)
{
2020-06-22 22:25:58 +02:00
/* Set the socket */
socket = endpoint;
2020-06-22 22:36:43 +02:00
2020-06-23 09:18:20 +02:00
/* Create the watcher */
watcher = new Watcher(this, endpoint);
2020-06-22 20:16:39 +02:00
2020-06-22 22:21:33 +02:00
/* Initialize the `requestQueue` mutex */
queueMutex = new Mutex();
2020-06-22 20:16:39 +02:00
/* Start the watcher */
watcher.start();
}
2020-06-22 20:48:09 +02:00
public void sendMessage(ulong tag, byte[] data)
{
2020-06-22 22:21:33 +02:00
/* Construct the message array */
byte[] messageData;
2020-06-22 22:36:43 +02:00
/* Add the `tag` bytes */
messageData ~= *(cast(byte*)&tag);
messageData ~= *(cast(byte*)&tag+1);
messageData ~= *(cast(byte*)&tag+2);
messageData ~= *(cast(byte*)&tag+3);
messageData ~= *(cast(byte*)&tag+4);
messageData ~= *(cast(byte*)&tag+5);
messageData ~= *(cast(byte*)&tag+6);
messageData ~= *(cast(byte*)&tag+7);
/* Add the `data` bytes (the actual message) */
messageData ~= data;
2020-06-22 22:21:33 +02:00
/* Send the message */
2020-06-22 22:36:58 +02:00
bSendMessage(socket, messageData);
2020-06-22 22:21:33 +02:00
/* Create a new Request */
Request newRequest = new Request(tag);
2020-06-23 01:07:17 +02:00
/* Lock the queue for reading */
lockQueue();
2020-06-22 22:21:33 +02:00
/* Add the request to the request queue */
2020-06-23 01:07:17 +02:00
requestQueue ~= newRequest;
/* Unlock the queue */
unlockQueue();
2020-06-22 20:48:09 +02:00
}
public bool isValidTag(ulong tag)
{
for(ulong i = 0; i < requestQueue.length; i++)
{
if(requestQueue[i].tag == tag)
{
return true;
}
}
return false;
}
public ulong getTagPosition(ulong tag)
{
for(ulong i = 0; i < requestQueue.length; i++)
{
if(requestQueue[i].tag == tag)
{
return i;
}
}
return 0;
}
2020-06-22 20:48:09 +02:00
public byte[] receiveMessage(ulong tag)
{
/* The received data */
byte[] receivedData;
/* Loop till fulfilled */
while(true)
{
/* Lock the queue for reading */
lockQueue();
/* Check if the request has been fulfilled */
if(requestQueue[getTagPosition(tag)].isFulfilled())
{
receivedData = requestQueue[getTagPosition(tag)].dataReceived;
break;
}
/* Unlock the queue */
unlockQueue();
}
return receivedData;
2020-06-22 20:48:09 +02:00
}
public Request[] getQueue()
{
2020-06-23 01:07:17 +02:00
return requestQueue;
2020-06-22 20:48:09 +02:00
}
public void lockQueue()
{
queueMutex.lock();
}
public void unlockQueue()
{
queueMutex.unlock();
}
}