You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by gr...@apache.org on 2020/04/24 06:55:51 UTC
[royale-asjs] 01/06: Ported support for ChangeWatcher.watch
(without weakReference)
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 <gr...@gmail.com>
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
{