Hi, I am attempting to make a high performance framework for Godot (C# only)

The end goal is a multithreaded game logic "engine" that uses godot for presentation.

PubSub.cs

My first feature is "done", and I would greatly appreciate feedback regarding usability.

Features

  1. Thread safe: supports any number of publishers and subscribers
  2. No allocations: sending/receiving messages doesn't allocate (no GC pressure).
  3. Pull, not push: Incoming Messages are enqueued for reading during the subscriber's update logic.
  4. No marshaling: stays in managed code land.

Godot already has this feature! (Signals)

The built-in godot signals workflow marshals back-and-forth between native and managed code. This PubSub is faster for C# to C# messaging.

Check it out

This is for CSharp developers: maybe later we could interop this with GDScript but I want to get a solid C# framework firstly.

Example use

Best to look at the code posted in the "check it out", but:

//Publisher:
var channel = pubSub.GetChannel<int>("myKey"); //create/get a channel for sending/receiving messages
channel.Publish(1);

//Subscriber:
var channel = pubSub.GetChannel<int>("myKey");  //create/get a channel for sending/receiving messages
var queue = new ConcurrentQueue<int>(); //create a thread safe queue that messages will be put in.
channel.Subscribe(queue); //now whenever a publish occurs, the queue will get the message

while(queue.TryDequeue(out var message)){ Console.Writeline(message); }  //do work with the message

My own "self critique"

The subscriber needs to discover the PubSub Channel's key and message type. I don't see an easy solution for this, so in my demo the subscriber reads static values from the publisher's class. This works but is verbose. Probably the workaround is to have a central registry (class) with all standard Channel keys+message types, but it's still pretty not ideal. Ideally, you could subscribe to a channel and consume it's messages without searching for either the key or message type.

Thanks, I'm working on a job system now, similar to what unity is using I think. I haven't used unity before but wrote a async node system for my old xna tech, so it shouldn't be very hard. What I'm concerned about is efficient communication back to godot (update movement, etc) but one problem at a time...

a year later

Okay I was playing around with this.

I have a specific issue that if you create a channel "foo" and then subscribe to it, grabbing messages from the queue empties it. This means if you would have to create a publishChannel for EACH subscriber, instead of on publisher and many subscribers.

Okay I am an idiot. I refactored the code to use the Channel implementation from System.Threading.Channels instead of using the Channel from ThreadStorm. x.x

a year later