[ create a new paste ] login | about

Link: http://codepad.org/buFsu4dy    [ raw code | fork ]

k4st - PHP, pasted on May 27:
<?php

require_once dirname(__FILE__). '/__include__.php';
require_once dirname(__FILE__). '/linear-state-machine.php';

/**
 * Maintain a stack of queues to validate incoming states against a state
 * machine.
 */
class LinearStateValidator extends Stack implements Stateful {
    
    protected $machine, // the state machine
              $current; // the current state
    
    /**
     * Constructor, bring in a state machine.
     */
    public function __construct(LinearStateMachine $machine) {
        $this->push($machine->transitions);
    }
    
    /**
     * With an incoming state, check if it's valid.
     */
    public function valid($state) {
        
        // go over the next states. self::next handles entering and exiting
        // branches
        while(NULL !== ($current = $this->next())) {
            
            // the state is required
            if($current->type & LinearState::REQUIRED) {
                
                if($state == $current->state)
                    return TRUE;
                break;
            
            // the state is optional by definition of coming here. Check if
            // the state is the current state, and if so, we've validated,
            // otherwise repeat the check for the next state
            } else if($state == $current->state)
                return TRUE;
        }
        
        return FALSE;
    }
    
    public function current() {
        return $this->current;
    }
    
    /**
     * Advance to the next state. Deal with entering and exiting branches as
     * well.
     */
    public function next() {
        
        // go through the stack, pop off used up state queues on it. Push on
        // branch queues.
        $top = NULL;
        do {
            
            // the stack is empty, no states left. Once we've reached the last
            // state, self::$current will remain as the last state reached.
            if(0 === count($this))
                return NULL;
            
            // get the top queue on the stack
            $top = $this->top();
            
            // the current queue on the stack is empty, pop it off and repeat
            if(0 == count($top)) {
                $this->pop();
                continue;
            }
            
            // the current queue on the stack is not empty, get its first
            // state (the next state we might return) without shifting it off
            $next = $top->front();
            
            // the next state is actually a branch. If the branch isn't empty,
            // push it onto the stack. If the branch is empty, take it out of
            // the queue on the top of the stack and repeat. 
            if($next->type & LinearState::BRANCH) {
                                
                // empty branch, shift it out and continue to the next
                // iteration of this check
                if(0 === count($next)) {
                    $top->shift();
                    continue;
                }
                
                // the branch isn't empty, push it onto the stack and repeat.
                $this->push($next);
            
            // the first element in the queue on the top of the stack is a
            // normal state. Break out of the loop and return the state.
            } else
                break;
        
        // keep going until we find an unused state or until everything is off
        // the stack
        } while(1);
    
        // get the next state
        return ($this->current = $top->shift());
    }
}


Create a new paste based on this one


Comments: