Home > Articles > Programming > C/C++

  • Print
  • + Share This
Like this article? We recommend

Like this article? We recommend

Coding the States

Here’s the code for the NumberEntry state:

class NumberEntryState : public FSMState<Calculator> {
protected:
  string accum;
public:

  NumberEntryState(Calculator *adriver) :
    FSMState<Calculator>(adriver, "NumberEntryState") { }

  void OnEntry() {
    Append();
  }

  FSMStateBase *HandleEvent() {
    if (isIn("01234567890.Ee")) {
      Append();
      return this;
    }
    else if (isIn("+-*/")) {
      ParseAndPush();
      return driver->getState("OperatorState");
    }
    else if (isIn("=")) {
      ParseAndPush();
      return driver->getState("EqualsState");
    }
    else {
      return driver->getState("ErrorState");
    }
  }

  void Append() {
    accum += Current;
  }

  void ParseAndPush() {
    double x = strtod(accum.c_str(), NULL);
    accum = "";
    driver->PostFixQueue.push(new CalcStackItem(x));
  }
};

Notice the parts involved. The OnEntry function gets called whenever the machine enters this state. There’s also a HandleEvent method, which handles all incoming characters. Inside the HandleEvent method, I just have an if statement that checks what character comes in. I wrote my own isIn function to check whether a character is in a string. Such functions already exist in the runtime library, but this one is specifically for this purpose.

Look at the different parts of the if block. The first part checks whether I received a digit or a decimal point, or a capital or lowercase E. If so, I perform the action described in the table, and the same for all the different possible events.

Additionally, I provided my two custom methods that serve as the actions—the Append function and the ParseAndPush function. Of course, the Append function is just a single line, so I could have just used that one line in place of calling Append; either is fine.

As for how the methods in this class get called, that’s the easy part. As you’ll see when I show you the rest of the code, you have to create the instance of this class, but the framework does the rest of the work, calling your methods for you.

  • + Share This
  • 🔖 Save To Your Account