[LON-CAPA-cvs] cvs: loncom /interface lonnavmaps.pm

bowersj2 lon-capa-cvs@mail.lon-capa.org
Tue, 19 Aug 2003 15:29:33 -0000


This is a MIME encoded message

--bowersj21061306973
Content-Type: text/plain

bowersj2		Tue Aug 19 11:29:33 2003 EDT

  Modified files:              
    /loncom/interface	lonnavmaps.pm 
  Log:
  Fix bug 2057, documentation and some code updates.
  
  
--bowersj21061306973
Content-Type: text/plain
Content-Disposition: attachment; filename="bowersj2-20030819112933.txt"

Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.221 loncom/interface/lonnavmaps.pm:1.222
--- loncom/interface/lonnavmaps.pm:1.221	Thu Aug  7 13:26:44 2003
+++ loncom/interface/lonnavmaps.pm	Tue Aug 19 11:29:33 2003
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.221 2003/08/07 17:26:44 bowersj2 Exp $
+# $Id: lonnavmaps.pm,v 1.222 2003/08/19 15:29:33 bowersj2 Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -168,23 +168,17 @@
 
     # See if there's only one map in the top-level, if we don't
     # already have a filter... if so, automatically display it
+    # (older code; should use retrieveResources)
     if ($ENV{QUERY_STRING} !~ /filter/) {
         my $iterator = $navmap->getIterator(undef, undef, undef, 0);
-        my $depth = 1;
-        $iterator->next();
-        my $curRes = $iterator->next();
+        my $curRes;
         my $sequenceCount = 0;
         my $sequenceId;
-        while ($depth > 0) {
-            if ($curRes == $iterator->BEGIN_MAP()) { $depth++; }
-            if ($curRes == $iterator->END_MAP()) { $depth--; }
-            
+        while ($curRes = $iterator->next()) {
             if (ref($curRes) && $curRes->is_sequence()) {
                 $sequenceCount++;
                 $sequenceId = $curRes->map_pc();
             }
-            
-            $curRes = $iterator->next();
         }
         
         if ($sequenceCount == 1) {
@@ -202,16 +196,11 @@
         $jumpToFirstHomework = 1;
         # Find the next homework problem that they can do.
         my $iterator = $navmap->getIterator(undef, undef, undef, 1);
-        my $depth = 1;
-        $iterator->next();
-        my $curRes = $iterator->next();
+        my $curRes;
         my $foundDoableProblem = 0;
         my $problemRes;
         
-        while ($depth > 0 && !$foundDoableProblem) {
-            if ($curRes == $iterator->BEGIN_MAP()) { $depth++; }
-            if ($curRes == $iterator->END_MAP()) { $depth--; }
-
+        while (($curRes = $iterator->next()) && !$foundDoableProblem) {
             if (ref($curRes) && $curRes->is_problem()) {
                 my $status = $curRes->status();
                 if ($curRes->completable()) {
@@ -229,8 +218,6 @@
                     $ENV{'form.postsymb'} = $curRes->symb();
                 }
             }
-        } continue {
-            $curRes = $iterator->next();
         }
 
         # If we found no problems, print a note to that effect.
@@ -1185,18 +1172,13 @@
 
         # Step three: Ensure the folders are open
         my $mapIterator = $navmap->getIterator(undef, undef, undef, 1);
-        my $depth = 1;
-        $mapIterator->next(); # discard the first BEGIN_MAP
-        my $curRes = $mapIterator->next();
+        my $curRes;
         my $found = 0;
         
         # We only need to do this if we need to open the maps to show the
         # current position. This will change the counter so we can't count
         # for the jump marker with this loop.
-        while ($depth > 0 && !$found) {
-            if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; }
-            if ($curRes == $mapIterator->END_MAP()) { $depth--; }
-            
+        while (($curRes = $mapIterator->next()) && !$found) {
             if (ref($curRes) && $curRes->symb() eq $here) {
                 my $mapStack = $mapIterator->getStack();
                 
@@ -1210,8 +1192,6 @@
                 }
                 $found = 1;
             }
-            
-            $curRes = $mapIterator->next();
         }            
     }        
 
@@ -1249,15 +1229,11 @@
     # Note this does not take filtering or hidden into account... need
     # to be fixed?
     my $mapIterator = $navmap->getIterator(undef, undef, $filterHash, 0);
-    my $depth = 1;
-    $mapIterator->next();
-    my $curRes = $mapIterator->next();
+    my $curRes;
     my $foundJump = 0;
     my $counter = 0;
     
-    while ($depth > 0 && !$foundJump) {
-        if ($curRes == $mapIterator->BEGIN_MAP()) { $depth++; }
-        if ($curRes == $mapIterator->END_MAP()) { $depth--; }
+    while (($curRes = $mapIterator->next()) && !$foundJump) {
         if (ref($curRes)) { $counter++; }
         
         if (ref($curRes) && $jump eq $curRes->symb()) {
@@ -1268,8 +1244,6 @@
             $args->{'currentJumpIndex'} = $counter;
             $foundJump = 1;
         }
-        
-        $curRes = $mapIterator->next();
     }
 
     my $showParts = setDefault($args->{'showParts'}, 1);
@@ -1347,7 +1321,7 @@
                                                          $it->{FIRST_RESOURCE},
                                                          $it->{FINISH_RESOURCE},
                                                          {}, undef, 1);
-        $depth = 0;
+        my $depth = 0;
         $dfsit->next();
         my $curRes = $dfsit->next();
         while ($depth > -1) {
@@ -1379,9 +1353,6 @@
 
     my $displayedJumpMarker = 0;
     # Set up iteration.
-    $depth = 1;
-    $it->next(); # discard initial BEGIN_MAP
-    $curRes = $it->next();
     my $now = time();
     my $in24Hours = $now + 24 * 60 * 60;
     my $rownum = 0;
@@ -1389,10 +1360,8 @@
     # export "here" marker information
     $args->{'here'} = $here;
 
-    while ($depth > 0) {
-        if ($curRes == $it->BEGIN_MAP()) { $depth++; }
-        if ($curRes == $it->END_MAP()) { $depth--; }
-
+    $args->{'indentLevel'} = -1; # first BEGIN_MAP takes this to 0
+    while ($curRes = $it->next()) {
         # Maintain indentation level.
         if ($curRes == $it->BEGIN_MAP() ||
             $curRes == $it->BEGIN_BRANCH() ) {
@@ -1545,8 +1514,6 @@
             $r->rflush();
         }
     } continue {
-        $curRes = $it->next();
-
 	if ($r) {
 	    # If we have the connection, make sure the user is still connected
 	    my $c = $r->connection;
@@ -2184,18 +2151,9 @@
     my @resources = ();
 
     # Run down the iterator and collect the resources.
-    my $depth = 1;
-    $it->next();
-    my $curRes = $it->next();
-
-    while ($depth > 0) {
-        if ($curRes == $it->BEGIN_MAP()) {
-            $depth++;
-        }
-        if ($curRes == $it->END_MAP()) {
-            $depth--;
-        }
-        
+    my $curRes;
+
+    while ($curRes = $it->next()) {
         if (ref($curRes)) {
             if (!&$filterFunc($curRes)) {
                 next;
@@ -2208,8 +2166,6 @@
             }
         }
 
-    } continue {
-        $curRes = $it->next();
     }
 
     return @resources;
@@ -2285,6 +2241,13 @@
 
 =over 4
 
+=item * B<END_ITERATOR>:
+
+The iterator has returned all that it's going to. Further calls to the
+iterator will just produce more of these. This is a "false" value, and
+is the only false value the iterator which will be returned, so it can
+be used as a loop sentinel.
+
 =item * B<BEGIN_MAP>:
 
 A new map is being recursed into. This is returned I<after> the map
@@ -2315,12 +2278,33 @@
 ending resource, will cause a lot of BRANCH_STARTs and BRANCH_ENDs,
 but only one resource will be returned.
 
+=head2 Normal Usage
+
+Normal usage of the iterator object is to do the following:
+
+ my $it = $navmap->getIterator([your params here]);
+ my $curRes;
+ while ($curRes = $it->next()) {
+   [your logic here]
+ }
+
+Note that inside of the loop, it's frequently useful to check if
+"$curRes" is a reference or not with the reference function; only
+resource objects will be references, and any non-references will 
+be the tokens described above.
+
+Also note there is some old code floating around that trys to track
+the depth of the iterator to see when it's done; do not copy that 
+code. It is difficult to get right and harder to understand then
+this. They should be migrated to this new style.
+
 =back
 
 =cut
 
 # Here are the tokens for the iterator:
 
+sub END_ITERATOR { return 0; }
 sub BEGIN_MAP { return 1; }    # begining of a new map
 sub END_MAP { return 2; }      # end of the map
 sub BEGIN_BRANCH { return 3; } # beginning of a branch
@@ -2406,13 +2390,13 @@
     
         # prime the recursion
         $self->{$firstResourceName}->{DATA}->{$valName} = 0;
-        my $depth = 0;
-        $iterator->next();
+	$iterator->next();
         my $curRes = $iterator->next();
-        while ($depth > -1) {
-            if ($curRes == $iterator->BEGIN_MAP()) { $depth++; }
-            if ($curRes == $iterator->END_MAP()) { $depth--; }
-        
+	my $depth = 1;
+        while ($depth > 0) {
+	    if ($curRes == $iterator->BEGIN_MAP()) { $depth++; }
+	    if ($curRes == $iterator->END_MAP()) { $depth--; }
+
             if (ref($curRes)) {
                 # If there's only one resource, this will save it
                 # we have to filter empty resources from consideration here,
@@ -2446,8 +2430,8 @@
                 $curRes->{DATA}->{DISPLAY_DEPTH} = $finalDepth;
                 if ($finalDepth > $maxDepth) {$maxDepth = $finalDepth;}
             }
-        } continue {
-            $curRes = $iterator->next();
+
+	    $curRes = $iterator->next();
         }
     }
 
@@ -2468,6 +2452,7 @@
     $self->{MAX_DEPTH} = $maxDepth;
     $self->{STACK} = [];
     $self->{RECURSIVE_ITERATOR_FLAG} = 0;
+    $self->{FINISHED} = 0; # When true, the iterator has finished
 
     for (my $i = 0; $i <= $self->{MAX_DEPTH}; $i++) {
         push @{$self->{STACK}}, [];
@@ -2485,6 +2470,10 @@
 sub next {
     my $self = shift;
 
+    if ($self->{FINISHED}) {
+	return END_ITERATOR();
+    }
+
     # If we want to return the top-level map object, and haven't yet,
     # do so.
     if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0}) {
@@ -2544,6 +2533,7 @@
             $self->{CURRENT_DEPTH}--;
             return END_BRANCH();
         } else {
+	    $self->{FINISHED} = 1;
             return END_MAP();
         }
     }
@@ -3881,6 +3871,7 @@
     # dimension and 5 entries on the other, which we want to colorize,
     # plus network failure and "no date data at all".
 
+    #if ($self->{RESOURCE_ERROR}) { return NETWORK_FAILURE; }
     if ($completionStatus == NETWORK_FAILURE) { return NETWORK_FAILURE; }
 
     my $suppressFeedback = lc($self->parmval("problemstatus", $part)) eq 'no';
@@ -3927,7 +3918,7 @@
     if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) {
         # and there are TRIES LEFT:
         if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) {
-            return TRIES_LEFT;
+            return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT;
         }
         return $suppressFeedback ? ANSWER_SUBMITTED : INCORRECT; # otherwise, return orange; student can't fix this
     }

--bowersj21061306973--