Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

ph33r

Visitor pattern, double despatching

This topic is 5098 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Those words scare me but that is what someone mentioned I need to use. EntityManager ------------- vector(Entity*) entitieList; void Send( int ENTID, enum MESSAGE, void* param1, void* param2 ); Entity ------ virtual Recieve( int ENTID, enum MESSAGE, void* param1, void* param2 ); Every object in the game is registered in the entity manager, and every object is derived from an Entity. When one object wants to send a message to another, it calls EntityManager::Send( id, message, param1, param2 ), The entity manager calls recieve on the entity and hat object it is calling needs to catch the message(or discard it). This is all fine an dandy but I'm using void* and c-style casts all over the place. I'd like to move this to template parameters and so every recieve function for each object in the game could have their own proper types. Someone said I need to use double despatching and the visitors pattern but left it at that and I have no idea where to start. [edited by - ph33r on June 8, 2004 2:41:40 PM]

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
bump

Share this post


Link to post
Share on other sites
quote:
I'm using void*
Don't do that.
quote:
and c-style casts all over the place.
Don't do that either. C++ casts are ugly in the hopes that it will make you not want to use casts. (it's a shame that C-style casts are still legal C++)
quote:
I'd like to move this to template parameters and so every recieve function for each object in the game could have their own proper types.
Templates are a fantastic solution to a lot of problems. This isn't one of those problems.
quote:
Someone said I need to use double despatching and the visitors pattern but left it at that and I have no idea where to start.
Visitor is a great solution to a problem that's completely different from yours.

It sounds like you've already done most of the hard work. All you need to do is make sure that your Entity::Receive method is virtual. (ideally, pure virtual) ent->Receive(...) will then call the correct method for whatever type a given entity happens to be.

"Without deviation, progress itself is impossible." -- Frank Zappa

[edited by - the speed bump on June 9, 2004 3:28:21 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by the Speed Bump
C++ casts are ugly in the hopes that it will make you not want to use casts. (it''s a shame that C-style casts are still legal C++)



What kind of dumb advice is that? Oh, you''re from Canada.

Share this post


Link to post
Share on other sites
quote:
Original post by PeterTarkus
What kind of dumb advice is that? Oh, you''re from Canada.


It''s not advice, the first half is fact and the second is opinion (and an opinion I share). I''m sure you''ve noticed the warning. Don''t post flamebait replies that don''t add any useful information to the topic.

Share this post


Link to post
Share on other sites
I ran into a similar problem with my event system.

Event.hpp
You''ll want to browse around to see how I did it, but I basically used type erasure to avoid vtable bloat.

Share this post


Link to post
Share on other sites
That code is great antareus, but I have no idea what it does.

The Speed Bump: I''m confused are you saying that Entity::Recieve prototype should look exactly like this?


class Entity
{
public:
// note the use of the elipse operator

virtual Recieve(...) = 0;
};


Then any derived class can put any types in there and any amount of arguements, and it will work correctly?

Share this post


Link to post
Share on other sites
quote:

class Entity
{
public:
// note the use of the elipse operator
virtual Recieve(...) = 0;
};


Then any derived class can put any types in there and any amount of arguements, and it will work correctly?


errrr no. I think I misunderstood your problem. Sorry about that.

If you want to be able to safely pass different parameters around for different messages, then Visitor is exactly what you need.

The basic idea is that the message to be consumed knows what it is, so it follows that it is able to send itself to a consumer. The consumer, then, can respond to an unknown message by sending it to itself.

struct Entity {
virtual void recieve(EntityMessage* msg) {
msg->visit(this);
}

virtual void recieveMoveMessage(MoveMessage* m) = 0;
virtual void recieveStopMessage(StopMessage* m) = 0;
};

struct EntityMessage {
virtual void visit(Entity* ent) = 0;
};

struct MoveMessage : EntityMessage {
virtual void visit(Entity* ent) {
ent->recieveMoveMessage(this);
}
};

struct StopMessage : EntityMessage {
virtual void visit(Entity* ent) {
ent->recieveStopMessage(this);
}
};


"Without deviation, progress itself is impossible." -- Frank Zappa

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!