开发者

How to convert my state machine to java?

开发者 https://www.devze.com 2023-02-19 19:48 出处:网络
Here is the normal way I would do things in C++: class object { public: enum { STATE_ACTIVE = 0, STATE_INACTIVE,

Here is the normal way I would do things in C++:

class object
{
public:
     enum
     {
          STATE_ACTIVE = 0,
          STATE_INACTIVE,

          OBJ_NUM_STATES,
     }

     int   m_State;

     virtual void  UpdateState  ()
     {
           switch(this->m_state)
           {
           case STATE_ACTIVE:    /* do stuff*/    break;
           case STATE_INACTIVE:  /* do stuff*/    break;
           }
     }
}

class SpecialGameObjec开发者_开发问答t : public Object
{
public:
    enum
    {
         STATE_SPECIAL_A = OBJ_NUM_STATES + 1,
         STATE_SPECIAL_B,

         SPECIAL_NUM_STATES,
    }

    virtual void UpdateState ()
    {
         Object::UpdateState();

         switch(this->m_State)
         {
         case STATE_ACTIVE:       /* do extra stuff */   break;
         case STATE_SPECIAL_A:    /* do special stuff*/  break;
         case STATE_SPECIAL_B:    /* do special stuff*/  break;
         }
    }
}

I am trying to figure out to get all of this functionality to work in java. Specifically I need working:

1) Ability for derived classes to have state values that automatically line up after the derived state values. That way I can add new state values to the base class without worrying about them overlapping the rage of state values used in any of the derived classes.

2) Ability to use the state values as cases in switch statements.

I looked into using static final ints to implement my state values. But those can't be used as case statements. Then I looked into extending enums, but that isn't allowed.

Does anyone have any suggestions for me?

Thank you


You need to implement the state pattern in Java. This might help you. Wikipedia also has a simple and easy to understand example in Java.


Is this enough to get you going?

final class GameObject {

  enum State { ACTIVE, INACTIVE };

  State state;

  void updateState()
  {
    switch(state) {
      case ACTIVE :
        // update state
        break;
      case INACTIVE:
        // update STATE
        break;
      default:
        assert false : "never get here";
    }
  } 
}

Note that in Java, enums are final so you can't extend an enum directly. (Reference this SO question.) If you really need to extend the notion of state into specialized subclasses, things are probably complicated enough that you should consider using polymorphism rather than switch statements (see also here) to get what you want. Alternatively, you could bundle the "super" state with specialized substates in a wrapper super- and sub-classes, perhaps with defined interfaces.

And, if you want to get seriously warped, you could do something like this. It's very cool that Java enums can implement interfaces, but I think this counts as a particularly ugly way of using that feature for your question...

final class GameObject {

  ActiveStateful state;

  interface ActiveStateful {
    State activeState();
  }

  enum State implements ActiveStateful {
    ACTIVE, INACTIVE;

    public State activeState() {
      return this;
    }
  };

  enum SubState implements ActiveStateful {
    SPECIAL_A(State.ACTIVE), SPECIAL_B(State.ACTIVE);

    SubState(final State activeState) {
      this.activeState = activeState;
    }

    final State activeState;

    public State activeState() {
      return activeState;
    }

  }

}


But those can't be used as case statements.

If I told you this was incorrect, that would solve your problems, yes? This is incorrect: you can switch on static final int constants.


I'd recommend using an enum and its ordinal values for switch statements. That's what enum was born for.


Please consider getting rid of switch altogether. It is a horrible abomination that should have ceased decades ago but didn’t. Read the excellent “Abandoning switch In Three (And A Bit) Steps” article for more information.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号