0
\$\begingroup\$

I'm currently working on a component based system for my game, and I've decided to use a messaging system to communicate between components. I've read some on the subject and it seems that most people are using message objects that extend on a base message object like so;

MySpecificMessage extends Message

or possibly they just have a single Message object which takes in a string variable that determines what it does, like so;

new Message("positionX:10"); //Plus other variables you might need

But I've also seen some implementations of this using statically defined integers as messages like so;

public static final int MySpecificMessage = 1; //Different numbers for different messages

Basically I'd like to know what the pros and cons are between them, and possibly when you'd use one over the other. Also, if you have any other type of messaging system please do share.

\$\endgroup\$
1
\$\begingroup\$

The syntax of your code snippets is Java, but this answer is from the perspective of C++ as that's what most game engines are written in.

Message Objects

Pros

Usability. Message objects are flexible and easy to debug. Since message objects names are known at runtime, you can easily print them, assert on them, etc. without having to write any reflection or other systems. In languages with built in reflection (C#, Java), this is less of a benefit.

Cons

Speed. Doing a string-compare for every message * every recipient sent is significantly slower than the alternatives.

Numbered Message Types

Pros

Speed! Numbered message types (plus sensible message handling with switch statements) means that messages can be quickly discarded.

Cons

Usability. If you define all your message-numbers in one file, that file is going to be referenced everywhere and modified constantly (by every member of the team) leading to frequent conflicts in merging. Additionally, at debugging-time, it may not be immediately obvious what each message is when you see them pass by.

Delegate Binding

I'm not really sure how you'd implement this in Java, but my preferred means of doing events is by attaching a delegate to a given message name (or type). The front-end code would look something like this:

In SomeClass.h

class SomeClass : Component
{
  void Initialize();
  void onSomeEvent(const SomeEvent &args);
}

class SomeEvent
{
public:
  GameObject sourceObject;
  int amount;
}

And in SomeClass.cpp

void SomeClass::Initialize()
{
  this.Owner.ConnectEvent(SomeEvent, onSomeEvent);
}
void SomeClass::onSomeEvent(const SomeEvent &args)
{
  // resolve the event here
}

Pros

Usability AND speed. Events can be created for free, without editing any extra files, events can be handled each in their own function rather without the need for a HandleEvent() function on every class, and (if it's set up correctly), it is every bit as fast as using integers for events.

Cons

Complicated to write in the first place. The back-end implementation is a bit tricky. ConnectEvent, in the above example, is actually a macro that expands to a template to construct the delegate. Furthermore, the event-listening system in the middle needs to be able to handle objects being after registering for events without segfaulting, and other hairy considerations.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.