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

bowersj2 lon-capa-cvs@mail.lon-capa.org
Thu, 14 Nov 2002 16:47:13 -0000


bowersj2		Thu Nov 14 11:47:13 2002 EDT

  Modified files:              
    /loncom/interface	lonnavmaps.pm 
  Log:
  Fixes two bugs:
  
  * Was getting the resources in the wrong order. If there were two equal
    depth branches AB and CD, which should be displayed as (Begin Branch)
    A B (End Branch) (Begin Branch) C D (End Branch), they were getting
    displayed as (Begin Branch) A C B D (End Branch), out of order.
  * In the same situation, it was not noticed that B or D (depending on
    which was explored first) was the end of a branch, since C or A
    was still on the stack at the same depth. Better end-of-branch detection
    code was added.
  
  
  
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.103 loncom/interface/lonnavmaps.pm:1.104
--- loncom/interface/lonnavmaps.pm:1.103	Tue Nov 12 13:25:11 2002
+++ loncom/interface/lonnavmaps.pm	Thu Nov 14 11:47:13 2002
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.103 2002/11/12 18:25:11 bowersj2 Exp $
+# $Id: lonnavmaps.pm,v 1.104 2002/11/14 16:47:13 bowersj2 Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1355,7 +1355,7 @@
                 my $resultingVal = $curRes->{DATA}->{$valName};
                 my $nextResources = $curRes->$nextResourceMethod();
                 my $resourceCount = scalar(@{$nextResources});
-            
+
                 if ($resourceCount == 1) {
                     my $current = $nextResources->[0]->{DATA}->{$valName} || 999999999;
                     $nextResources->[0]->{DATA}->{$valName} = min($resultingVal, $current);
@@ -1441,7 +1441,7 @@
     my $here;
     while ( $i >= 0 && !$found ) {
         if ( scalar(@{$self->{STACK}->[$i]}) > 0 ) {
-            $here = $self->{HERE} = shift @{$self->{STACK}->[$i]};
+            $here = pop @{$self->{STACK}->[$i]};
             $found = 1;
             $newDepth = $i;
         }
@@ -1459,6 +1459,18 @@
         }
     }
 
+    # If this is not a resource, it must be an END_BRANCH marker we want
+    # to return directly.
+    if (!ref($here)) {
+        if ($here == END_BRANCH()) { # paranoia, in case of later extension
+            $self->{CURRENT_DEPTH}--;
+            return $here;
+        }
+    }
+
+    # Otherwise, it is a resource and it's safe to store in $self->{HERE}
+    $self->{HERE} = $here;
+
     # Get to the right level
     if ( $self->{CURRENT_DEPTH} > $newDepth ) {
         push @{$self->{STACK}->[$newDepth]}, $here;
@@ -1478,14 +1490,29 @@
     # So we need to look at all the resources we can get to from here,
     # categorize them if we haven't seen them, remember if we have a new
     my $nextUnfiltered = $here->getNext();
-
+    my $maxDepthAdded = -1;
+    
     for (@$nextUnfiltered) {
         if (!defined($self->{ALREADY_SEEN}->{$_->{ID}})) {
-            push @{$self->{STACK}->[$_->{DATA}->{DISPLAY_DEPTH}]}, $_;
+            my $depth = $_->{DATA}->{DISPLAY_DEPTH};
+            push @{$self->{STACK}->[$depth]}, $_;
             $self->{ALREADY_SEEN}->{$_->{ID}} = 1;
+            if ($maxDepthAdded < $depth) { $maxDepthAdded = $depth; }
         }
     }
-    
+
+    # Is this the end of a branch? If so, all of the resources examined above
+    # led to lower levels then the one we are currently at, so we push a END_BRANCH
+    # marker onto the stack so we don't forget.
+    # Example: For the usual A(BC)(DE)F case, when the iterator goes down the
+    # BC branch and gets to C, it will see F as the only next resource, but it's
+    # one level lower. Thus, this is the end of the branch, since there are no
+    # more resources added to this level or above.
+    my $isEndOfBranch = $maxDepthAdded < $self->{CURRENT_DEPTH};
+    if ($isEndOfBranch) {
+        push @{$self->{STACK}->[$self->{CURRENT_DEPTH}]}, END_BRANCH();
+    }
+
     # That ends the main iterator logic. Now, do we want to recurse
     # down this map (if this resource is a map)?
     if ($self->{HERE}->is_map() &&