javaLover javaLover - 17 days ago 6
C++ Question

Declare variable in switch case (enum of subcategory) - What is alternative?

I have a game with many types of

turret
, each type can simply denoted by enum.

Duplicate-code problem arise when there are subcategories of
turret
.

I currently code like this :-

switch(type_of_turret){
//category : SHOOTER
case SHOOTER_FIRE :
case SHOOTER_ICE :
{
float temperator=0;
switch(type_of_turret){ //duplicate switch case
case SHOOTER_FIRE : temperator=1000; break;
case SHOOTER_ICE : temperator=-1000; break;
}
temperator=sinWave(temperator,time); //(Edit) an example of calculation
shoot(rigidBody,temperator);
}break;
//category : PROPULSION
......
break;
}


There are not so many types of
type_of_turret
(10 to 20), but the duplicating already looks bad for me.

If I can declare variable inside the switch (but not inside case), it would be nice :-

switch(type_of_turret){
float temperator=0; //neat but wrong syntax
case SHOOTER_FIRE : temperator=1000; /*break?*/ //neat
case SHOOTER_ICE : temperator=-1000; /*break?*/ //neat
temperator=sinWave(temperator,time); //(Edit) just an example
shoot(rigidBody,temperator); //neat
break;
....
break;
}


Question



How to make the code more neat?

Specifically, how can I imitate "the declaration variable inside switch-case" behavior?

My poor solution



Create class for each category, e.g.
Shooter
and
Propulsion
derived from
Turret
.

Then create subcategory of
Shooter
using enum or more derive classes.

Disadvantage: introduces unnecessary complexity, and performance may decrease (virtual function)

Edit (Another disadvantage): It breaks "no-method religious" of my Entity–Component–System as in the following quote :-


you’ll see that the methods for acting upon Components should all live inside the Systems, not the Components


http://t-machine.org/index.php/2007/12/22/entity-systems-are-the-future-of-mmog-development-part-3/

Reference



There are some similar questions on stackoverflow, e.g. Why can't variables be declared in a switch statement?, but none discuss what alternative approaches are.

Answer

As I said in a comment, do not be afraid of polymorphic classes with virtual functions. For example, I would define a virtual shoot() function in each turret sub class which takes care of the temperature, or even a virtual MyTemp():

class BaseTurretT
{   
    virtual int MyTemp() = 0;
    public:
    virtual void shootAt(RigidBodyT &rb)
    {
        // default implementation, may be overriden
        shoot(rb, MyTemp());
    }
    // ...
};

class HotTurretT: public BaseTurretT
{
    int MyTemp() { return 1000; }
    // ...
};

class ColdTurretT: public BaseTurretT
{
    int MyTemp() { return -1000; }
    // ...
};        

// more turrets in the future.

With these definitions, your whole switch collapses to a single line. Assume we have a vector of pointers to base turrets. The objects pointed to are of the various derived turrets, but the using code doesn't know and doesn't care:

RigidBodyT rb; 
vector<BaseTurretT *> turrets;
// ... 
for(BaseTurretT *turret: turrets)
{
    turret->shootAt(rb);    // no switch. No idea which turret type.
}

One of the best things of this design is its maintainability. If you want to add more turrets in the future (and looking at the way games evolve, that seems like a safe bet), you do not have to revisit the places where you use turrets. You just add a new class, and all the existing code takes care of itself.