diff --git a/html/inc/bolt.inc b/html/inc/bolt.inc index 9652607617..bb325dccd9 100644 --- a/html/inc/bolt.inc +++ b/html/inc/bolt.inc @@ -11,37 +11,24 @@ ini_set('display_startup_errors', true); // - Different units may have the same logical name; // however, such units must be identical. -// A position in a course (i.e. the last item viewed) is described by -// 1) a "path" - a list of names. -// 2) an associative array mapping name to state structures. -// e.g. a loop counter -// Typically this includes the logical name of the current child. -// Normally this is implied by the state; -// however, it may differ if the course structure has changed. -// In general the unit should restart in this case +// A state in a course is described by an associative array +// mapping logical names to state structures. +// Typically this includes the logical name of the current child +// and info such as a sequence index. abstract class BoltUnit { public $name; // logical name. + public $is_item; - abstract function walk( - &$state, $old_path, &$new_path, $next, &$item, &$frac_done - ); + abstract function walk(&$iter, $incr, &$frac_done); // multi-purpose function for traversing a course. - // if $old_path is null - // This unit is being started; - // append names to $new_path for this unit and descendants - // $next is ignored - // $item is the initial item - // return is ignored - // else - // This unis is being resumed in the middle. - // The first entry in $old_path is for this unit. - // Check for name mismatch (if changed course). - // Append names to $new_path for this unit and descendants - // if $next, the bottom-level non-item unit should increment. - // return value: true if the caller should increment + // Create entry in $iter->state if not there. + // Recurse to first child. + // If first child is an item, set $iter->item + // If incr is set + // the bottom-level non-item unit should increment. + // return value: true if the caller should increment // frac_done: Fraction done (of this unit and any subunits) - abstract function is_item(); } // An iterator represents a user's position in a course. @@ -49,52 +36,37 @@ abstract class BoltUnit { // and the course may change underneath it. // class BoltIter { - public $path; // array of names public $top; // topmost unit public $state; // state array + + // the following are temps public $item; // current item public $frac_done; // fraction done - // point to the start of a course; set up path. - // function __construct($top) { $this->top = $top; - $this->path = null; $this->state = array(); } function decode_state($encoded_state) { $this->state = json_decode($encoded_state, true); - print_r($this->state); - $this->path = $this->state['path']; } function encode_state() { - $this->state['path'] = $this->path; - print_r($this->state); return json_encode($this->state); } - // get current item + // get current item and fraction done // function at() { - $new_path = array(); - $this->top->walk($this->state, $this->path, $new_path, false, $item, $frac_done); - $this->path = $new_path; - $this->item = $item; - $this->frac_done = $frac_done; + $this->top->walk($this, false, $this->frac_done); } - // move to the next item (and return it) - // return true if we're off the end + // move to the next item, and return it in $this->item + // (null if course finished) // function next() { - $item = null; - $new_path = array(); - $this->top->walk($this->state, $this->path, $new_path, true, $item, $frac_done); - $this->path = $new_path; - $this->item = $item; - $this->frac_done = $frac_done; + $this->top->walk($this, true, $this->frac_done); } } @@ -103,24 +75,21 @@ class BoltSequence extends BoltUnit { function __construct($n, $u) { $this->name = $n; $this->units = $u; + $this->is_item = false; } - function walk(&$state, $old_path, &$new_path, $next, &$item, &$frac_done) { + function walk(&$iter, $incr, &$frac_done) { //echo "call to walk() for $this->name: next: $next\n"; $n = count($this->units); - if ($old_path) { - //echo "old path: \n"; - //var_dump($old_path); - //echo "------------\n"; - $child_name = $old_path[0]; - $state_rec = $state[$this->name]; - $i = $state_rec['i']; + if (array_key_exists($this->name, $iter->state)) { + $state_rec = $iter->state[$this->name]; + $child_name = $state_rec['child_name']; - // first, look up unit by name + // look up unit by name // $child = null; - for ($j=0; $j<$n; $j++) { - $c = $this->units[$j]; + for ($i=0; $i<$n; $i++) { + $c = $this->units[$i]; if ($c->name == $child_name) { $child = $c; break; @@ -130,6 +99,7 @@ class BoltSequence extends BoltUnit { // if not there, look up by index // if (!$child) { + $i = $state_rec['i']; if ($i >= $n) { // and if index is too big, use last unit // @@ -138,22 +108,21 @@ class BoltSequence extends BoltUnit { $child = $this->units[$i]; } - // at this point, $child is the right unit + // at this point, $child is the current unit, and $i is its index // - if ($next) { - $inc = false; - if ($child->is_item()) { - $inc = true; + if ($incr) { + $my_inc = false; + if ($child->is_item) { + $my_inc = true; } else { - array_shift($old_path); - $inc = $child->walk( - $state, $old_path, $new_path, true, $item, $frac_done - ); + $my_inc = $child->walk($iter, $incr, $frac_done); } - if ($inc) { + if ($my_inc) { $i++; if ($i == $n) { $frac_done = 1; + $state_rec['i'] = 0; + $iter->state[$this->name] = $state_rec; return true; } } @@ -161,23 +130,19 @@ class BoltSequence extends BoltUnit { } else { $i = 0; } - $frac_done = $i/$n; $child = $this->units[$i]; + $frac_done = $i/$n; $state_rec = null; $state_rec->i = $i; $state_rec->child_name = $child->name; - $new_path[] = $child->name; - $state[$this->name] = $state_rec; - if ($child->is_item()) { - $item = $child; + $iter->state[$this->name] = $state_rec; + if ($child->is_item) { + $iter->item = $child; } else { - $child->walk($state, null, $new_stack, false, $item, $f); + $child->walk($iter, false, $f); $frac_done += $f*(1/$n); } } - function is_item() { - return false; - } } class BoltItem extends BoltUnit { @@ -185,6 +150,7 @@ class BoltItem extends BoltUnit { function __construct($name, $filename) { $this->filename = $filename; $this->name = $name; + $this->is_item = true; } function begin() { return array(new BoltFrame($this)); @@ -192,10 +158,7 @@ class BoltItem extends BoltUnit { function unit_list() { return array(&$this); } - function is_item() { - return true; - } - function walk(&$state, $old_stack, &$new_stack, $next, &$item, &$frac_done) { + function walk(&$iter, $incr, &$frac_done) { echo "SHOULDN'T BE HERE\n"; } }