This is an automated email from the ASF dual-hosted git repository.

gregdove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit ed645b9806e82dcd43722d4640c95e41798d545f
Author: greg-dove <[email protected]>
AuthorDate: Fri Apr 24 17:47:51 2020 +1200

    Ported support for ChangeWatcher.watch (without weakReference)
---
 .../src/main/royale/mx/binding/BindabilityInfo.as  | 179 +++++++++++++++------
 .../main/royale/mx/binding/utils/ChangeWatcher.as  |  56 +++----
 2 files changed, 161 insertions(+), 74 deletions(-)

diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/binding/BindabilityInfo.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/binding/BindabilityInfo.as
index 8500fbe..ede40bf 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/binding/BindabilityInfo.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/binding/BindabilityInfo.as
@@ -20,8 +20,22 @@
 package mx.binding
 {
 
+COMPILE::SWF{
+       import flash.utils.Dictionary;
+}
+
 import mx.events.PropertyChangeEvent;
 
+
+import org.apache.royale.events.ValueChangeEvent;
+import org.apache.royale.reflection.DefinitionWithMetaData;
+import org.apache.royale.reflection.MetaDataArgDefinition;
+import org.apache.royale.reflection.MetaDataDefinition;
+import org.apache.royale.reflection.TypeDefinition;
+import org.apache.royale.reflection.describeType;
+import org.apache.royale.reflection.utils.getMembersWithNameMatch;
+import org.apache.royale.reflection.utils.filterForMetaTags;
+
 [ExcludeClass]
 
 /**
@@ -38,7 +52,7 @@ public class BindabilityInfo
        //  Class constants
        //
        
//--------------------------------------------------------------------------
-       
+
        /**
         *  Name of [Bindable] metadata.
         *  
@@ -57,7 +71,7 @@ public class BindabilityInfo
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
         */
-       public static const MANAGED:String = "Managed";
+//     public static const MANAGED:String = "Managed";
        
        /**
         *  Name of [ChangeEvent] metadata.
@@ -67,7 +81,7 @@ public class BindabilityInfo
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
         */
-       public static const CHANGE_EVENT:String = "ChangeEvent";
+//     public static const CHANGE_EVENT:String = "ChangeEvent";
        
        /**
         *  Name of [NonCommittingChangeEvent] metadata.
@@ -77,8 +91,8 @@ public class BindabilityInfo
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
         */
-       public static const NON_COMMITTING_CHANGE_EVENT:String =
-               "NonCommittingChangeEvent";
+       //public static const NON_COMMITTING_CHANGE_EVENT:String =
+       //      "NonCommittingChangeEvent";
 
        /**
         *  Name of describeType() <accessor> element.
@@ -100,6 +114,50 @@ public class BindabilityInfo
         */
        public static const METHOD:String = "method";
 
+
+       COMPILE::SWF
+       private static const cache:Dictionary = new Dictionary();
+
+       COMPILE::JS
+       private static const cache:Map = new Map()
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Static methods
+       //
+       
//--------------------------------------------------------------------------
+
+       public static function getCachedInfo(forTarget:Object):BindabilityInfo{
+               var typeDef:TypeDefinition = describeType(forTarget);
+               var info:BindabilityInfo = getFromCache(typeDef);
+               if (!info) {
+                       info = new BindabilityInfo(typeDef, true);
+               }
+               return info;
+       }
+
+       private static function 
getFromCache(typeDef:TypeDefinition):BindabilityInfo{
+               var info:BindabilityInfo;
+               COMPILE::SWF{
+                       info = cache[typeDef.getClass()]
+               }
+               COMPILE::JS{
+                       info = cache.get(typeDef.getClass())
+               }
+               return info;
+       }
+
+       private static function storeInCache(info:BindabilityInfo):void{
+               var typeDef:TypeDefinition = info.typeDefinition;
+               COMPILE::SWF{
+                       cache[typeDef.getClass()] = info;
+               }
+               COMPILE::JS{
+                       cache.set(typeDef.getClass(), info);
+               }
+       }
+
+
        
//--------------------------------------------------------------------------
        //
        //  Constructor
@@ -114,11 +172,14 @@ public class BindabilityInfo
         *  @playerversion AIR 1.1
         *  @productversion Flex 3
         */
-       public function BindabilityInfo(typeDescription:XML)
+       public function BindabilityInfo(typeDefinition:TypeDefinition, 
cache:Boolean=false)
        {
                super();
 
-               this.typeDescription = typeDescription;
+               this.typeDefinition = typeDefinition;
+               if (cache) {
+                       storeInCache(this);
+               }
        }
 
        
//--------------------------------------------------------------------------
@@ -130,7 +191,7 @@ public class BindabilityInfo
        /**
         *  @private
         */
-       private var typeDescription:XML;
+       private var typeDefinition:TypeDefinition;
        
        /**
         *  @private
@@ -168,33 +229,29 @@ public class BindabilityInfo
                        // Seed with class-level events.
                        changeEvents = copyProps(getClassChangeEvents(), {});
 
-                       // Get child-specific events.
-                       var childDesc:XMLList =
-                               typeDescription.accessor.(@name == childName) +
-                               typeDescription.method.(@name == childName);
-                       
-                       var numChildren:int = childDesc.length();
+                       var accessorsAndMethods:Array = [];
+
+                       getMembersWithNameMatch(typeDefinition.accessors, 
childName, accessorsAndMethods);
+                       getMembersWithNameMatch(typeDefinition.methods, 
childName, accessorsAndMethods);
+
+                       var numChildren:int = accessorsAndMethods.length;
 
                        if (numChildren == 0)
                        {
-                               // we've been asked for events on an unknown 
property
-                               if (!typeDescription.@dynamic)
-                               {
-                                       trace("warning: no describeType entry 
for '" +
-                                                 childName + "' on non-dynamic 
type '" +
-                                                 typeDescription.@name + "'");
-                               }
+                               trace("warning: no describeType entry for '" +
+                                               childName + "' on non-dynamic 
type '" +
+                                               typeDefinition.name + "'");
                        }
                        else
                        {
                                if (numChildren > 1)
                                {
                                        trace("warning: multiple describeType 
entries for '" +
-                                                 childName + "' on type '" + 
typeDescription.@name +
-                                                 "':\n" + childDesc);
+                                                       childName + "' on type 
'" + typeDefinition.name +
+                                                       "':\n" + 
accessorsAndMethods);
                                }
 
-                               addBindabilityEvents(childDesc.metadata, 
changeEvents);
+                               addBindabilityEvents(accessorsAndMethods, 
changeEvents);
                        }
 
                        childChangeEvents[childName] = changeEvents;
@@ -207,35 +264,45 @@ public class BindabilityInfo
         *  @private
         *  Build or return cached class change events object.
         */
+
        private function getClassChangeEvents():Object
        {
                if (!classChangeEvents)
                {
                        classChangeEvents = {};
 
-                       addBindabilityEvents(typeDescription.metadata, 
classChangeEvents);
+                       //@todo check this (currently fails in swf at runtime)
+                       //addBindabilityEvents(typeDefinition.metadata, 
classChangeEvents);
+
 
+                       //if class has Bindable metadata, assume yes ?
+                       if 
(typeDefinition.retrieveMetaDataByName('Bindable').length) {
+                               
classChangeEvents[ValueChangeEvent.VALUE_CHANGE] = true;
+                       }
+                       // tbd, do we want this?
                        // Class-level [Managed] means all properties
-                       // dispatch propertyChange.
-                       if (typeDescription.metadata.(@name == 
MANAGED).length() > 0)
-                       {
-                               
classChangeEvents[PropertyChangeEvent.PROPERTY_CHANGE] = true;
+                       // dispatch valueChange.
+                       if 
(typeDefinition.retrieveMetaDataByName('Managed').length) {
+                               
classChangeEvents[ValueChangeEvent.VALUE_CHANGE] = true;
                        }
+
                }
 
                return classChangeEvents;
        }
 
+
        /**
         *  @private
         */
-       private function addBindabilityEvents(metadata:XMLList,
+
+       private function addBindabilityEvents(members:Array,
                                                                                
  eventListObj:Object):void
        {
-               addChangeEvents(metadata.(@name == BINDABLE), eventListObj, 
true);
-               addChangeEvents(metadata.(@name == CHANGE_EVENT), eventListObj, 
true);
-               addChangeEvents(metadata.(@name == NON_COMMITTING_CHANGE_EVENT),
-                                               eventListObj, false);
+               var metaNames:Array = [BINDABLE];
+               var changeEvents:Array = filterForMetaTags(members, metaNames);
+
+               addChangeEvents(changeEvents, eventListObj );
        }
 
        /**
@@ -244,20 +311,40 @@ public class BindabilityInfo
         *  to an event list object.
         *  Note: metadata's first arg value is assumed to be change event name.
         */
-       private function addChangeEvents(metadata:XMLList, eventListObj:Object, 
isCommit:Boolean):void
+
+       private function addChangeEvents(members:Array, 
eventListObj:Object):void
        {
-               for each (var md:XML in metadata)
+               for each (var md:DefinitionWithMetaData in members)
                {
-                       var arg:XMLList = md.arg;
-                       if (arg.length() > 0)
-                       {
-                               var eventName:String = arg[0].@value;
-                               eventListObj[eventName] = isCommit;
-                       }
-                       else
-                       {
-                               trace("warning: unconverted Bindable metadata 
in class '" +
-                                         typeDescription.@name + "'");
+                       var metaNames:Array = [BINDABLE];
+
+                       for each(var meta:String in metaNames) {
+                               var metaItems:Array = 
md.retrieveMetaDataByName(meta);
+                               if (metaItems.length) {
+                                       //if there is no arg, then it is 
valueChange
+                                       for each(var 
metaItem:MetaDataDefinition in metaItems) {
+                                               if (metaItem.args.length) {
+                                                       //check for no key
+                                                       var eventTypeArgs:Array 
= metaItem.getArgsByKey('');
+                                                       if 
(!eventTypeArgs.length) {
+                                                               //check for 
'event' key
+                                                               eventTypeArgs = 
metaItem.getArgsByKey('event');
+                                                       }
+                                                       if 
(eventTypeArgs.length) {
+                                                               
eventListObj[MetaDataArgDefinition(eventTypeArgs[0]).value] = true;
+                                                       }
+                                               } else {
+                                                       if (meta == BINDABLE) {
+                                                               
eventListObj[ValueChangeEvent.VALUE_CHANGE] = true;
+                                                       }
+                                                       else {
+                                                               trace("warning: 
unconverted change events metadata in class '" +
+                                                                               
typeDefinition.name + "'", metaItem);
+                                                       }
+
+                                               }
+                                       }
+                               }
                        }
                }
        }
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/binding/utils/ChangeWatcher.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/binding/utils/ChangeWatcher.as
index addd3aa..713af62 100644
--- 
a/frameworks/projects/MXRoyale/src/main/royale/mx/binding/utils/ChangeWatcher.as
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/binding/utils/ChangeWatcher.as
@@ -26,10 +26,10 @@ package mx.binding.utils
 import org.apache.royale.events.IEventDispatcher;
 import org.apache.royale.events.Event;
 
-import mx.core.EventPriority;
+//import mx.core.EventPriority;
 import mx.binding.BindabilityInfo;
 import mx.events.PropertyChangeEvent;
-// import mx.utils.DescribeTypeCache;
+import org.apache.royale.events.ValueChangeEvent;
 
 /**
  *  The ChangeWatcher class defines utility methods
@@ -140,9 +140,7 @@ public class ChangeWatcher
      *  @productversion Flex 3
      */
     public static function watch(host:Object, chain:Object,
-                                 handler:Function,
-                                 commitOnly:Boolean = false,
-                                 useWeakReference:Boolean = 
false):ChangeWatcher
+                                 handler:Function):ChangeWatcher
     {
         if (!(chain is Array))
             chain = [ chain ];
@@ -150,9 +148,8 @@ public class ChangeWatcher
         if (chain.length > 0)
         {
             var w:ChangeWatcher =
-                new ChangeWatcher(chain[0], handler, commitOnly,
-                    watch(null, chain.slice(1), handler, commitOnly));
-            w.useWeakReference = useWeakReference;
+                new ChangeWatcher(chain[0], handler,
+                    watch(null, chain.slice(1), handler));
             w.reset(host);
             return w;
         }
@@ -187,10 +184,9 @@ public class ChangeWatcher
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
      */
-    public static function canWatch(host:Object, name:String,
-                                    commitOnly:Boolean = false):Boolean
+    public static function canWatch(host:Object, name:String):Boolean
     {
-        return !isEmpty(getEvents(host, name, commitOnly));
+        return !isEmpty(getEvents(host, name));
     }
 
     /**
@@ -213,16 +209,14 @@ public class ChangeWatcher
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
      */
-    public static function getEvents(host:Object, name:String,
-                                     commitOnly:Boolean = false):Object
+    public static function getEvents(host:Object, name:String):Object
     {
         if (host is IEventDispatcher)
         {
             // Get { eventName: isCommitting, ... } for all change events
             // defined by host's class on prop <name>
-            /*var allEvents:Object = DescribeTypeCache.describeType(host).
-                                   bindabilityInfo.getChangeEvents(name);
-            if (commitOnly)
+            var allEvents:Object = 
BindabilityInfo.getCachedInfo(host).getChangeEvents(name);
+            /*if (commitOnly)
             {
                 // Filter out non-committing events.
                 var commitOnlyEvents:Object = {};
@@ -234,7 +228,9 @@ public class ChangeWatcher
             else
             {
                 return allEvents;
-            }*/return {};
+            }return {};*/
+
+            return allEvents;
         }
         else
         {
@@ -285,7 +281,6 @@ public class ChangeWatcher
      *  @productversion Flex 3
      */
     public function ChangeWatcher(access:Object, handler:Function,
-                                  commitOnly:Boolean = false,
                                   next:ChangeWatcher = null)
     {
         super();
@@ -294,10 +289,10 @@ public class ChangeWatcher
         name = access is String ? access as String : access.name;
         getter = access is String ? null : access.getter;
         this.handler = handler;
-        this.commitOnly = commitOnly;
+   //     this.commitOnly = commitOnly;
         this.next = next;
         events = {};
-        useWeakReference = false;
+     //   useWeakReference = false;
         isExecuting = false;
     }
 
@@ -361,7 +356,7 @@ public class ChangeWatcher
      *  @playerversion AIR 1.1
      *  @productversion Flex 3
      */
-    private var commitOnly:Boolean;
+  //  private var commitOnly:Boolean;
 
     /**
      *  If watching a chain, this is a watcher on the next property
@@ -418,7 +413,7 @@ public class ChangeWatcher
      * 
      *  @royalesuppresspublicvarwarning
      */
-    public var useWeakReference:Boolean;
+   // public var useWeakReference:Boolean;
 
     
//--------------------------------------------------------------------------
     //
@@ -527,18 +522,18 @@ public class ChangeWatcher
             {
                 host.removeEventListener(p, wrapHandler);
             }
-            events = {};
+            if (newHost == null) events = {};
         }
 
         host = newHost;
 
         if (host != null)
         {
-            events = getEvents(host, name, commitOnly);
+            events = getEvents(host, name);
             for (p in events)
             {
-                host.addEventListener(p, wrapHandler, false,
-                    EventPriority.BINDING, useWeakReference);
+                host.addEventListener(p, wrapHandler, false/*,
+                    EventPriority.BINDING, useWeakReference*/);
             }
         }
 
@@ -561,6 +556,7 @@ public class ChangeWatcher
      *  @private
      *  Listener for change events.
      *  Resets chained watchers and calls user-supplied handler.
+     *
      */
     private function wrapHandler(event:Event):void
     {
@@ -573,10 +569,14 @@ public class ChangeWatcher
                 if (next)
                     next.reset(getHostPropertyValue());
 
-                if (event is PropertyChangeEvent)
+                if (event is ValueChangeEvent){
+                    if ((event as ValueChangeEvent).propertyName == name)
+                        handler(event);
+                }
+                else if (event is PropertyChangeEvent)
                 {
                     if ((event as PropertyChangeEvent).property == name)
-                        handler(event as PropertyChangeEvent);
+                        handler(event);
                 }
                 else
                 {

Reply via email to