Mediating a swf's document class causes an Error

Pedr's Avatar

Pedr

29 Sep, 2010 01:06 PM

I am loading a swf that has been published from the Flash IDE with a document class [SomeDocumentClass]. The swf loads fine and I can listen to the events the document class dispatches without problems by listening to the SWFLoader that loads it.

I decided to refactor things so that I am Mediating the document class directly. However this causes an error to be thrown.

ReferenceError: Error #1056: Cannot create property product_1 on app.view.ui.flash.SomeDocumentClass
at flash.display::Sprite/constructChildren()
at flash.display::Sprite()

Where product_1 is the name of one of the MovieClips placed on the swf's stage at authortime and never referenced in the document class.

Does anyone have any idea how I can work around this?

  1. Support Staff 1 Posted by Shaun Smith on 29 Sep, 2010 01:15 PM

    Shaun Smith's Avatar

    Interesting. How are you mediating the document class directly without compiling it into your shell swf?

  2. 2 Posted by Stray on 29 Sep, 2010 01:19 PM

    Stray's Avatar

    Hi Pedr,

    This is an interesting one,

    usually the error you're describing happens when you declare a stage item (like a MC) with a name on the stage, where you don't have "automatically declare stage instances" checked in your publish settings.

    Workarounds include making your document class dynamic, or adding the item using code in the document class. Or of course you can check the "automatically declare stage instances" option.

    But.. it sounds like this exact swf was fine until you put it directly into the mediator map?

    If you can confirm that this is the case, we can look into it a bit more.

    Personally I don't mediate the swfs I load directly. I wrap them in a bridging view class (to which they are added) and I mediate that. I think that's an easier workflow to understand - keeps the responsibilities more separate, and also makes your app more flexible as it's not coupled to the loading of a specific swf.

    The other option is to simply relay the sharedEventDispatcher events to and from the main robotlegs eventDispatcher. I'm a fan of this approach as well, as it creates a class which very neatly describes the event flow between the two parties.

    I hope this is helpful,

    Stray

  3. 3 Posted by Pedr on 29 Sep, 2010 01:46 PM

    Pedr's Avatar

    @Sean

    Sorry - not sure what you mean. I'm Mediating it as I would any component - mediatorMap.mapView( SomeDocument, SomeDocumentMediator). Are you suggesting the problem is something to do with different application domains?

    @Stray

    Thanks.

     If you can confirm that this is the case, we can look into it a bit more.

    Yep. It's not any of the things I would normally expect to throw throw this error. It is definitely getting thrown as a result of the Mediation directly or indirectly, but I'm not getting anything helpful in the stack.

    As far as Mediating it directly, it's a small piece of functionality I have had to snap off from the main app into a fla that can be edited and replicated by people who know almost nothing about code. I want to treat it like it is just another component and Mediate it directly without caring that it has been loaded as a swf.

    I've put together a simple example (attached).

  4. 4 Posted by Pedr on 29 Sep, 2010 01:53 PM

    Pedr's Avatar

    @Stray

    Thanks. Making the document class dynamic stops the error being thrown, but it would still be interesting to know why this is happening.

  5. 5 Posted by Stray on 29 Sep, 2010 02:02 PM

    Stray's Avatar

    Hi Pedr,

    the reason it happens is because of what Shaun picked up on - you are importing the document class into your main App to map against.

    However, when you have that 'auto declare stage instances' checked, flash edits the document class at export and effectively makes it dynamic.

    Because the non-dynamic document class is the first one the app loads (before the swf loads) you're loading the non-dynamic one, and your swf is instantiating using this version and not the dynamic version that is compiled in the swf.

    [I haven't done a joa and looked in the byte code to discover this, it's just from trial and error]

    Stray

  6. Support Staff 6 Posted by Ondina D.F. on 29 Sep, 2010 02:05 PM

    Ondina D.F.'s Avatar

    Maybe
    public static const URL:String = "assets/runtime/swf/someSWF.swf";
    instead of
    public static const URL:String = "runtime/swf/someSWF.swf";

    would at least eliminate the ReferenceError: Error #1056
    Ondina

  7. 7 Posted by Stray on 29 Sep, 2010 02:16 PM

    Stray's Avatar

    > Maybe
    > public static const URL:String = "assets/runtime/swf/someSWF.swf";
    > instead of
    > public static const URL:String = "runtime/swf/someSWF.swf";
    >
    > would at least eliminate the ReferenceError: Error #1056

    The reference error is generated inside the swf, so the path to the swf shouldn't affect it.

    Did you compile and find this eliminated? Would throw our dynamic / application theories out ... so it would be good to know if this is the case.

    Stray

  8. 8 Posted by Pedr on 29 Sep, 2010 02:29 PM

    Pedr's Avatar

    @Stray

    You and Sean were right. I decompiled the swf and Flash adds:

    public var movieClip_1:MovieClip;

    to the document class. Obviously my original document class was used and when the sprite tried to assign movieClip_1 the variable it is expecting isn't there , causing the error. I'm still slightly confused by how the movieClip_1 actually gets created and assigned, but I guess that's another far more complicated story.

    Thanks for your help.

  9. 9 Posted by Stray on 29 Sep, 2010 02:34 PM

    Stray's Avatar

    It's just part of what the 'automatically declare stage instances' does. It's not even just dynamic in that case - it's actually declaring the variable in the document class. I had thought it made it dynamic as well (if you can see that in your decompiled class I'd be interested to know).

    Great stuff - glad we got to the (typically adobe-style obscure) cause of it!

  10. 10 Posted by Pedr on 29 Sep, 2010 02:48 PM

    Pedr's Avatar

    No dynamic to be found:

    package app.view.ui.flash
    {

    import flash.display.*;
    
    public class SomeDocumentClass extends Sprite {
        public var movieClip_1:MovieClip;
    
        public function SomeDocumentClass() {
            return;
        }
    }

    }

  11. 11 Posted by Stray on 29 Sep, 2010 02:55 PM

    Stray's Avatar

    Great - thanks - good to know what it's doing!

    Did you know that all the frame code is represented as functions called function1 function23 (if it's on frame 23) and so on?

    Amazing what the compiler for FLAs gets up to.

  12. Support Staff 12 Posted by Shaun Smith on 29 Sep, 2010 03:02 PM

    Shaun Smith's Avatar

    By the way, if you want to avoid compiling that class into both SWFs, you could map against the class name and inject an interface:

    mediatorMap.mapView("package.to.your::ViewClass", SomeMediator, ISomeView);
    

    And your mediator would manipulate the view through that interface:

    [Inject]
    public var view:ISomeView;
    

    Might also solve the original issue.

  13. Support Staff 13 Posted by Shaun Smith on 29 Sep, 2010 03:05 PM

    Shaun Smith's Avatar

    @Stray: I think it's amazing that Adobe managed to get AS3 to work on the timeline at all!

  14. 14 Posted by pedr browne on 29 Sep, 2010 03:07 PM

    pedr browne's Avatar

    Yep. The good old undocumented addFrameScript(). Definitely handy to know
    about.

    On 29 September 2010 15:57, Stray <
    [email blocked]<tender%[email blocked]>
    > wrote:

  15. 15 Posted by Stray on 29 Sep, 2010 03:25 PM

    Stray's Avatar

    It's a beautiful thing. We now set up most FLA code in an xml doc and apply it all that way. Easier than scrubbing through 8000 frames to find out what the hell the designer accidentally copied / deleted ...

    And Shaun - you're right. The whole FLA / swf thing is quite miraculous - the inconsistencies are fairly exceptional under the circumstances!

  16. Support Staff 16 Posted by Ondina D.F. on 30 Sep, 2010 07:34 AM

    Ondina D.F.'s Avatar

    I tried to load the swf like so:

    http://gist.github.com/604180

    This works. I don’t know if that’s what you wanted to achieve or if
    you found a better solution already.
    I'd be interested to hear how you guys solved the issue or if you tried what Shaun
    suggested.

    Ondina

  17. 17 Posted by Stray on 30 Sep, 2010 07:47 AM

    Stray's Avatar

    Hi Ondina,

    the problem was that (as we suspected) Flash actually amends the document class to give it the children as stage properties when it exports the swf, because 'automatically declare stage instances' is checked.

    The Class being imported into the loading app was the unamended version of the document class. Making the document class dynamic did the trick (as it is the first one loaded it is then used in the swf once it is loaded too, but doesn't have the amendments that Flash made on publish).

    Pathing wasn't (as far as we can see) relevant - it was the additional properties the flash compiler adds that were the missing ingredient.

  18. Support Staff 18 Posted by Ondina D.F. on 30 Sep, 2010 08:09 AM

    Ondina D.F.'s Avatar

    Hi Stray,

    true, the pathing wasn’t the problem. My compiler complained though the first time I tried Pedr’s example and I didn’t see that it came from the loaded swf. Sorry about that.

    I tried Pedr’s original example with a dynamic class and it didn’t work. Maybe I was doing something wrong.

    In my example I didn’t have to make the class dynamic. The swf is added to the stage on loader complete event. That’s all.

    Ondina

  19. Stray closed this discussion on 10 Feb, 2011 04:07 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac