Load map features images into cache rather than have Image components load them each...
authorDave Stubbs <osm@randomjunk.co.uk>
Sun, 28 Feb 2010 19:32:06 +0000 (19:32 +0000)
committerDave Stubbs <osm@randomjunk.co.uk>
Sun, 28 Feb 2010 19:32:06 +0000 (19:32 +0000)
TODO.txt
net/systemeD/potlatch2/TagViewer.mxml
net/systemeD/potlatch2/mapfeatures/Feature.as
net/systemeD/potlatch2/mapfeatures/editors/Choice.as
net/systemeD/potlatch2/mapfeatures/editors/ChoiceEditorFactory.as
net/systemeD/potlatch2/utils/CachedDataLoader.as [new file with mode: 0644]

index 2920d95..39d7b77 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -22,18 +22,12 @@ Potlatch 2: main outstanding issues
 * Plugin support
 
 
-== Server interaction ==
-
-* Should redraw members of a relation when the relation is loaded
-
-
 == UI ==
 
 * UI for geometry operations
 * Keyboard shortcuts
 * CSS editing
 * Direct click-to-edit of relation role should actually work
-* Relation member changes should update TagViewer automatically
 
 
 == Tagging ==
index 6074d0e..eed3af0 100644 (file)
       private function refreshFeatureIcon():void {
           var oldFeature:Feature = feature;
           feature = selectedEntity == null ? null : mapFeatures.findMatchingFeature(selectedEntity);
-          if ( feature != oldFeature )
+          if ( feature != oldFeature ) {
+              if ( oldFeature != null )
+                  oldFeature.removeEventListener("imageChanged", featureImageChanged);
+              if ( feature != null )
+                  feature.addEventListener("imageChanged", featureImageChanged);
               initialiseEditors();
+          }
 
           if ( feature != null )
               setFeatureIcon(selectedEntity, feature);
               blankFeatureIcon(selectedEntity);
       }
 
+      private function featureImageChanged(event:Event):void {
+          setFeatureIcon(selectedEntity, feature);
+      }
+      
       private function setFeatureIcon(entity:Entity, feature:Feature):void {
           //blankFeatureIcon(entity);
           
index 7036c0f..77fa3bb 100644 (file)
@@ -2,7 +2,11 @@ package net.systemeD.potlatch2.mapfeatures {
 
     import flash.events.EventDispatcher;
     import flash.events.Event;
+    import flash.net.*;
+    import flash.utils.ByteArray;
+    
     import net.systemeD.halcyon.connection.Entity;
+    import net.systemeD.potlatch2.utils.CachedDataLoader;
 
        public class Feature extends EventDispatcher {
         private var mapFeatures:MapFeatures;
@@ -78,13 +82,21 @@ package net.systemeD.potlatch2.mapfeatures {
         }
     
         [Bindable(event="imageChanged")]
-        public function get image():String {
+        public function get image():ByteArray {
             var icon:XMLList = _xml.icon;
+            var imageURL:String = null;
 
             if ( icon.length() > 0 && icon[0].hasOwnProperty("@image") )
-                return icon[0].@image;
-            else
-                return null;
+                imageURL = icon[0].@image;
+            
+            if ( imageURL != null ) {
+                return CachedDataLoader.loadData(imageURL, imageLoaded);
+            }
+            return null;
+        }
+        
+        private function imageLoaded(url:String, data:ByteArray):void {
+            dispatchEvent(new Event("imageChanged"));
         }
         
         public function htmlDetails(entity:Entity):String {
index 635c95a..93acb03 100644 (file)
@@ -1,6 +1,7 @@
 package net.systemeD.potlatch2.mapfeatures.editors {
 
     import flash.events.*;
+    import flash.utils.ByteArray;
 
        public class Choice extends EventDispatcher {
 
@@ -10,8 +11,8 @@ package net.systemeD.potlatch2.mapfeatures.editors {
         public var description:String = "";
         [Bindable]
         public var value:String = null;
-        [Bindable]
-        public var icon:String = null;
+        [Bindable("iconLoaded")]
+        public var icon:ByteArray = null;
 
         private var _match:RegExp = null;
         
@@ -26,6 +27,11 @@ package net.systemeD.potlatch2.mapfeatures.editors {
                 _match = new RegExp("^("+matchStr+")$");
             }
         }
+        
+        public function imageLoaded(url:String, data:ByteArray):void {
+            icon = data;
+            dispatchEvent(new Event("iconLoaded"));
+        }
     }
 
 }
index acef766..3b221ce 100644 (file)
@@ -2,6 +2,7 @@ package net.systemeD.potlatch2.mapfeatures.editors {
 
     import net.systemeD.halcyon.connection.*;
     import net.systemeD.potlatch2.mapfeatures.*;
+    import net.systemeD.potlatch2.utils.CachedDataLoader;
     import flash.display.*;
 
        public class ChoiceEditorFactory extends SingleTagEditorFactory {
@@ -16,7 +17,8 @@ package net.systemeD.potlatch2.mapfeatures.editors {
                 choice.value = String(choiceXML.@value);
                 choice.description = String(choiceXML.@description);
                 choice.label = String(choiceXML.@text);
-                choice.icon = choiceXML.hasOwnProperty("@icon") ? String(choiceXML.@icon) : null;
+                choice.icon = choiceXML.hasOwnProperty("@icon") ? 
+                    CachedDataLoader.loadData(String(choiceXML.@icon), choice.imageLoaded) : null;
                 choice.match = String(choiceXML.@match);
                 choices.push(choice);
             }
diff --git a/net/systemeD/potlatch2/utils/CachedDataLoader.as b/net/systemeD/potlatch2/utils/CachedDataLoader.as
new file mode 100644 (file)
index 0000000..3ed0834
--- /dev/null
@@ -0,0 +1,48 @@
+package net.systemeD.potlatch2.utils {
+
+       import flash.events.*;
+       import flash.net.*;
+       import flash.utils.ByteArray;
+
+    import net.systemeD.halcyon.ExtendedURLLoader;
+
+       public class CachedDataLoader {
+
+        private static var allData:Object = {};
+        private static var requestsMade:Object = {};
+        
+               public static function loadData(url:String, onLoadHandler:Function = null):ByteArray {
+                   var data:ByteArray = allData[url];
+                   if ( data != null )
+                       return data;
+                   
+                   var requests:Array = requestsMade[url];
+                   if ( requests == null ) {
+                       requests = [];
+                       requestsMade[url] = requests;
+
+                           var loader:ExtendedURLLoader = new ExtendedURLLoader();
+                   loader.info = url;
+                loader.addEventListener(Event.COMPLETE, imageLoaded);
+                loader.dataFormat = URLLoaderDataFormat.BINARY;
+                loader.load(new URLRequest(url));
+                   }
+                   requests.push(onLoadHandler);
+                   
+                   return allData[url];
+               }
+
+        private static function imageLoaded(event:Event):void {
+            var loader:ExtendedURLLoader = ExtendedURLLoader(event.target);
+            var url:String = loader.info as String;
+            allData[url] = loader.data;
+            
+            var requests:Array = requestsMade[url];
+            for each ( var handler:Function in requests ) {
+                handler(url, loader.data);
+            }
+            
+            delete requestsMade[url];
+        }
+       }
+}