You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2013/10/31 18:43:51 UTC

git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Updated Branches:
  refs/heads/develop 246600d16 -> 3c3d2c01f


fix up new MXML codegen and Databinding codegen handling


Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/3c3d2c01
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/3c3d2c01
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/3c3d2c01

Branch: refs/heads/develop
Commit: 3c3d2c01f26dbb15d6d15d83f295490bfa3c9a05
Parents: 246600d
Author: Alex Harui <ah...@apache.org>
Authored: Wed Oct 30 23:52:34 2013 -0700
Committer: Alex Harui <ah...@apache.org>
Committed: Thu Oct 31 10:30:00 2013 -0700

----------------------------------------------------------------------
 .../framework/src/mx/core/UIComponent.as        | 457 +++++++++++++++----
 .../src/spark/components/SkinnableContainer.as  |  11 +-
 mustella/as3/src/mustella/UnitTester.as         | 427 ++++++++++++++++-
 3 files changed, 782 insertions(+), 113 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/frameworks/projects/framework/src/mx/core/UIComponent.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/framework/src/mx/core/UIComponent.as b/frameworks/projects/framework/src/mx/core/UIComponent.as
index 822b49c..d181000 100644
--- a/frameworks/projects/framework/src/mx/core/UIComponent.as
+++ b/frameworks/projects/framework/src/mx/core/UIComponent.as
@@ -53,7 +53,13 @@ import flash.utils.Dictionary;
 import flash.utils.getQualifiedClassName;
 
 import mx.automation.IAutomationObject;
+import mx.binding.Binding;
 import mx.binding.BindingManager;
+import mx.binding.FunctionReturnWatcher;
+import mx.binding.PropertyWatcher;
+import mx.binding.StaticPropertyWatcher;
+import mx.binding.Watcher;
+import mx.binding.XMLWatcher;
 import mx.controls.IFlexContextMenu;
 import mx.core.LayoutDirection;
 import mx.effects.EffectManager;
@@ -1724,10 +1730,6 @@ public class UIComponent extends FlexSprite
         _width = super.width;
         _height = super.height;
         
-        var attributes:Array =  this.MXMLProperties;
-        if (attributes)
-            generateMXMLAttributes(attributes);
-
     }
 
     //--------------------------------------------------------------------------
@@ -7814,9 +7816,9 @@ public class UIComponent extends FlexSprite
     
     protected function addMXMLChildren(comps:Array):void
     {
-        for each (var i:DisplayObject in comps)
+        for each (var i:Object in comps)
         {
-            addChild(i);
+		    addChild(i as DisplayObject);
         }
     }
     
@@ -7839,14 +7841,20 @@ public class UIComponent extends FlexSprite
             name = data[i++];
             simple = data[i++];
             value = data[i++];
-            if (simple == null)
-                value = generateMXMLArray(document, value as Array);
+			if (simple === null)
+				value = generateMXMLArray(document, value as Array);
+			else if (simple === undefined)
+				value = generateMXMLVector(document, value as Array);
             else if (simple == false)
                 value = generateMXMLObject(document, value as Array);
             if (name == "id")
             {
                 document[value] = comp;
                 id = value as String;
+				if (comp is IMXMLObject)
+					continue;  // skip assigment to comp
+				if (!("id" in comp))
+					continue;
             }
             else if (name == "_id")
             {
@@ -7856,107 +7864,194 @@ public class UIComponent extends FlexSprite
             }
             comp[name] = value;
         }
-        if (comp is IMXMLObject)
-            comp.initialized(document, id);
-        return comp;
+		m = data[i++]; // num styles
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(document, value as Array);
+			else if (simple == false)
+				value = generateMXMLObject(document, value as Array);
+			comp.setStyle(name, value);
+		}
+		
+		m = data[i++]; // num effects
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(document, value as Array);
+			else if (simple == false)
+				value = generateMXMLObject(document, value as Array);
+			comp.setStyle(name, value);
+		}
+		
+		m = data[i++]; // num events
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			value = data[i++];
+			comp.addEventListener(name, value);
+		}
+		
+		if (comp is IUIComponent)
+		{
+			if (comp.document == null)
+				comp.document = document;
+		}
+		var children:Array = data[i++];
+		if (children)
+		{
+			comp.generateMXMLInstances(document, children);
+		}
+		
+		if (id)
+		{
+			document[id] = comp;
+			mx.binding.BindingManager.executeBindings(document, id, comp); 
+		}
+		if (comp is IMXMLObject)
+			comp.initialized(document, id);
+		return comp;
     }
     
-    public function generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array
+    public function generateMXMLVector(document:Object, data:Array, recursive:Boolean = true):*
     {
-        var comps:Array = [];
+        var comps:Array;
         
         var n:int = data.length;
-        var i:int = 0;
-        while (i < n)
-        {
-            var cls:Class = data[i++];
-            var comp:Object = new cls();
-            
-            var m:int;
-            var j:int;
-            var name:String;
-            var simple:*;
-            var value:Object;
-            var id:String = null;
-            
-            m = data[i++]; // num props
-            for (j = 0; j < m; j++)
-            {
-                name = data[i++];
-                simple = data[i++];
-                value = data[i++];
-                if (simple == null)
-                    value = generateMXMLArray(document, value as Array, recursive);
-                else if (simple == false)
-                    value = generateMXMLObject(document, value as Array);
-                if (name == "id")
-                    id = value as String;
-                if (name == "document" && !comp.document)
-                    comp.document = document;
-                else if (name == "_id")
-                    id = value as String; // and don't assign to comp
-                else
-                    comp[name] = value;
-            }
-            m = data[i++]; // num styles
-            for (j = 0; j < m; j++)
-            {
-                name = data[i++];
-                simple = data[i++];
-                value = data[i++];
-                if (simple == null)
-                    value = generateMXMLArray(document, value as Array, recursive);
-                else if (simple == false)
-                    value = generateMXMLObject(document, value as Array);
-                comp.setStyle(name, value);
-            }
-            
-            m = data[i++]; // num effects
-            for (j = 0; j < m; j++)
-            {
-                name = data[i++];
-                simple = data[i++];
-                value = data[i++];
-                if (simple == null)
-                    value = generateMXMLArray(document, value as Array, recursive);
-                else if (simple == false)
-                    value = generateMXMLObject(document, value as Array);
-                comp.setStyle(name, value);
-            }
-            
-            m = data[i++]; // num events
-            for (j = 0; j < m; j++)
-            {
-                name = data[i++];
-                value = data[i++];
-                comp.addEventListener(name, value);
-            }
-            
-            var children:Array = data[i++];
-            if (children)
-            {
-                if (recursive)
-                    comp.generateMXMLInstances(document, children, recursive);
-                else
-                    comp.setMXMLDescriptor(children);
-            }
-            
-            if (id)
-            {
-                document[id] = comp;
-                mx.binding.BindingManager.executeBindings(document, id, comp); 
-            }
-            if (comp is IMXMLObject)
-                comp.initialized(document, id);
-            comps.push(comp);
-        }
-        return comps;
+		var hint:* = data.shift();
+		var generatorFunction:Function = data.shift();
+		comps = generateMXMLArray(document, data, recursive);
+		return generatorFunction(comps);
     }
     
+	public function generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array
+	{
+		var comps:Array = [];
+		
+		var n:int = data.length;
+		var i:int = 0;
+		while (i < n)
+		{
+			var cls:Class = data[i++];
+			var comp:Object = new cls();
+			
+			var m:int;
+			var j:int;
+			var name:String;
+			var simple:*;
+			var value:Object;
+			var id:String = null;
+			
+			m = data[i++]; // num props
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple === null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple === undefined)
+					value = generateMXMLVector(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				if (name == "id")
+				{
+					document[value] = comp;
+					id = value as String;
+					if (comp is IMXMLObject)
+						continue;  // skip assigment to comp
+					try {
+						if (!("id" in comp))
+							continue;
+					}
+					catch (e:Error)
+					{
+						continue; // proxy subclasses might throw here
+					}
+				}
+				if (name == "document" && !comp.document)
+					comp.document = document;
+				else if (name == "_id")
+					id = value as String; // and don't assign to comp
+				else
+					comp[name] = value;
+			}
+			m = data[i++]; // num styles
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple == null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				comp.setStyle(name, value);
+			}
+			
+			m = data[i++]; // num effects
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple == null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				comp.setStyle(name, value);
+			}
+			
+			m = data[i++]; // num events
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				value = data[i++];
+				comp.addEventListener(name, value);
+			}
+			
+			if (comp is IUIComponent)
+			{
+				if (comp.document == null)
+					comp.document = document;
+			}
+			var children:Array = data[i++];
+			if (children)
+			{
+				if (recursive)
+					comp.generateMXMLInstances(document, children, recursive);
+				else
+					comp.setMXMLDescriptor(children);
+			}
+			
+			if (id)
+			{
+				document[id] = comp;
+				mx.binding.BindingManager.executeBindings(document, id, comp); 
+			}
+			if (comp is IMXMLObject)
+				comp.initialized(document, id);
+			comps.push(comp);
+		}
+		return comps;
+	}
+	
     protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void
     {
         var comps:Array = generateMXMLArray(document, data, recursive);
-        addMXMLChildren(comps);
+		var children:Array = [];
+		for each (var comp:Object in comps)
+		{
+			if (comp is DisplayObject || comp is IVisualElement)
+				children.push(comp);
+		}
+        addMXMLChildren(children);
     }
     
     protected function generateMXMLAttributes(data:Array):void
@@ -7975,8 +8070,10 @@ public class UIComponent extends FlexSprite
             name = data[i++];
             simple = data[i++];
             value = data[i++];
-            if (simple == null)
-                value = generateMXMLArray(this, value as Array, false);
+			if (simple === null)
+				value = generateMXMLArray(this, value as Array);
+			else if (simple === undefined)
+				value = generateMXMLVector(this, value as Array);
             else if (simple == false)
                 value = generateMXMLObject(this, value as Array);
             if (name == "id")
@@ -8020,6 +8117,164 @@ public class UIComponent extends FlexSprite
             this.addEventListener(name, value as Function);
         }
     }
+	
+	mx_internal function setupBindings():void
+	{
+		var fieldWatcher:Object;
+		var bindingData:Array = this["_bindings"];
+		var n:int = bindingData[0];
+		var bindings:Array = [];
+		var i:int;
+		var index:int = 1;
+		for (i = 0; i < n; i++)
+		{
+			var source:Object = bindingData[index++];
+			var destination:Object = bindingData[index++];
+			var binding:Binding = new Binding(this,
+				(source is Function) ? source as Function : null,
+				(destination is Function) ? destination as Function : null,
+				(destination is Function) ? null : (destination is String) ? destination as String : destination.join("."),
+				(source is Function) ? null : (source is String) ? source as String : source.join("."));
+			bindings.push(binding);
+		}
+		var watchers:Object = decodeWatcher(this, bindingData.slice(index), bindings);
+		this["_bindings"] = bindings;
+		this["_watchers"] = watchers;
+
+	}
+	
+	private function decodeWatcher(target:Object, bindingData:Array, bindings:Array):Array
+	{
+		var watcherMap:Object = {};
+		var watchers:Array = [];
+		var n:int = bindingData.length;
+		var index:int = 0;
+		var watcherData:Object;
+		var theBindings:Array;
+		var bindingIndices:Array;
+		var bindingIndex:int;
+		var propertyName:String;
+		var eventNames:Array;
+		var eventName:String;
+		var eventObject:Object;
+		var getterFunction:Function;
+		var value:*;
+		var w:Watcher;
+		
+		while (index < n)
+		{
+			var watcherIndex:int = bindingData[index++];
+			var type:int = bindingData[index++];
+			switch (type)
+			{
+				case 0:
+				{
+					var functionName:String = bindingData[index++];
+					var paramFunction:Function = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					w = new FunctionReturnWatcher(functionName,
+						this,
+						paramFunction,
+						eventObject,
+						theBindings);
+					break;
+				}
+				case 1:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					getterFunction = bindingData[index++];
+					w = new StaticPropertyWatcher(propertyName, 
+						eventObject, theBindings, getterFunction);
+					break;
+				}
+				case 2:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					getterFunction = bindingData[index++];
+					w = new PropertyWatcher(propertyName, 
+						eventObject, theBindings, getterFunction);
+					break;
+				}
+				case 3:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					w = new XMLWatcher(propertyName, theBindings);
+					break;
+				}
+			}
+			watchers.push(w);
+			w.updateParent(target);
+			if (target is Watcher)
+			{
+				if (w is FunctionReturnWatcher)
+					FunctionReturnWatcher(w).parentWatcher = Watcher(target);
+				Watcher(target).addChild(w);
+			}
+
+			var children:Array = bindingData[index++];
+			if (children != null)
+			{
+				children = decodeWatcher(w, children, bindings);
+			}
+		}            
+		return watchers;
+	}
+	
     /**
      *  Performs any final processing after child objects are created.
      *  This is an advanced method that you might override

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/frameworks/projects/spark/src/spark/components/SkinnableContainer.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/spark/src/spark/components/SkinnableContainer.as b/frameworks/projects/spark/src/spark/components/SkinnableContainer.as
index edff9c6..cdd6652 100644
--- a/frameworks/projects/spark/src/spark/components/SkinnableContainer.as
+++ b/frameworks/projects/spark/src/spark/components/SkinnableContainer.as
@@ -881,13 +881,16 @@ public class SkinnableContainer extends SkinnableContainerBase
     //
     //--------------------------------------------------------------------------
     
-    private var creatingChildren:Boolean;
+    private var creatingDeferredContent:Boolean;
     
     override protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void
     {
         // don't generate children during super.createChildren
-        if (creatingChildren)
+        if (!creatingDeferredContent)
+		{
+			setMXMLDescriptor(data);
             return;
+		}
         
         super.generateMXMLInstances(document, data, recursive);
     }
@@ -903,9 +906,7 @@ public class SkinnableContainer extends SkinnableContainerBase
      */
     override protected function createChildren():void
     {
-        creatingChildren = true;
         super.createChildren();
-        creatingChildren = false;
         
         // TODO (rfrishbe): When navigator support is added, this is where we would 
         // determine if content should be created now, or wait until
@@ -1072,7 +1073,9 @@ public class SkinnableContainer extends SkinnableContainerBase
         var children:Array =  this.MXMLDescriptor;
         if (children)
         {
+			creatingDeferredContent = true;
             generateMXMLInstances(document, children);
+			creatingDeferredContent = false;
             mxmlContentCreated = true; // keep the code from recursing back into here.
             _deferredContentCreated = true; 
             dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c3d2c01/mustella/as3/src/mustella/UnitTester.as
----------------------------------------------------------------------
diff --git a/mustella/as3/src/mustella/UnitTester.as b/mustella/as3/src/mustella/UnitTester.as
index fa3c774..24c3918 100644
--- a/mustella/as3/src/mustella/UnitTester.as
+++ b/mustella/as3/src/mustella/UnitTester.as
@@ -23,30 +23,39 @@ import flash.display.DisplayObject;
 import flash.display.DisplayObjectContainer;
 import flash.display.InteractiveObject;
 import flash.display.Stage;
-import flash.events.Event;
 import flash.events.ErrorEvent;
-import flash.events.FocusEvent;
+import flash.events.Event;
 import flash.events.EventDispatcher;
+import flash.events.FocusEvent;
 import flash.events.IOErrorEvent;
 import flash.events.ProgressEvent;
 import flash.events.SecurityErrorEvent;
 import flash.events.UncaughtErrorEvent;
-import flash.geom.Point;
 import flash.geom.Matrix;
+import flash.geom.Point;
 import flash.geom.Rectangle;
 import flash.net.Socket;
+import flash.net.URLLoader;
+import flash.net.URLLoaderDataFormat;
+import flash.net.URLRequest;
 import flash.system.ApplicationDomain;
 import flash.system.Security;
 import flash.system.fscommand;
 import flash.utils.Dictionary;
-import flash.utils.getQualifiedClassName;
 import flash.utils.Timer;
+import flash.utils.getQualifiedClassName;
 import flash.utils.setTimeout;
-import flash.net.URLRequest;
-import flash.net.URLLoader;
-import flash.net.URLLoaderDataFormat;
 
+import mx.binding.Binding;
+import mx.binding.BindingManager;
+import mx.binding.FunctionReturnWatcher;
+import mx.binding.PropertyWatcher;
+import mx.binding.StaticPropertyWatcher;
+import mx.binding.Watcher;
+import mx.binding.XMLWatcher;
+import mx.core.IMXMLObject;
 import mx.core.mx_internal;
+
 use namespace mx_internal;
 
 [Mixin]
@@ -1474,10 +1483,47 @@ public class UnitTester extends EventDispatcher
 		scriptName = getQualifiedClassName(this);
 		if (scriptName.indexOf("::") >= 0)
 			scriptName = scriptName.substring(scriptName.indexOf("::") + 2);
-
 			
 	}
 
+	//----------------------------------
+	//  MXML Descriptor
+	//----------------------------------
+	
+	/**
+	 *  The descriptor of MXML children.
+	 */
+	private var _MXMLDescriptor:Array;
+	
+	public function get MXMLDescriptor():Array
+	{
+		return _MXMLDescriptor;
+	}
+	
+	public function setMXMLDescriptor(value:Array):void
+	{
+		_MXMLDescriptor = value;    
+	}
+	
+	//----------------------------------
+	//  MXML Properties
+	//----------------------------------
+	
+	/**
+	 *  The attributes of MXML top tag.
+	 */
+	private var _MXMLProperties:Array;
+	
+	public function get MXMLProperties():Array
+	{
+		return _MXMLProperties;
+	}
+	
+	public function setMXMLProperties(value:Array):void
+	{
+		_MXMLProperties = value;    
+	}
+
 	/**
 	 *  The name of the script
 	 */
@@ -1794,6 +1840,10 @@ public class UnitTester extends EventDispatcher
 	 */
 	public function startTests():void
 	{
+		var children:Array =  this.MXMLDescriptor;
+		if (children)
+			generateMXMLInstances(this, children);
+
 		var r:Object = _root;
 		r = r["topLevelSystemManager"];
 		r = r.rawChildren;
@@ -2014,6 +2064,367 @@ public class UnitTester extends EventDispatcher
 
 	}
 
+	protected function addMXMLChildren(comps:Array):void
+	{
+	}
+	
+	protected function generateMXMLObject(document:Object, data:Array):Object
+	{
+		var i:int = 0;
+		var cls:Class = data[i++];
+		var comp:Object = new cls();
+		
+		var m:int;
+		var j:int;
+		var name:String;
+		var simple:*;
+		var value:Object;
+		var id:String;
+		
+		m = data[i++]; // num props
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(document, value as Array);
+			else if (simple == false)
+				value = generateMXMLObject(document, value as Array);
+			if (name == "id")
+			{
+				document[value] = comp;
+				id = value as String;
+			}
+			else if (name == "_id")
+			{
+				document[value] = comp;
+				id = value as String;
+				continue; // skip assignment to comp
+			}
+			comp[name] = value;
+		}
+		if (comp is IMXMLObject)
+			comp.initialized(document, id);
+		return comp;
+	}
+	
+	public function generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array
+	{
+		var comps:Array = [];
+		
+		var n:int = data.length;
+		var i:int = 0;
+		while (i < n)
+		{
+			var cls:Class = data[i++];
+			var comp:Object = new cls();
+			
+			var m:int;
+			var j:int;
+			var name:String;
+			var simple:*;
+			var value:Object;
+			var id:String = null;
+			
+			m = data[i++]; // num props
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple == null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				if (name == "id")
+					id = value as String;
+				if (name == "document" && !comp.document)
+					comp.document = document;
+				else if (name == "_id")
+					id = value as String; // and don't assign to comp
+				else
+					comp[name] = value;
+			}
+			m = data[i++]; // num styles
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple == null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				//comp.setStyle(name, value);
+			}
+			
+			m = data[i++]; // num effects
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				simple = data[i++];
+				value = data[i++];
+				if (simple == null)
+					value = generateMXMLArray(document, value as Array, recursive);
+				else if (simple == false)
+					value = generateMXMLObject(document, value as Array);
+				//comp.setStyle(name, value);
+			}
+			
+			m = data[i++]; // num events
+			for (j = 0; j < m; j++)
+			{
+				name = data[i++];
+				value = data[i++];
+				comp.addEventListener(name, value);
+			}
+			
+			var children:Array = data[i++];
+			if (children)
+			{
+				if (recursive)
+					comp.generateMXMLInstances(document, children, recursive);
+				else
+					comp.setMXMLDescriptor(children);
+			}
+			
+			if (id)
+			{
+				document[id] = comp;
+				mx.binding.BindingManager.executeBindings(document, id, comp); 
+			}
+			if (comp is IMXMLObject)
+				comp.initialized(document, id);
+			comps.push(comp);
+		}
+		return comps;
+	}
+	
+	protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void
+	{
+		var comps:Array = generateMXMLArray(document, data, recursive);
+		addMXMLChildren(comps);
+	}
+	
+	protected function generateMXMLAttributes(data:Array):void
+	{
+		var i:int = 0;
+		var m:int;
+		var j:int;
+		var name:String;
+		var simple:*;
+		var value:Object;
+		var id:String = null;
+		
+		m = data[i++]; // num props
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(this, value as Array, false);
+			else if (simple == false)
+				value = generateMXMLObject(this, value as Array);
+			if (name == "id")
+				id = value as String;
+			if (name == "_id")
+				id = value as String; // and don't assign
+			else
+				this[name] = value;
+		}
+		m = data[i++]; // num styles
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(this, value as Array, false);
+			else if (simple == false)
+				value = generateMXMLObject(this, value as Array);
+			// this.setStyle(name, value);
+		}
+		
+		m = data[i++]; // num effects
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			simple = data[i++];
+			value = data[i++];
+			if (simple == null)
+				value = generateMXMLArray(this, value as Array, false);
+			else if (simple == false)
+				value = generateMXMLObject(this, value as Array);
+			// this.setStyle(name, value);
+		}
+		
+		m = data[i++]; // num events
+		for (j = 0; j < m; j++)
+		{
+			name = data[i++];
+			value = data[i++];
+			this.addEventListener(name, value as Function);
+		}
+	}
+
+	mx_internal function setupBindings():void
+	{
+		var fieldWatcher:Object;
+		var bindingData:Array = this["_bindings"];
+		var n:int = bindingData[0];
+		var bindings:Array = [];
+		var i:int;
+		var index:int = 1;
+		for (i = 0; i < n; i++)
+		{
+			var source:Object = bindingData[index++];
+			var destination:Object = bindingData[index++];
+			var binding:Binding = new Binding(this,
+				(source is Function) ? source as Function : null,
+				(destination is Function) ? destination as Function : null,
+				(destination is Function) ? null : (destination is String) ? destination as String : destination.join("."),
+				(source is Function) ? null : (source is String) ? source as String : source.join("."));
+			bindings.push(binding);
+		}
+		var watchers:Object = decodeWatcher(this, bindingData.slice(index), bindings);
+		this["_bindings"] = bindings;
+		this["_watchers"] = watchers;
+	}
+	
+	private function decodeWatcher(target:Object, bindingData:Array, bindings:Array):Array
+	{
+		var watcherMap:Object = {};
+		var watchers:Array = [];
+		var n:int = bindingData.length;
+		var index:int = 0;
+		var watcherData:Object;
+		var theBindings:Array;
+		var bindingIndices:Array;
+		var bindingIndex:int;
+		var propertyName:String;
+		var eventNames:Array;
+		var eventName:String;
+		var eventObject:Object;
+		var getterFunction:Function;
+		var value:*;
+		var w:Watcher;
+		
+		while (index < n)
+		{
+			var watcherIndex:int = bindingData[index++];
+			var type:int = bindingData[index++];
+			switch (type)
+			{
+				case 0:
+				{
+					var functionName:String = bindingData[index++];
+					var paramFunction:Function = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					w = new FunctionReturnWatcher(functionName,
+						this,
+						paramFunction,
+						eventObject,
+						theBindings);
+					break;
+				}
+				case 1:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					getterFunction = bindingData[index++];
+					w = new StaticPropertyWatcher(propertyName, 
+						eventObject, theBindings, getterFunction);
+					break;
+				}
+				case 2:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is String)
+						eventNames = [ value ];
+					else
+						eventNames = value;
+					eventObject = {};
+					for each (eventName in eventNames)
+						eventObject[eventName] = true;
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					getterFunction = bindingData[index++];
+					w = new PropertyWatcher(propertyName, 
+						eventObject, theBindings, getterFunction);
+					break;
+				}
+				case 3:
+				{
+					propertyName = bindingData[index++];
+					value = bindingData[index++];
+					if (value is Array)
+						bindingIndices = value;
+					else
+						bindingIndices = [ value ];
+					theBindings = [];
+					for each (bindingIndex in bindingIndices)
+						theBindings.push(bindings[bindingIndex]);
+					w = new XMLWatcher(propertyName, theBindings);
+					break;
+				}
+			}
+			watchers.push(w);
+			w.updateParent(target);
+			if (target is Watcher)
+			{
+				if (w is FunctionReturnWatcher)
+					FunctionReturnWatcher(w).parentWatcher = Watcher(target);
+				Watcher(target).addChild(w);
+			}
+			
+			var children:Array = bindingData[index++];
+			if (children != null)
+			{
+				children = decodeWatcher(w, children, bindings);
+			}
+		}            
+		return watchers;
+	}
+
 	private static function callLaterErrorDefaultHandler(event:Event):void
 	{
 		var o:Object = event;


Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Alex Harui <ah...@adobe.com>.

On 11/2/13 4:11 PM, "Justin Mclean" <ju...@classsoftware.com> wrote:

>Hi,
>
>Also why this?
>+	protected function addMXMLChildren(comps:Array):void
>+	{
>+	}
Forgot to clean that up.  I'm going to try to re-factor this code into a
common utility class soon.  Variants are now in at least three places.

-Alex


Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

Also why this?
+	protected function addMXMLChildren(comps:Array):void
+	{
+	}

Justin

Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Alex Harui <ah...@adobe.com>.
Well, the changes you copied into this thread I think are all in Falcon
java files aren't they?  The code checked into the SDK should be gated by
that one null check and some generated code from Falcon.

And the net is that Falcon generated the new codegen and BasicTests
passed.  I'm now debugging my internal customer's huge app.  I think the
SDK changes have been in long enough for Mustella to pass as well.

I'll try doing more local commits, but sometimes with Falcon code when I
tried that I ended up reverting some commits and that also made the check
in hard to read.

-Alex

On 11/2/13 8:38 PM, "Justin Mclean" <ju...@classsoftware.com> wrote:

>Hi,
>
>> Yeah, sorry.  This is all for Falcon.  Doesn't affect MXMLC SWFs at all.
>
>Are you 100% sure? I'm not sure and not looked at the code closely but it
>looks like more than a null check to me.
>
>Looks like there quite a few changes in there and there a couple of
>things that look a little odd at first viewing. I'm not familiar with the
>code so it hard to tell what all these changes are actually for.
>
>For instance logic here you have && ! flex SDK and then else || FlexSDK
>shouldn't the second be an &&? Again I don't know and it could be fine it
>just looks odd on first viewing.
>+            if (s.contains(".") && !isFlexSDK)
>            {
>                String[] parts = s.split("\\.");
>                for (String part : parts)
>                    ret.addInstruction(OP_pushstring, part);
>                ret.addInstruction(OP_newarray, parts.length);
>            }
>-            else if (s == null || s.length() == 0)
>+            else if (s == null || s.length() == 0 || isFlexSDK
>
>And in one part this line was removed "for (int i = 0; i <
>node.getChildCount(); i++)" and replaced with something else, but a
>little further down it's left in.
>
>And changes like this just seem mysterious.
>-            propertyCount += 4;
>+            propertyCount += 5;
>
>I would of expected changes like large to be a merge of a branch with at
>least a dozen check in comments. Done like this it makes it quite hard to
>review. Might also be helpful to some discussion on the list about the
>changes and/or some comments in the code.
>
>Thanks,
>Justin


Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

> Yeah, sorry.  This is all for Falcon.  Doesn't affect MXMLC SWFs at all.

Are you 100% sure? I'm not sure and not looked at the code closely but it looks like more than a null check to me.

Looks like there quite a few changes in there and there a couple of things that look a little odd at first viewing. I'm not familiar with the code so it hard to tell what all these changes are actually for.

For instance logic here you have && ! flex SDK and then else || FlexSDK shouldn't the second be an &&? Again I don't know and it could be fine it just looks odd on first viewing.
+            if (s.contains(".") && !isFlexSDK)
            {
                String[] parts = s.split("\\.");
                for (String part : parts)
                    ret.addInstruction(OP_pushstring, part);
                ret.addInstruction(OP_newarray, parts.length);
            }
-            else if (s == null || s.length() == 0)
+            else if (s == null || s.length() == 0 || isFlexSDK

And in one part this line was removed "for (int i = 0; i < node.getChildCount(); i++)" and replaced with something else, but a little further down it's left in.

And changes like this just seem mysterious.
-            propertyCount += 4;
+            propertyCount += 5;

I would of expected changes like large to be a merge of a branch with at least a dozen check in comments. Done like this it makes it quite hard to review. Might also be helpful to some discussion on the list about the changes and/or some comments in the code.

Thanks,
Justin

Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Alex Harui <ah...@adobe.com>.
Yeah, sorry.  This is all for Falcon.  Doesn't affect MXMLC SWFs at all.
The initial code paths went in in 4.10 I think.   Unless I made a mistake
there should only be one null check per UIComponent instance that MXMLC
SWFs will see.

-Alex

On 11/2/13 4:09 PM, "Justin Mclean" <ju...@classsoftware.com> wrote:

>Hi,
>
>Can you give a little more detail about this change and why you made it?
>What exactly is the "new" MXML codegen? How does performance compare
>before and after these changes?
>
>Updating the Release notes would also be nice.
>
>Thanks,
>Justin


Re: git commit: [flex-sdk] [refs/heads/develop] - fix up new MXML codegen and Databinding codegen handling

Posted by Justin Mclean <ju...@classsoftware.com>.
Hi,

Can you give a little more detail about this change and why you made it? What exactly is the "new" MXML codegen? How does performance compare before and after these changes?

Updating the Release notes would also be nice.

Thanks,
Justin