Two more files documented.
authorSteve Bennett <stevagewp@gmail.com>
Sun, 12 Dec 2010 03:47:59 +0000 (03:47 +0000)
committerSteve Bennett <stevagewp@gmail.com>
Sun, 12 Dec 2010 03:47:59 +0000 (03:47 +0000)
net/systemeD/halcyon/connection/Entity.as
net/systemeD/halcyon/connection/actions/SetTagAction.as

index 58d6639..6e4ce8d 100644 (file)
@@ -2,9 +2,10 @@ package net.systemeD.halcyon.connection {
 
     import flash.events.EventDispatcher;
     import flash.utils.Dictionary;
-    
+
     import net.systemeD.halcyon.connection.actions.*;
 
+    /** An Entity is an object stored in the map database, and therefore uploaded and downloaded. This includes Nodes, Ways, Relations but also Changesets etc. */
     public class Entity extends EventDispatcher {
         private var _id:Number;
         private var _version:uint;
@@ -12,11 +13,13 @@ package net.systemeD.halcyon.connection {
         private var _timestamp:String;
         private var tags:Object = {};
         private var modified:Boolean = false;
-               private var _loaded:Boolean = true;
-               private var parents:Dictionary = new Dictionary();
-               public var locked:Boolean = false;                                              // lock against purging when off-screen
-               public var deleted:Boolean = false;
-               public var parentsLoaded:Boolean = true;                                // are all its parents in memory?
+        private var _loaded:Boolean = true;
+        private var parents:Dictionary = new Dictionary();
+        /** Lock against purging when off-screen */
+        public var locked:Boolean = false;
+        public var deleted:Boolean = false;
+        /** Have all its parents (ie, relations that contain this object as a member, ways that contain this node) been loaded into memory */
+        public var parentsLoaded:Boolean = true;
 
         public function Entity(id:Number, version:uint, tags:Object, loaded:Boolean, uid:Number, timestamp:String) {
             this._id = id;
@@ -28,14 +31,17 @@ package net.systemeD.halcyon.connection {
             modified = id < 0;
         }
 
+        /** ID for the entity. */
         public function get id():Number {
             return _id;
         }
 
+        /** Current version number. */
         public function get version():uint {
             return _version;
         }
 
+        /** User identifier associated with the entity. (?) */
         public function get uid():Number {
             return _uid;
         }
@@ -44,28 +50,33 @@ package net.systemeD.halcyon.connection {
             return _loaded;
         }
 
-               public function get timestamp():String {
-                       return _timestamp;
-               }
+        /** Most recent modification of the entity. */
+        public function get timestamp():String {
+            return _timestamp;
+        }
 
-               public function updateEntityProperties(version:uint, tags:Object, loaded:Boolean, parentsLoaded:Boolean, uid:Number, timestamp:String):void {
-                       _version=version; this.tags=tags; _loaded=loaded; this.parentsLoaded=parentsLoaded; _uid = uid; _timestamp = timestamp;
-                       deleted=false;
-               }
+        /** Set a bunch of properties in one hit. Implicitly makes entity not deleted. */
+        public function updateEntityProperties(version:uint, tags:Object, loaded:Boolean, parentsLoaded:Boolean, uid:Number, timestamp:String):void {
+            _version=version; this.tags=tags; _loaded=loaded; this.parentsLoaded=parentsLoaded; _uid = uid; _timestamp = timestamp;
+            deleted=false;
+        }
 
-               public function renumber(newID:Number, newVersion:uint):void {
-                       this._id = newID;
-                       this._version = newVersion;
-               }
+        /** Assign a new ID and version. */
+        public function renumber(newID:Number, newVersion:uint):void {
+            this._id = newID;
+            this._version = newVersion;
+        }
 
                // Tag-handling methods
 
+        /** Whether the entity has > 0 tags. */
         public function hasTags():Boolean {
             for (var key:String in tags)
                 return true;
             return false;
         }
 
+        /** Whether the entity has any tags other than meta-tags (attribution, created_by, source, tiger:...) */
         public function hasInterestingTags():Boolean {
             for (var key:String in tags) {
               if (key != "attribution" && key != "created_by" && key != "source" && key.indexOf('tiger:') != 0) {
@@ -76,6 +87,7 @@ package net.systemeD.halcyon.connection {
             return false;
         }
 
+        /** Rough function to detect entities untouched since TIGER import. */
         public function isUneditedTiger():Boolean {
             // todo: make this match the rules from the tiger edited map
             // http://github.com/MapQuest/TIGER-Edited-map/blob/master/inc/layer-tiger.xml.inc
@@ -85,19 +97,33 @@ package net.systemeD.halcyon.connection {
             return false;
         }
 
+        /** Retrieve a tag by key. */
         public function getTag(key:String):String {
             return tags[key];
         }
 
-               public function tagIs(key:String,value:String):Boolean {
-                       if (!tags[key]) { return false; }
-                       return tags[key]==value;
-               }
-        
+        /** @return true iff there exists key=value */
+        public function tagIs(key:String,value:String):Boolean {
+            if (!tags[key]) { return false; }
+            return tags[key]==value;
+        }
+
+        /** Set key=value, with optional undoability.
+         * @param key Name of key to set
+         * @parame value Value to set tag to
+         * @param performAction Single-argument function to pass a SetTagAction to.
+         * @example setTag("highway", "residential", MainUndoStack.getGlobalStack().addAction);
+         */
         public function setTag(key:String, value:String, performAction:Function):void {
             performAction(new SetTagAction(this, key, value));
         }
 
+        /** Change oldKey=[value] to newKey=[value], with optional undoability.
+         * @param oldKey Name of key to rename
+         * @parame newKey New name of key
+         * @param performAction Single-argument function to pass a SetTagKeyAction to.
+         * @example renameTag("building", "amenity", MainUndoStack.getGlobalStack().addAction);
+         */
         public function renameTag(oldKey:String, newKey:String, performAction:Function):void {
             performAction(new SetTagKeyAction(this, oldKey, newKey));
         }
@@ -106,6 +132,7 @@ package net.systemeD.halcyon.connection {
             return new TagList(tags);
         }
 
+        /** Returns an object that duplicates the tags on this entity. */
         public function getTagsCopy():Object {
             var copy:Object = {};
             for (var key:String in tags )
@@ -113,12 +140,13 @@ package net.systemeD.halcyon.connection {
             return copy;
         }
 
-               public function getTagsHash():Object {
-                       // hm, not sure we should be doing this, but for read-only purposes
-                       // it's faster than using getTagsCopy
-                       return tags;
-               }
+        public function getTagsHash():Object {
+            // hm, not sure we should be doing this, but for read-only purposes
+            // it's faster than using getTagsCopy
+            return tags;
+        }
 
+        /** Returns an array that duplicates the tags on this entity. */
         public function getTagArray():Array {
             var copy:Array = [];
             for (var key:String in tags )
@@ -128,155 +156,177 @@ package net.systemeD.halcyon.connection {
 
                // Clean/dirty methods
 
+        /** Check if entity is modified since last markClean(). */
         public function get isDirty():Boolean {
             return modified;
         }
 
+        /** Reset modified flag. */
         public function markClean():void {
             modified = false;
         }
 
+        /** Set entity as modified. */
         internal function markDirty():void {
             modified = true;
         }
 
-               // Delete entity
-               
-               public function remove(performAction:Function):void {
-                       // to be overridden
-               }
-               
-               public function isDeleted():Boolean {
-                   return deleted;
-               }
-               
-               public function setDeletedState(isDeleted:Boolean):void {
-                   deleted = isDeleted;
+
+        /** Delete entity - must be overridden. */
+        public function remove(performAction:Function):void {
+            // to be overridden
+        }
+
+        /** Whether entity is marked deleted. */
+        public function isDeleted():Boolean {
+            return deleted;
+        }
+
+        /** Mark entity as deleted. */
+        public function setDeletedState(isDeleted:Boolean):void {
+            deleted = isDeleted;
             if (this is Node) {
-              var n:Node = Node(this);
-              if (isDeleted) {
-                Connection.getConnection().removeDupe(n);
-              } else {
-                Connection.getConnection().addDupe(n);
-              }
+                var n:Node = Node(this);
+                if (isDeleted) {
+                    Connection.getConnection().removeDupe(n);
+                } else {
+                    Connection.getConnection().addDupe(n);
+                }
             }
-               }
-               
-               internal function isEmpty():Boolean {
-                       return false;   // to be overridden
-               }
+        }
 
-               public function nullify():void {
-                       // this retains a dummy entity in memory, for entities that we no longer need
-                       // but which are part of a still-in-memory relation
-                       nullifyEntity();
-               }
-               
-               protected function nullifyEntity():void {
-                       // this is the common nullify behaviour for all entity types (we'd call this by super() if ActionScript let us)
-                       _version=0;
-                       _loaded=false;
-                       tags={};
-               }
-               
-               
-               public function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
-                       return true;    // to be overridden
-               }
+       /** Whether entity is "empty" - to be overridden by subclass. */
+        internal function isEmpty():Boolean {
+            return false;
+        }
 
-               public function removeFromParents(performAction:Function):void {
-                       for (var o:Object in parents) {
-                               if (o is Relation) { Relation(o).removeMember(this, performAction); }
-                               else if (o is Way) { Way(o).removeNode(Node(this), performAction); }
-                               if (o.isEmpty()) { o.remove(performAction); }
-                       }
-               }
+        /** Free up memory by converting entity to a dummy entity, for entities that we no longer need
+        *  but which are part of a still-in-memory relation */
+        public function nullify():void {
+            nullifyEntity();
+        }
 
-               // Parent handling
-               
-               public function addParent(parent:Entity):void {
-                       parents[parent]=true;
-                       
-                       if ( parent is Relation )
-                           dispatchEvent(new RelationMemberEvent(Connection.ADDED_TO_RELATION, this, parent as Relation, -1));
-               }
+        /** Implement nullifybehaviour: delete tags, etc. */
+        protected function nullifyEntity():void {
+            // this is the common nullify behaviour for all entity types (we'd call this by super() if ActionScript let us)
+            _version=0;
+            _loaded=false;
+            tags={};
+        }
 
-               public function removeParent(parent:Entity):void {
-                       delete parents[parent];
 
-                       if ( parent is Relation )
-                           dispatchEvent(new RelationMemberEvent(Connection.REMOVED_FROM_RELATION, this, parent as Relation, -1));
-               }
-               
-               public function get parentWays():Array {
-                       var a:Array=[];
-                       for (var o:Object in parents) {
-                               if (o is Way) { a.push(o); }
-                       }
-                       return a;
-               }
+        public function within(left:Number,right:Number,top:Number,bottom:Number):Boolean {
+            return true;       // to be overridden
+        }
 
-               public function get hasParents():Boolean {
-                       for (var o:Object in parents) { return true; }
-                       return false;
-               }
-               
-               public function get hasParentWays():Boolean {
-                       for (var o:Object in parents) {
-                               if (o is Way) { return true; }
-                       }
-                       return false;
-               }
-               
-               public function get numParentWays():uint {
-                       var i:uint=0;
-                       for (var o:Object in parents) {
-                               if (o is Way) { i++; }
-                       }
-                       return i;
-               }
-               
-               public function get parentRelations():Array {
-                       var a:Array=[];
-                       for (var o:Object in parents) {
-                               if (o is Relation) { a.push(o); }
-                       }
-                       return a;
-               }
-               
-               public function findParentRelationsOfType(type:String, role:String=null):Array {
-                       var a:Array=[];
-                       for (var o:Object in parents) {
-                               if (o is Relation && Relation(o).tagIs('type',type) && (role==null || Relation(o).hasMemberInRole(this,role))) { 
-                                       a.push(o);
-                               }
-                       }
-                       return a;
-               }
-               
-               public function countParentObjects(within:Object):uint {
-                       var count:uint=0;
-                       for (var o:Object in parents) {
-                               if (o.getType()==within.entity && o.getTag(within.k)) {
-                                       if (within.v && within.v!=o.getTag(within.k)) { break; }
-                                       if (within.role && !Relation(o).hasMemberInRole(this,within.role)) { break; }
-                                       count++;
-                               }
-                       }
-                       return count;
-               }
-               
-               public function get parentObjects():Array {
-                       var a:Array=[];
-                       for (var o:Object in parents) { a.push(o); }
-                       return a;
-               }
-               
-               public function hasParent(entity:Entity):Boolean {
+        public function removeFromParents(performAction:Function):void {
+            for (var o:Object in parents) {
+                if (o is Relation) { Relation(o).removeMember(this, performAction); }
+                else if (o is Way) { Way(o).removeNode(Node(this), performAction); }
+                if (o.isEmpty()) { o.remove(performAction); }
+            }
+        }
+
+        // Parent handling
+
+        /** Create parent link from this entity to another. */
+        public function addParent(parent:Entity):void {
+            parents[parent]=true;
+
+            if ( parent is Relation )
+                dispatchEvent(new RelationMemberEvent(Connection.ADDED_TO_RELATION, this, parent as Relation, -1));
+        }
+
+        /** Remove parent link. */
+        public function removeParent(parent:Entity):void {
+            delete parents[parent];
+
+            if ( parent is Relation )
+                dispatchEvent(new RelationMemberEvent(Connection.REMOVED_FROM_RELATION, this, parent as Relation, -1));
+        }
+
+        /** Get array of all Ways of which this object (presumably a node) is a child. */
+        public function get parentWays():Array {
+            var a:Array=[];
+            for (var o:Object in parents) {
+                if (o is Way) { a.push(o); }
+            }
+            return a;
+        }
+
+        /** Whether this entity has any parents. */
+        public function get hasParents():Boolean {
+            for (var o:Object in parents) { return true; }
+            return false;
+        }
+
+        /** Whether this entity has any parents that are Ways. */
+        public function get hasParentWays():Boolean {
+            for (var o:Object in parents) {
+                if (o is Way) { return true; }
+            }
+            return false;
+        }
+
+        /** How many parents are Ways? */
+        public function get numParentWays():uint {
+            var i:uint=0;
+            for (var o:Object in parents) {
+                if (o is Way) { i++; }
+            }
+            return i;
+        }
+
+        /** All parents that are Relations */
+        public function get parentRelations():Array {
+            var a:Array=[];
+            for (var o:Object in parents) {
+                if (o is Relation) { a.push(o); }
+            }
+            return a;
+        }
+
+        /** Returns parents that are relations, and of the specified type, and of which this entity is the correct role (if provided).
+        *
+        * @example entity.findParentRelationsOfType('multipolygon','inner');
+        */
+        public function findParentRelationsOfType(type:String, role:String=null):Array {
+            var a:Array=[];
+            for (var o:Object in parents) {
+                if (o is Relation && Relation(o).tagIs('type',type) && (role==null || Relation(o).hasMemberInRole(this,role))) {
+                    a.push(o);
+                }
+            }
+            return a;
+        }
+
+        /** How many parents does this entity have that satisfy the "within" constraint? */
+        public function countParentObjects(within:Object):uint {
+            var count:uint=0;
+            for (var o:Object in parents) {
+                if (o.getType()==within.entity && o.getTag(within.k)) {
+                    if (within.v && within.v!=o.getTag(within.k)) { break; }
+                    if (within.role && !Relation(o).hasMemberInRole(this,within.role)) { break; }
+                    count++;
+                }
+            }
+            return count;
+        }
+
+        /** All parents of this entity. */
+        public function get parentObjects():Array {
+            var a:Array=[];
+            for (var o:Object in parents) { a.push(o); }
+                return a;
+            }
+
+        /** Whether 'entity' is a parent of this Entity. */
+        public function hasParent(entity:Entity):Boolean {
             return parents[entity] == true;
         }
 
-               public function get memberships():Array {
+            /** Returns all relations that this Entity is part of, as array of {relation, position, role}, sorted by position. */
+            public function get memberships():Array {
                        var list:Array=[];
                        for (var o:Object in parents) {
                                if (o is Relation) {
@@ -289,21 +339,22 @@ package net.systemeD.halcyon.connection {
                        }
             // it's useful to return in a sorted order, even if the relations are interleaved
             // e.g. [{r0 p1},{r1 p1},{r0 p4}]
-                       return list.sortOn("position"); 
+                       return list.sortOn("position");
                }
 
-               // Resume/suspend redraw
-               
+
+
+               /** Temporarily prevent redrawing of the object. */
                public function suspend():void {
                        dispatchEvent(new EntityEvent(Connection.SUSPEND_REDRAW, this));
                }
-               
+               /** Resume redrawing of the object */
                public function resume():void {
                        dispatchEvent(new EntityEvent(Connection.RESUME_REDRAW, this));
                }
 
-               // To be overridden
 
+                /** Basic description of Entity - should be overriden by subclass. */
                public function getDescription():String {
                        var basic:String=this.getType()+" "+_id;
                        if (tags['ref'] && tags['name']) { return tags['ref']+' '+tags['name']+' ('+basic+')'; }
@@ -312,6 +363,7 @@ package net.systemeD.halcyon.connection {
                        return basic;
                }
 
+        /** The type of Entity (node, way etc). By default, returns ''. */
         public function getType():String {
             return '';
         }
index 5f5a445..991ef5b 100644 (file)
@@ -1,18 +1,19 @@
 package net.systemeD.halcyon.connection.actions {
 
     import net.systemeD.halcyon.connection.*;
-    
+
+    /** An UndoableEntityAction corresponding to the setting of a single tag and value. */
     public class SetTagAction extends UndoableEntityAction {
         private var oldValue:String;
         private var key:String;
         private var value:String;
-        
+
         public function SetTagAction(entity:Entity, key:String, value:String) {
             super(entity, "Set "+key+"="+value);
             this.key = key;
             this.value = value;
         }
-            
+
         public override function doAction():uint {
             var tags:Object = entity.getTagsHash();
             oldValue = tags[key];
@@ -28,7 +29,7 @@ package net.systemeD.halcyon.connection.actions {
                 return NO_CHANGE;
             }
         }
-            
+
         public override function undoAction():uint {
             var tags:Object = entity.getTagsHash();
             if ( oldValue == null || oldValue == "" )
@@ -37,14 +38,14 @@ package net.systemeD.halcyon.connection.actions {
                 tags[key] = oldValue;
             markClean();
             entity.dispatchEvent(new TagEvent(Connection.TAG_CHANGED, entity, key, key, value, oldValue));
-            
+
             return SUCCESS;
         }
-        
+
         public override function mergePrevious(prev:UndoableAction):Boolean {
             if ( !(prev is SetTagAction) )
                 return false;
-                
+
             var prevSet:SetTagAction = prev as SetTagAction;
             if ( prevSet.entity == entity && prevSet.key == key ) {
                 oldValue = prevSet.oldValue;