MercuryMessaging
MercuryMessaging copied to clipboard
MercuryMessaging vs traditional event messaging via delegates
Hi @celvezio! It's Alex the undergrad; asking this here instead of in an email so it can be archived for reference (if the question ends up being useful).
When first going through the readme for MM I got slightly confused about the need the framework is addressing. (Later on I clicked through to your abstract on ACM and I think I get it now.)
But! Just for my own clarity:
Here's (roughly, this is pseudocode) an example of how past teams I've worked with would have handled event messaging in C#/Unity.
// stateful object in the gameworld
public class Node : Monobehaviour {
// lifecycle events
void Awake() {
// register self to messaging system
Messenger.DisableAllNodesHandler += OnDisableAllNodes;
this.SetActive(true);
}
void Destroy() {
// unregister self from messaging system
Messenger.DisableAllNodesHandler -= OnDisableAllNodes;
}
// actual callback
void OnDisableAllNodes() {
this.SetActive(false);
}
}
// 'messaging system' via a delegate
public class Messenger {
// 'disable nodes' event
public static delegate void DisableAllNodesHandler();
}
// 'game logic'
public class GameWorld {
static void Main() {
// initialize nodes in the scene
for (var i = 0; i < 20; i++) {
GameObject.Instantiate(Node);
}
// disable nodes in the scene via callback
Messenger.DisableAllNodesHandler();
}
}
Is the idea behind this framework to provide a wrapper component to gameobjects that obviates the need to explicitly add and register a callback method? (i.e. void OnDisableNodes
)
Aside from the fact that all possible events need to be hardcoded in ahead of time to the Messenger
class as delegates, this method has felt fairly flexible to me. (We used it widely, for instance, on Into the Dark: Narakan, a 4-years-in-dev Unity project, without much trouble.)
Looking at the quickstart example boilerplate,
GetComponent<MmRelayNode>().MmInvoke(MmMethod.SetActive, true,
new MmControlBlock(MmLevelFilterHelper.Default, MmActiveFilter.All,
default(MmSelectedFilter), MmNetworkFilter.Local));
And having only cursorily looked at the documentation, my sense is:
MmRelayNode
is functionally equivalent to Messenger
in my example (i.e. it's the actual event handler that observers are subscribing to)... OR I have it backwards and relay nodes are actually attached as components to observers. (But then what are they subscribing to?)
MmMethod.SetActive, true
looks a little bit like automagic--SetActive(true)
will be invoked on observer instances, but how is MmMethod
's SetActive
related to Monobehaviour
's SetActive
? Where is it defined?
MmControlBlock
looks like it adds secondary functionality--it enables filtering through and sampling more precisely which observers you want to target with a message broadcast from the subscribed to controller.
Finally, for reference here's a quote from your ACM abstract:
When components need to communicate horizontally, programmers must connect those components manually and register/unregister events as needed. Moreover, events and callback signatures may be incompatible, making modular UIs cumbersome to build and share within or across applications.
The upshot of all this:
MercuryMessaging automates and abstracts out the Awake()
and Destroy()
portions of my example; and by abstracting the need for hardcoded event handlers/delegates directly addresses the incompatible callback problem. (Do I have that right?)
So, my outstanding question is, is there a catch? (Which to some degree I think you've addressed here.)
But then there's also this asynchronous UNET/networking component I haven't even started looking into yet--Is there possibly a UML diagram somewhere that points out all the relationships between different parts of the framework?
I hope this wasn't too lengthy, thank you for your time!
-Alex