Upgraded to new Tasky, now using fixed descriptor classes

This commit is contained in:
Tristan B. Velloza Kildaire 2022-05-24 23:04:49 +02:00
parent 60e333c3b3
commit 3bd59840fd
2 changed files with 151 additions and 38 deletions

View File

@ -5,8 +5,9 @@
"copyright": "Copyright © 2021, Tristan B. Kildaire",
"dependencies": {
"bformat": "3.1.3",
"dlog": "~>0.0.6",
"msgpack-d": "1.0.3",
"tasky": "1.0.3"
"tasky": "1.2.0"
},
"description": "Client-side DNET API",
"license": "LGPLv2",

View File

@ -5,10 +5,34 @@
module libdnet.libdnet;
import std.socket : Address, Socket;
import tasky.engine : Engine;
import tasky.engine : Engine, TaskyEvent;
import tasky.jobs : Descriptor;
import libdnet.messages.types;
import msgpack;
/* TODO: Remove this when we use the newer version of tasky (which uses TaskyEvent) */
import eventy.event : Event;
import dlog;
public class Client
{
/**
* Without __gshared, this would cause us to have a `logger` per-thread
* and statically init a new DefaultLogger() for each respective `logger` field
*
* This makes sure we have one `logger` field for ALL threads and therefore
* only one static initialization.
*
* Funnily enough if you wanted the opposite behaviour, omitting the `__gshared`
* will not help, DMD complains. One must make it explicit I guess with a
* static initialization block `static this()`.
*/
private __gshared static Logger logger = new DefaultLogger();
private Engine engine;
@ -16,7 +40,7 @@ public class Client
private Socket sock;
@ -33,53 +57,141 @@ public class Client
this.endpoint = endpoint;
/* Open socket here */
Socket sock = new Socket();
sock.connect(endpoint);
this.sock = new Socket();
/* Initialize a new Tasky engine */
engine = new Engine(sock);
/* Register handlers */
registerHandlers();
}
public enum SpecProtocolID : byte
{
NEWMESSAGE
}
/**
* Protocols
*/
private ulong[SpecProtocolID] ids;
/**
* Registers all of the handlers
*/
private final void registerHandlers()
{
/* Register the message handler */
Descriptor messageHandlerDesc = new class Descriptor
{
this()
{
super(0);
}
public override void handler_TaskyEvent(TaskyEvent e)
{
/* Call the entry point handler */
messageHandler_entry(e);
}
};
ids[SpecProtocolID.NEWMESSAGE] = messageHandlerDesc.getDescriptorClass();
/* TODO: Handler IDs must match the specifition so these should be set in sequence */
/**
* TODO: Only output when in debug mode
*/
logger.log("<<< Protocol specification breakdown >>>");
import std.conv : to;
foreach(SpecProtocolID specID; ids.keys())
{
logger.log("["~to!(string)(specID)~"] = "~to!(string)(ids[specID]));
}
}
unittest
{
logger.log("unittesting with null address family (no connect() call)");
Client c = new Client(null);
}
/**
* New message handler
*
* This is called whenever a new message arrives
*
* TODO: Switch to `TaskyEvent e`
*/
private final void messageHandler_entry(TaskyEvent e)
{
/* Get the payload */
ubyte[] eventPayload = cast(ubyte[])e.getPayload();
/* TODO: Check for msgpack errors */
/* Unpack the message */
EntityMessage message = unpack!(EntityMessage)(eventPayload);
/* Call the handler */
messageHandler(message);
}
/**
* Override this to provide your handler for new messages
*/
public void messageHandler(EntityMessage message)
{
import std.stdio;
writeln(message);
}
/**
* Authenicate with the server
*
* This is a handler that will get a unique descriptor
* for this given authentication attempt such that it
* matches up the reply, you want to ovveride authResponseHandler
*/
public void auth(string[] credentials)
{
/* TODO: Do auth */
/* TODO: Set the handler to `authResponseHandler` */
Descriptor desc;
/* TODO: Check if descriptor IDs available */
/* Get the descriptor ID */
desc.getDescriptorClass();
}
public void authResponseHandler()
{
}
/**
* Connect to the server
*/
public void connect()
public final void start()
{
/* TODO: Catch errors: Connect the socket to the endpoint host */
sock.connect(endpoint);
/* Start the Tasky engine */
engine.start();
}
/**
* Login
*/
public void login(string[] credentials)
{
}
/**
* Shutsdown the client
*/
public void shutdown()
{
/* TODO: Logout if not already logged out */
/* TODO: Get tasky to shutdown */
}
/* TODO: Hook ~this() onto shutdown() */
/**
* When the next cycle of the garbage collector
* runs and realises there is a zero-refcount
* to this object then shutdown the client
*/
~this()
{
/* Shutdown the client */
shutdown();
}
}