After spending a decent amount of time searching, I was unable to find any helpful postings on this very simple Papervision task, so here is a quick workaround.
Once you’ve created a MovieAssetMaterial, the 2D MovieClip inside the material can be referenced via the movie property (i.e. MyAssetMaterial.movie). The problem is that the display list inside is not direcly accessible since the movie property is typed as “DisplayObject” rather than MovieClip or Sprite as needed. So you must type it yourself! Example:
1 2 3 4 5 | var testMaterial:MovieAssetMaterial = new MovieAssetMaterial("firstClip", true, false, false, true) var myClip = MovieClip(testMaterial.movie); var myText = myClip.getChildByName("menuLabel"); myText.text = "Updated Dynamic Text"; |
We are investing in developing an open source video player framework for Flash. The goals are to
1) Give us a standardized starting point for video player development and share that with the community
2) More importantly (for us) is to demonstrate how we build software using classic software engineering techniques including UML, but in an agile kinda way and utilizing our own special twist.
This will hopefully help aspiring flash video player developers with a reference model to compare their efforts with. Hopefully others will pitch in with their knowledge and insights and we can all help each other understand how to do this rather specialized craft better.
We started this effort just at the same time we discovered the Open Source Media Framework (OSMF) http://www.opensourcemediaframework.com/ which is a new layer on top of the existing flash api for delivering video. We will be exploring this framework further over the coming months, but after watching the videos here on the API, I can testify that interacting with the OSMF api is *much* simpler on the face of it. Whether it has the chops to support all of the functionality needed for complex development (yet!) is something we will be trying to figure out.
Will keep our discoveries posted as they happen.
Ouch! Spent good chunk of yesterday dealing with a bug introduced in Firefox 3.6 on the Mac:
http://www.soundstep.com/blog/2010/03/02/firefox-3-6-mac-bug-with-mouseevent/
Basically, if you click on a sprite (or probably any DisplayObject) you will now get a bonus MouseEvent.ROLL_OUT event. Which totally sucks when you actually use that event for its intended purpose!
Hope they get that fixed soon.
I changed to the 4.1 flex sdk recently. After a week or so, the autocomplete suddenly stopped working. I tried a few things including deleting the .metadata to no avail.
Rolling back to 4.0 seems to have worked.
There is a great tutorial on flashandmath.com that goes into depth about issues with runtime loading external swf files. However it is a little chewy so I’m going to try to boil it down a bit and go straight to the results. Please read that article for more in-depth information.
When loading a swf, you have two options for getting it onto the display list. The first is to add the loader itself to the display list:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Parent.swf _loader = new Loader(); // !!! Immediately add the loader to the display // list BEFORE calling load() addChild( _loader ); // loader is now on display list, // stage and parent are available for // Widget.swf's document class constructor _loader.load( new URLRequest( "Widget.swf" ) ); |
However, this means that the loader is on the display list as well as the child swf. So the display hierarchy would be:
Parent.swf -> loader -> Widget.swf
The code is straightforward and this approach guarantees that the DisplayObject.parent and DisplayObject.stage properties are initialized and available for use in the document class constructor. For most situations, I’m sure this is an adequate way to go to avoid the complexities I’m about to discuss. However…
I personally do not like to have to remember that the loader is the parent of the Widget and not the Parent.swf. Not that it should matter too much, but it strikes me as inelegant. Instead, what I want on the display list is the following hierarchy:
Parent.swf -> Widget.swf
So the Widget.swf is an immediate child of the Parent.swf with no intervening loader in the middle. The way to accomplish this goal is to do the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Parent.swf public function Parent() { _loader = new Loader(); _loader.contentLoaderInfo.addEventListener( Event.COMPLETE, complete ); _loader.load( new URLRequest( "Widget.swf" ) ); } ///////////////////////////////////////////// public function complete( event:Event ):void { var widget:MovieClip = MovieClip(_loader.content); addChild( widget ); } |
The rest of this article is about how to load a Widget.swf directly into a Parent.swf without having the loader in the middle.
The ideal scenario is, of course, that the loaded swf will work the same way both standalone during development as when it is loaded into the Parent.swf file. This makes debugging much easier if things are structured this way. The problem, as alluded to above, is that with this approach when we are loading the Widget.swf into Parent.swf, we will not have DocumentObject.parent or (most importantly) DocumentObject.stage available in the document class constructor because the Widget.swf will not be on the display list at that point.
So in order to be able to work in the same manner in both situations, it is necessary to know exactly when everything has been initialized properly.
The short story is: the best plan is to structure the Widget.swf code to start working in response to the Event.ADDED_TO_STAGE event.
To analyze the possibilities, I structured the Parent.swf and the Widget.swf to both receive the following events to observe how things actually played out:
- Event.INIT
- Event.COMPLETE
- Event.ADDED
- Event.ADDED_TO_STAGE
When working with Widget.swf standalone, it has the following event trace (code is at the bottom for both Parent.swf and Widget.swf):
Widget: Widget() ( parent != null, root != null, stage != null ) Widget: Event.ADDED ( parent != null, root != null, stage != null ) Widget: Event.ADDED_TO_STAGE ( parent != null, root != null, stage != null ) Widget: Event.INIT ( parent != null, root != null, stage != null ) Widget: Event.COMPLETE ( parent != null, root != null, stage != null )
So we can see here that at all times we have access to all interesting properties in the display hierarchy. Also notice the particular order that the events occurred in – this will not be the same order for other experiments.
( A comment about DocumentObject.root – it is always present under all circumstances as it refers to the document class for the current .swf. In Parent.swf it will be the Parent class. In Widget.swf, it will be the Widget class. It does not matter if it is on the display list or not.)
One thing to point out is the semantics of Event.INIT and Event.COMPLETE. Event.INIT is sent when all assets on frame 1 of the timeline for that swf have been loaded. Event.COMPLETE is sent when all data has been loaded for all frames. This sequence puzzles me a bit though. In thinking about it, I’m not sure what confidence I can have in what is available in the constructor to reference (like other classes and display elements on frame 1 at least). I haven’t found any docs stating that everything is good to go for a standalone swf file in the constructor. But so far in my development I haven’t hit any issues. If anybody has some intel, please let me know. Otherwise I would assume that you are really, really ready with a 1 frame swf after Event.INIT and after Event.COMPLETE with a multiframe swf. But so far, so good using the document class constructor in standalone.
Next I did the load test into Parent.swf. While most of this was what I expected, I am still puzzled by the first Widget: Event.ADDED event – the parent isn’t set! I also verified (not shown) that the Event.target was the Widget, so I don’t know what is up with that one.
Here’s the sequence:
Parent: Parent() Widget: Widget() ( parent == null, root != null, stage == null ) Widget: Event.ADDED ( parent == null, root != null, stage == null ) Widget: Event.ADDED ( parent != null, root != null, stage == null ) Widget: parent is Loader Parent: Event.INIT (all assets on frame 1 are loaded) Widget: Event.INIT ( parent != null, root != null, stage == null ) Parent: Event.COMPLETE (all assets on all frames are loaded) --------------------- Before Parent.addChild() Widget: Event.ADDED ( parent != null, root != null, stage != null ) Widget: Event.ADDED_TO_STAGE ( parent != null, root != null, stage != null ) After Parent.addChild() --------------------- Widget: Event.COMPLETE ( parent != null, root != null, stage != null )
The first Event that actually has all conditions met is the last Event.ADDED event. However, the Widget will receive three of them, so it is better to just wait for the Event.ADDED_TO_STAGE. In both scenarios everything is ready to roll at that point.
This approach is what we now use in order to simplify our Main.swf files by factoring out the preloader code into a separate Preloader.swf file. So our architecture is to have a Loader.swf that first loads Preloader.swf and then starts on Main.swf. We update the Preloader.swf display from progress information, and when Main.swf is ready, we unload Preloader.swf and display Main.swf.
We like this approach a lot and it enables us to remove a lot of timeline complexity from the important “controller” type swf assets and factor it into “resource” type swfs.
Here’s the code for Widget.swf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package { import flash.events.*; import flash.display.*; import flash.net.*; public class Widget extends MovieClip { /////////////////////////////////////////////////////////////////////// public function Widget() { formatTrace( "Widget: Widget()" ); this.loaderInfo.addEventListener( Event.INIT, init ); this.loaderInfo.addEventListener( Event.COMPLETE, complete ); this.addEventListener( Event.ADDED, added ); this.addEventListener( Event.ADDED_TO_STAGE, addedToStage ); // have widget show up this.opaqueBackground = 0xff0000; } /////////////////////////////////////////////////////////////////////// public function init( event:Event ):void { formatTrace( "Widget: Event.INIT" ); } /////////////////////////////////////////////////////////////////////// public function complete( event:Event ):void { formatTrace( "Widget: Event.COMPLETE" ); } /////////////////////////////////////////////////////////////////////// public function added( event:Event ):void { formatTrace( "Widget: Event.ADDED" ); if ( parent is flash.display.Stage ) trace( "Widget: parent is Stage" ); if ( parent is Loader ) trace( "Widget: parent is Loader" ); } /////////////////////////////////////////////////////////////////////// public function addedToStage( event:Event ):void { formatTrace( "Widget: Event.ADDED_TO_STAGE" ); } /////////////////////////////////////////////////////////////////////// public function formatTrace( msg:String ):void { msg += " ("; msg += ( parent == null ) ? " parent == null" : " parent != null"; msg += ( root == null ) ? ", root == null" : ", root != null"; msg += ( stage == null ) ? ", stage == null" : ", stage != null"; msg += " )" trace( msg ); } } } |
Here’s the Parent.swf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package { import flash.events.*; import flash.display.*; import flash.net.*; public class Parent extends MovieClip { /////////////////////////////////////////////////////////////////////// private var _loader:Loader; /////////////////////////////////////////////////////////////////////// public function Parent() { trace( "Parent: Parent()" ); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.MEDIUM; _loader = new Loader(); _loader.contentLoaderInfo.addEventListener( Event.INIT, init ); _loader.contentLoaderInfo.addEventListener( Event.COMPLETE, complete ); _loader.load( new URLRequest( "Widget.swf" ) ); } /////////////////////////////////////////////////////////////////////// public function init( event:Event ):void { trace( "Parent: Event.INIT (all assets on frame 1 are loaded)" ); } /////////////////////////////////////////////////////////////////////// public function complete( event:Event ):void { trace( "Parent: Event.COMPLETE (all assets on all frames are loaded)" ); var widget:MovieClip = MovieClip(_loader.content); trace( "---------------------\n" ); trace( "Before Parent.addChild()" ); addChild( widget ); trace( "After Parent.addChild()" ); trace( "---------------------\n" ); widget.x = stage.stageWidth / 2 - ( widget.width / 2 ); widget.y = 60; } /////////////////////////////////////////////////////////////////////// } } |
I jumped into the Flash world through Flex about three years ago. In the past year, I have been going deep with the Flash IDE and am discovering subtleties with the display list that you just don’t hit using Flex Builder. Not that they aren’t there, its just that the normal entities and work patterns that define your world as a Flex developer never result in exposing these types of issues.
Recently we had a project that was exhibiting bizarre behavior when mousing over a pseudo combo-box we were hand-rolling. The thing would pop up upon mousing over the hit area, but then flash repeatedly as we moved around the combo.
It turned out that we were layering an instance of a “hit box” over the combo and then ostensibly removing it by setting the alpha to 0. However, we were also relying on MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT for some of our logic in detecting entry and exit from the combo. Because the hit box was still on the display list, the ROLL_OVER/OUT code wasn’t working.
The solution was pretty simple, once we tracked down the cause. What needed to be done was to set the visibility to 0 of the obstructing hit box rather than changing the alpha to 0.
Above, what is on the stage is a Parent movie clip that has embedded in it a Child movie clip. So the Child is a direct descendant on the display list from Parent. Layered over the Parent is an instance of another symbol, Not Child. Not Child is simply placed on the display list above Parent instance, but is (despite how it looks) NOT a child (thus the name) of Parent.
To see the behavior that tripped us up, use the combo to select a state for the “Not Child” to be “Alpha = 0″ and mouse over where it used to be. You will see that Parent continues to get ROLL_OVER/OUT messages.
Setting the Visibility of Not Child to “Not Visible” will fix all ills.
Here is the code for the Document Class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package { import flash.events.*; import flash.display.*; [SWF ( width = '400', height = '250', backgroundColor = '0xFFFFFF', frameRate = '30' ) ] public class RolloverDemo extends MovieClip { public function RolloverDemo() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; this.f_cboNotChildState.addEventListener( Event.CHANGE, cboNotChildStateChange ); } public function cboNotChildStateChange( event:Event ):void { switch ( this.f_cboNotChildState.selectedItem.data ) { case "visible": { f_notChild.visible = true; f_notChild.alpha = 1; return; } case "alpha_0": { f_notChild.visible = true; f_notChild.alpha = 0; return; } case "notVisible": { f_notChild.visible = false; f_notChild.alpha = 1; return; } } } } } |
The Parent class file looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package { import flash.events.*; import flash.display.*; public class Parent extends MovieClip { public function Parent() { addEventListener( MouseEvent.ROLL_OVER, rollOver ); addEventListener( MouseEvent.ROLL_OUT, rollOut ); } public function rollOver( mouseEvent:MouseEvent ):void { trace( "RollOver Parent" ); MovieClip(root).f_txtOutput.text = "RollOver Parent"; } public function rollOut( mouseEvent:MouseEvent ):void { trace( "RollOut Parent" ); MovieClip(root).f_txtOutput.text = "RollOut Parent"; } } } |
We try very hard at IA to standardize file organization and naming conventions in our projects. However, sad to say, the best of intentions can sometimes get you in as much trouble as negligence.
What we hit was a surprising clash of namespaces between a Top.swf that subsequently loads up a child Widget.swf.
Lets say the Top.swf has this organization for its primary controller class:
1 2 | // Top.swf controller app.controller.MainController.as |
Unfortunately, if Widget.swf also has a controller with the exact same package and filename, Flash gets confused when it loads the Widget:
1 2 | // Widget.swf controller: app.controller.MainController.as // bad - flash will call Top.swf's code or blow up at runtime |
The simple solution is, of course, to change the path for one (or both) of them. Our new policy is to always start the package path with a unique package name for the swf rather than try to mess with the naming scheme of the files:
1 2 3 | // New highest-level packages top.app.controller.MainController.as widget.app.controller.MainController.as |
I assume that multiple loaded swfs would also have these same issues, but haven’t tested that theory.
In hind site (20-20 and all), given the way Flash works, it makes sense that this situation could arise, but it was still a bit surprising Flash doesn’t scope things better.
Welcome to the Infinite Array blog stream of consciousness! Glad you have found us and hope we are informative and possibly even entertaining.
I wanted to start my blog entries with some core concepts that are the basis for my thinking about software engineering and that underpin our software development work here at Infinite Array. Life is strange, and it is always amazing how a single event can serve to guide your path for years to come. I had that kind of experience professionally while working on a very challenging project at Microsoft, and it has shaped my career and interests ever since. So I am making my first blog entry about that stage in my life which will hopefully will both be of some interest as well as give background for my future postings on my take on software engineering.
At that point I was the dev lead for a new v1 language learning product from the Microsoft Encarta group. We had a number of innovative features for the time including a study planner to help you schedule your course work as well as a 3D world that you navigated through to interact with characters from our videos using speech recognition. It was during the creation of these two features that I hit upon what has now become a both a mantra and mission in my professional life. This revolution in my thinking I now call “Contextual Programming“.
While designing the study planner, our team iterated on the feature repeatedly while trying to pin down exactly what we wanted to accomplish. There were so many tricky rules and even trickier exceptions to the tricky rules that progress was very slow. Finally my PM and I sat down for a key planning meeting that would change everything in how I would think about and create complex software systems.
It so happened that at that point in my career I had become very interested in the idea of visually designing software using the Object Modeling Technique (OMT). The OMT was developed by James Rumbaugh and colleagues and brought together in a book in 1991 entitled “Object-Oriented Modeling and Design“:
(I still think this book is an excellent place to start for anyone interested in the visual design of software.) The OMT is the precursor of what has now become UML, so it has an impressive role in the software engineering world and is a lot simpler than UML to get started with.
One of the central design techniques advocated by the OMT is utilizing an advanced form of something called a “state machine” diagram in order to model (draw) how the software system should dynamically change over time. State machines are fundamental computer science, and much of the theory of what computers can do was first expressed using them.
I had also used state machines in practice (real code, not just modeling software) to implement communication protocols, which is a typical application for them to be used in.
Bringing the OMT state machine dynamic models together with some practical experience creating software using them (though to solve a significantly different type of problem) would radically change how I would work in the future.
For those readers that have no idea what I’m talking about, state machines are simply a way of drawing the various operational modes of a process and how they are related. If you have ever seen a site map for a web application with a bunch of boxes for pages and arrows for the transitions between them, then you get it. Here is a simple example:

State machine on how to get a rodent
(BTW, it looks like rodent.com is still up for grabs, in case anybody is interested). The concept is actually quite simple despite how the academic literature usually comes across. Implementing one, on the other hand, demands some careful thought about the how.
So, back at our meeting, my PM and I broke out the beer and spent several hours modeling the logical design for the study planner using the state machine notation from the OMT. When the dust had settled, we had worked through all of the high-level conceptual problems and exceptions that had plagued us during three rounds of wordy specs.
This was huge – by using these diagramming techniques we had successfully worked out in a matter of hours something that had not gelled in weeks. Score 1 for drawing software in the real world.
As I went back to my desk to actually implement the thing, however, I was very torn as to how to go about it. We were short on time and I was under the gun to get this thing baked. The usual way to build such features was create set of objects and write a bunch of event handlers on them to implement the controlling logic (duh – its called “object-oriented programming”). But this time I wanted to try to apply the techniques I had learned developing state machines for communications protocols to creating the controlling logic for a GUI application.
The problem was that OMT then and, to a great extent, UML today, does not have a systematic and universal way to implement these software models by hand. There are tools out there now that will do code generation, but I have not heard much joy about the results and the higher end ones are pricey. Back then, there was nothing at all.
But I felt that I had achieved such clarity with the state machine visualization that I was drawn irresistibly to the possibility of directly implementing this bothersome feature as one.
I had no idea how well, or if, this approach would would work. But I tried it, and for reasons that I have pondered ever since, it worked amazingly well.
Since then have always used state machine controllers when building complex software.
If you are interested, you can take a look at the patent the team received here.
Here are the state diagrams:



The upshot was that we successfully shipped the product and it did quite well for a time until it was sadly killed off during a reshuffling of the organizational deck chairs at Microsoft due to its not earning as much money as MS Office, though admittedly by a long shot. It was probably the hardest work I’ve done as a software developer with one of the best teams ever – I had a lot of fun and learned a lot (like beware your dependencies – but that is another story).
Since then I have been evolving my approach as to how to utilize state machines as the key mechanism for implementing controller systems for complex, stateful applications. In over 10 years in applying it to numerous programming languages and development environments I have never found a situation where it did not add such clarity and precision to the effort that I thought the approach was not worth the overhead.
In my some of my next entries I will be expanding on these ideas that I now collectively call “Contextual Programming”.

