Sign in to follow this  

Grouping Unrelated Stuff in C++

This topic is 4108 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

I'm trying to make a system in a single player text based game where you would give an object (like a player) a script and any parameters. The problem is I don't know how to pass multiple unknown types as a group in C++. Here's how I would do it in Java:
void runScript(String str, Object[] params){
  //not the best example, but hopefully communicates what I'm trying to do
  if(str.equals("buy")
  {
    if(params[0] instanceof Merchant)
    {
       // run a function for trading
       ((Merchant)params[0]).tradeWith(this);
    }
  }
}
Could anyone give me suggestions, or another way to do this? Thank you for your time and assistance.

Share this post


Link to post
Share on other sites
Quote:
Original post by mako_5
The problem is I don't know how to pass multiple unknown types as a group in C++.


If the types are completely unknown, you are more or less hosed, although you can follow ApochPiQ suggestion as a possible fix.

Quote:
Here's how I would do it in Java


It works in Java because all objects have a common base class. Such a design can be duplicated in C++ using a container of pointers to a common base class of the parameters you're going to use. Please note that pointers are necessary. Since you come from a Java background, boost::shared_ptr may be useful to approximate the behaviour of Java references.

Quote:
if(params[0] instanceof Merchant)


Capability queries can be a sign of poor design. Prefer calling common virtual member functions whenever possible.

Quote:
Could anyone give me suggestions, or another way to do this?


Here is the code that most closely duplicates your Java approach. Think twice before using it. If you can you tell us more about your system, we might be able to give you a better solution.


void runScript(const std::string& str, const std::vector<Object*>& params)
{
if(str == "buy")
{
if( Merchant* m = dynamic_cast<Merchant*>(params[0]) )
{
m->tradeWith(*this);
}
}
}

Share this post


Link to post
Share on other sites
What I was trying to do, was to make objects communicate through a general object passing system. All of these events or actions (whatever you want to call them), get handled in this order:

1:Characters / Items in rooms
2:Rooms
3:Locales (groups of rooms)
4:World

An unhandled event bubbles up to the next level of command:
unhandled character scripts get sent up to rooms, which if cannot handle send them to locales and finally to the world.

This prevents each of these components from being required to know directly about any other object. In an asteroids game (Java) I made, an object could request an explosion by sending an object like this to be collected by the script handler...

new GameEvent("particle system",new Object[]{"explosion",new Point(x,y)});


When the script system would loop through to find events objects want carried out, it takes this event and sends it to the destination object (the event collector has previously mapped strings to objects that can receive these generic commands).

The target, "particle system" then takes the command, interprets it, and then executes it if possible.

Perhaps using inheritance would be a better idea (like you mentioned virtual)...?
e.g.

//abstract base class
class ICommand{
public:
ICommand(const std::string& destination_){destination = destination_};
~ICommand(){};
virtual void execute()=0;

private;
std::string destination;
};


class MakeExplosionCommand{
public:
MakeExplosionCommand(const std::string& std::string destination, float locX, float locY);
//etc...
///*virtual*/ provided to remind programmer that yeah, it's virtual
/*virtual*/ void execute();
};

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Capability queries can be a sign of poor design. Prefer calling common virtual member functions whenever possible.


Agreed. Good polymorphism is almost always better design than if statements.

Share this post


Link to post
Share on other sites
Quote:
Original post by mako_5
An unhandled event bubbles up to the next level of command:
unhandled character scripts get sent up to rooms, which if cannot handle send them to locales and finally to the world.


So you have something like a Chain of Responsibility pattern.

Quote:
When the script system would loop through to find events objects want carried out, it takes this event and sends it to the destination object (the event collector has previously mapped strings to objects that can receive these generic commands).


Then I think you are looking from the wrong end of the problem. Typically, an object knows what kind of events it is able to handle, rather than having an event know what kind of objects it can be handled by.

Quote:
The target, "particle system" then takes the command, interprets it, and then executes it if possible.


See above. In your example, you should ask the target object to handle a "buy" event, rather than ask it whether it is a Merchant.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
See above. In your example, you should ask the target object to handle a "buy" event, rather than ask it whether it is a Merchant.


Thanks for the help Fruny. I now see exactly what you're talking about. I'll get started on the event hierarchy now...

Share this post


Link to post
Share on other sites

This topic is 4108 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this