Boost logo

Boost Users :

From: Robert Dailey (rcdailey_at_[hidden])
Date: 2008-03-26 10:40:59


On Wed, Mar 26, 2008 at 2:03 AM, Kevin Scarr <kscarr_at_[hidden]> wrote:

> Steven Watanabe wrote:
> > You might also look into replacing Packet with boost::variant.
>
> I would second this. If you use:
>
> typedef boost::variant<WalkPacket,CharPacket,etc> Packet;
>
> You might also consider using pointers in your Packet type, or even
> shared_ptr<WalkPacket>, etc, but that is a detail which depends on how
> the rest of your application is built. I use pointer-like types because
> I am very aware of making copies of my potentially-large and numerous
> packets.
>
> In this situation, all of your messaging infrastructure that deals with
> packets passes around instances of the variant type.
>
> As you have described, your clients have a mechanism where they can
> register using wrapper functions around the signals library to receive
> notification on the arrival of specific packet types - one signal for
> each packet type.
>
> When it comes time to distribute your packet, you can make use of the
> boost::variant visitor feature, which allows you to select operations
> based on the actual type of the data in your variant instance. In your
> case it might look something like this:
>
> // Your packet type
> typedef boost::variant<WalkPacket,ChatPacket,etc> Packet;
>
> // Your signals...
> boost::signal<void (WalkerPacket)> distributeWalkerPacket;
> boost::signal<void (ChatPacket)> distributeChatPacket;
>
> // Helper class for apply_visitor
>
> class doDistributePacket : public static_visitor<>
> {
> public:
>
> void operator() ( WalkPacket p ) const
> {
> distributeWalkPacket( p );
> }
>
> void operator() ( ChatPacket p ) const
> {
> distributeChatPacket( p );
> }
>
> // and so on ...
> };
>
> // Free function to drive this above.
> void DistributePacket( Packet p )
> {
> apply_visitor( doDistributePacket(), p );
> }
>
>
>
> I like boost::variant because it tends to bring all the type-dependent
> code together and makes it easy to encapsulate type based decisions.
>
> Kevin

I love the logic presented here. boost::variant has always been confusing to
me, but I took the time just now to read over the documentation for it a few
times and I get it now. However, the issue still remains in how to organize
all of my signals. In your example you have all of the signals manually
typed out into separate variables, whereas I would rather have them in some
sort of container, such as a map. I couldn't put them in a std::map, since
the value type is always required to be the same. I could use boost::tuple
if I could guarantee that my packet ID's started at 0 and where contiguous
thereafter (however the size limit of a tuple would be too small). Something
like a tuple, except as a map would be a great solution. However since
someone has already pretty much addressed that no such container exists, I'm
still looking for clean alternatives. Consider that I may have 100 packet
types (which is not unreasonable in the game we're working on), it would
quickly become unmanageable to have 100 signal variables. Perhaps having 1
signal for all packets might be a good alternative, however I'd have to sit
down and think about how it is going to work. Using 1 signal for all
packets, as I pointed out before, really constrains the signature of the
slots. Perhaps I should just send the boost::variant to my slots?

Thanks everyone for your continued help. You're really giving me some great
ideas.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net