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.
Grouping Unrelated Stuff in C++
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:
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); } }}
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...
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();
};
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();
};
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement