Open GoogleCodeExporter opened 8 years ago
What you're bringing up is the balance between ease of understanding and ease
of use. I'd argue that you can more readily understand what's happening in the
existing message handling code because it's completely straightforward, if
slightly verbose.
I'm slightly hesitant to include boost as a dependency since I've had some
pretty miserable experiences with it in the past. That said, if it can be done
in an isolated and modular way to just provide the overload you mention, it
might be worth it. Would you be able to put together a patch showing exactly
what you're talking about?
Original comment by lieseg...@gmail.com
on 16 Mar 2013 at 8:42
Here is my patch; it's a helper class that uses boost::function and boost::bind
to allow redirecting messages to specific functions, functors, lambdas, and
members without any changes to the code base.
Usage is simple: for each message redirection, a MessageTrampoline is made,
assigned a function to call, and used anywhere a MessageListener is allowed.
Example:
theSwitchboard.SubscribeTo(_shootHook.Hook(this,&PlayerShip::Shoot), "Shoot");
Allows for the switchboard to directly redirect the message "shoot" to the
shoot member in PlayerShip of "this" instance.
I'd argue this is much easier to understand at a glance, as there is no "spooky
action at a distance"; the message goes directly to the place it should go,
with no intermediate and possibly error prone string checks. It's also just
much easier to use.
This design is different then my original design, but serves the same purpose,
requires no core changes, and is a little easier to read.
Possible improvements:
1. Current trampoline requires called functions to accept Message*; the point
of the trampoline is to reduce the need for message string operations, so I
feel an optimization for the special case where the message is utterly unneeded
would be appropriate (but would reduce code readability OR maintainability).
2. Creation of a MessageListenerManager that maintains a collection of
trampolines and allows for quick creation of hooks, to replace MessageListener
in classes which derive from MessageListener currently, which derives from
MessageListener and provides the same interface. This would allow for the
current model of deriving from MessageListener and passing "this" to
theSwitchboard to continue to work, while allowing a much easier syntax for the
extremely common case where a message ought to be redirected.
Possible example if Actor derived from MessageListenerManager:
theSwitchboard.SubscribeTo(this->Hook(this,&PlayerShip::Shoot), "Shoot");
theSwitchboard.SubscribeTo(this->Hook(this,&PlayerShip::Move), "Move");
etc
with the trampolines created automatically, and destroyed when the object
returns (as is the case now, and the case with data members of
MessageTrampoline, ensuring safety)
3. It'd be really nice if MessageListener's had a name. This is unrelated to
the rest of this, but messages have names, actors have names, all sorts of
things have names, but messages are sent with a name and a listener, and
there's no real way to log that listener because listeners do not have a name.
Also, it's a little strange that MessageListener is who sends messages, not
MessageSender or a related class. If MessageListener is also a Sender, it only
makes sense that there is some "pretty" way to identify them besides a raw
pointer.
If you need an example test case to demonstrate how MessageTrampoline works, I
will be happy to send you a small example.
Thanks!
Original comment by LoveOver...@gmail.com
on 17 Mar 2013 at 3:46
Attachments:
Original issue reported on code.google.com by
LoveOver...@gmail.com
on 16 Mar 2013 at 7:31