Question

I have a Sensor state machine for which I've written Cycle() methods:

  /// <summary>
  /// Cycle sets the machine to follow a path from one it's current state to the next. The 
  /// behavior of the sensor is to revert to it's default state should an invalid state be
  /// encountered.
  /// </summary>
  /// <returns></returns>
  public IState Cycle() {
     if(_currentState.Next.IsNullOrEmpty()) {
        _currentState = DefaultState.Set();
     } else {
        _currentState = _currentState.Cycle();
     }
     return _currentState;
  }

  public IEnumerator<IState> Cycle(Func<bool> HasWork) {
     while(HasWork()) {
        yield return Cycle();
     }
  }

Implementation:

  [TestMethod]
  public void SensorExperiment_CycleWhileFunc() {
     float offset = .5f;
     IState previousState = State.Empty;

     IStimulus temp = new PassiveStimulus(68f) {
        Offset = offset
     };
     ISensor thermostat = new Sensor(65f, 75f, temp);

     int cycles = 0;
     // using this func to tell the machine when to turn off
     Func<bool> hasWork = () => {
        previousState = thermostat.CurrentState;
        // run 10 cycles6
        return cycles++ < 10;
     };

     var iterator = thermostat.Cycle(hasWork);

     while(iterator.MoveNext()) {
        Console.WriteLine("Previous State: {0}\tCurrent State: {1}",
           previousState.Name, iterator.Current.Name);
     }
  }

I have read Eric Lippert's answer to an inquiry using the IEnumerator as a StateMachine. Is my implementation abusing or leveraging the use of an IEnumerator? I see my implementation as a way to provide automation of a sequence of states.

Was it helpful?

Solution

I don't think using it like this is really an abuse, after all, you treat the result most as a collection.

On the other hand, I don't see any reason why you should use iterator here. If you rewrote your code to something like the following, it should work the same.

while (hasWork())
    Console.WriteLine("Previous State: {0}\tCurrent State: {1}",
       previousState.Name, thermostat.Cycle().Name);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top