I've finally implemented an extendable message class and messageServer class. The message class dynamically assigns a unique static ID to each derived message type (ex. ObjectCreatedMessage might be assigned id = 1). The actual message data is a member of the derived class.
Messages can be pushed to MessageServer class by upcasting to MessageBase*.
Systems (or anything) can subscribe to Message Server by passing a std::function to:
typedef std::function<void(MessageBase*)> Callback;
void registerCallback(int messageType, Callback callback);
When MessageServer is processing messages, it pops a message off the queue, checks the message type, then sends the message to each callback function registered to that type.
My Questions are:
- Is this efficient?
- How could I implement an "unregister" function? std::functions can't be compared by equality.
- What is a smart way to handle the callback failing? (perhaps the registered object went out of scope so the function pointer is undefined)
std::function
in another class that is derived from anICallback
base and have each derived type support a typeid retrieval system (as you did for the messages). Then you could use that thing to compareICallback
references/pointers more reliably. Or, if you're not talking about types, having a lock protectedid
generator static variable in theICallback
can help you manage unique, derived callback instances (not just by types). Would this be ok for you? (polymorphism isn't fast, but if you're not bothered by its minor performance hit, it's good enough) \$\endgroup\$