izzum\statemachine\StateMachine::runToCompletion PHP Method

runToCompletion() public method

when using cyclic graphs, you could get into an infinite loop between states. design your machine correctly.
public runToCompletion ( string $message = null ) : integer
$message string optional message. this can be used by the persistence adapter to be part of the transition history to provide extra information about the transition.
return integer the number of sucessful transitions made.
    public function runToCompletion($message = null)
    {
        $transitions = 0;
        try {
            $run = true;
            while ($run) {
                // run the first transition possible
                $run = $this->run($message);
                if ($run) {
                    $transitions++;
                }
            }
        } catch (Exception $e) {
            $this->handlePossibleNonStatemachineException($e, $e->getCode());
        }
        return $transitions;
    }

Usage Example

 /**
  * @test
  */
 public function shouldBeAbleToStoreAndRetrieveData()
 {
     $redis = new Redis();
     $redis->setDatabase(15);
     //clear the redis database for testing
     $redis->flushdb();
     $machine = new StateMachine(new Context(new Identifier('1', 'test-machine'), null, $redis));
     //create the loader
     //get the configuration from the json file
     $configuration = file_get_contents(__DIR__ . '/../loader/fixture-example.json');
     //set it. normally, this would be done by a seperate process that has already loaded the configuration
     $redis->set(Redis::KEY_CONFIGURATION, $configuration);
     //load the machine
     $count = $redis->load($machine);
     //add the machine to the backend system
     $this->assertTrue($machine->add('this is the first addition'));
     $this->assertFalse($machine->add(), 'returns false, already added');
     $this->assertTrue($machine->run('this is a test run message'), 'succesful transitions so it returns true');
     $this->assertEquals('b', $machine->getCurrentState());
     $this->assertContains('1', $redis->getEntityIds('test-machine'));
     $this->assertTrue($machine->hasEvent('goToC'));
     try {
         $machine->goToC();
         $this->fail('should not come here');
     } catch (Exception $e) {
         $this->assertEquals(Exception::RULE_APPLY_FAILURE, $e->getCode());
     }
     $this->assertEquals('b', $machine->getCurrentState());
     //create new instance of same machine
     $machine2 = new StateMachine(new Context(new Identifier('1', 'test-machine'), null, $redis));
     $this->assertNotSame($machine2, $machine);
     $redis->load($machine2);
     $this->assertEquals('b', $machine2->getCurrentState(), 'should retrieve the same value');
     //create new instance of other machine
     $machine3 = new StateMachine(new Context(new Identifier('2', 'test-machine'), null, $redis));
     $this->assertNotSame($machine2, $machine3);
     $redis->load($machine3);
     $this->assertTrue($machine3->add());
     $this->assertNotEquals('b', $machine3->getCurrentState()->getName(), 'should not retrieve the same value as the other machine');
     $this->assertEquals('a', $machine3->getCurrentState()->getName(), 'initial state');
     //echo $machine3->toString(true);
     $this->assertEquals(2, $machine3->runToCompletion("go to the final state"));
     $this->assertEquals('done', $machine3->getCurrentState()->getName(), 'final state');
     $machine4 = new StateMachine(new Context(new Identifier('3', 'another-machine'), null, $redis));
     $a = new State('begin', State::TYPE_INITIAL);
     $b = new State('enter', State::TYPE_NORMAL);
     $c = new State('leave', State::TYPE_FINAL);
     $machine4->addTransition(new Transition($a, $b));
     $machine4->addTransition(new Transition($b, $c));
     $machine4->add('creating another machine to see that all goes well storing the data for multiple machines in redis');
     $this->assertEquals(2, $machine4->runToCompletion('running the machine to completion'));
     $ids = $redis->getEntityIds('test-machine');
     $this->assertEquals(array('1', '2'), $ids);
     $ids = $redis->getEntityIds('another-machine');
     $this->assertEquals(array('3'), $ids);
     $ids = $redis->getEntityIds('test-machine', 'done');
     $this->assertEquals(array('2'), $ids, 'only 2 was run to completion and in state done');
     $ids = $redis->getEntityIds('another-machine', 'leave');
     $this->assertEquals(array('3'), $ids, 'only 3 was run to completion and in state leave');
     //$redis->hmset("key" , array("name1" => "value1", "name2" => "value2"));
 }