06
Aug
07

Building a simple Flex module

I’ve been playing around with Flex Modules lately and thought I’d post this. It’s pretty basic, but it is kind of a “my first module” type experiment. I tried to show a few different things including: calling a module’s methods from the parent application as well as setting properties in the parent application from the loaded module.

If you haven’t looked at modules in Flex yet, I highly encourage you to check out the Flex Doc Team blog at http://blogs.adobe.com/flexdoc/, where you can find their latest version of the “Creating Modular Applications” chapter (blog entry, PDF).

Full code after the jump.

View MXML (main.mxml)

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/06/building-a-simple-flex-module/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.events.VideoEvent;

            [Bindable]
            private var moduleTitle:String;

            private var vm:VideoModule;

            private function init():void {
                vm = VideoModule(m1.child);
                moduleTitle = vm.getModuleTitle();
            }

            private function stopVideo():void {
                vm.stopVideo();
            }

            private function playPauseVideo():void {
                vm.playPauseVideo();
            }
        ]]>
    </mx:Script>

    <mx:Panel id="panel"
            title="Module: {moduleTitle}">
        <mx:ModuleLoader id="m1"
                url="VideoModule.swf"
                ready="init();"/>
        <mx:ControlBar>
            <mx:Button label="Play/Pause" click="playPauseVideo()" />
            <mx:Button label="Stop" click="stopVideo()" />
            <mx:Spacer width="100%" />
            <mx:Label id="playheadTime" fontWeight="bold" />
        </mx:ControlBar>
    </mx:Panel>

</mx:Application>

View MXML (VideoModule.mxml)

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/06/building-a-simple-flex-module/ -->
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
        width="100%"
        height="100%">

    <mx:Script>
        <![CDATA[
            public function getModuleTitle():String {
                return "Video Module";
            }

            /* Stop the video playback. */
            public function stopVideo():void {
                videoDisplay.stop();
            }

            /* If the video is currently playing, pause playback. Otherwise, resume playback. */
            public function playPauseVideo():void {
                if (videoDisplay.playing) {
                    videoDisplay.pause();
                } else {
                    videoDisplay.play();
                }
            }

            private function updateVideoTime():void {
                /* If the playheadTime is 0, the DateFormatter returns an empty string.
                   To work around this we can default the time to 10ms if the playheadTime
                   is zero. */
                var pTime:Date = new Date(videoDisplay.playheadTime * 1000 || 10);
                var tTime:Date = new Date(videoDisplay.totalTime * 1000);
                parentApplication.playheadTime.text = dateFormatter.format(pTime) + " / " + dateFormatter.format(tTime);
            }
        ]]>
    </mx:Script>

    <mx:DateFormatter id="dateFormatter"
            formatString="NN:SS" />

    <mx:VideoDisplay id="videoDisplay"
            source="http://www.helpexamples.com/flash/video/cuepoints.flv"
            playheadUpdate="updateVideoTime();" />
</mx:Module>

View source is enabled in the following example.


23 Responses to “Building a simple Flex module”


  1. 1 Okay Aug 10th, 2007 at 10:16 pm

    Easy enough, but what’s the difference/advantage of doing this vs. just creating a custom class?

  2. 2 Good Nov 7th, 2007 at 2:15 am

    I’m wondering the same thing as the previous poster, what’s the difference/advantage of doing this vs. just creating a custom class in an mxml/AS file?

  3. 3 jason Nov 29th, 2007 at 7:51 am

    I want to develop these modules as different projects. I’ve been looking for how this is done and how you would reference the different modules but I’m not having much luck. Any suggestions?

  4. 4 Greg Jan 3rd, 2008 at 7:08 pm

    I’ll take the liberty of answering the first two questions, which are important ones: why use Modules over classes or componenets?

    A module is compiled separately, as a unique SWF and is then loaded, as needed, by the shell Application. The immediate reason one would go to the trouble to work this way is that modules do not contribute to the file size of the main SWF — they are loaded progressively, much in the way we used to load additional SWFs on-the-fly in Flash with loadMovie().

  5. 5 Joe Beuckman Jan 24th, 2008 at 10:32 am

    What is the advantage of modules over just loading an application as a swf - which can be developed and tested alone, etc.

  6. 6 Joe Apr 22nd, 2008 at 8:06 pm

    你好,我来自中国,看了你写的觉得很好,但是我是属于初学者,希望能和你交个朋友,以后互相学习学习,谢谢哦!

  7. 7 prasanth May 8th, 2008 at 11:35 pm

    I want to add effects when a module loads . like a wipe left .Is it possible .Can you help me out on this

  8. 8 peterd May 9th, 2008 at 8:27 am

    prasanth,

    Does this snippet work for you?

    <mx:WipeDown id="wipeEffect" duration="6000" />
    
    <mx:Panel id="panel"
            title="Module: {moduleTitle}">
        <mx:ModuleLoader id="m1"
                url="VideoModule.swf"
                ready="init(); wipeEffect.play([m1]);" />
    

    Basically it uses the ready event to play a wipe effect.

    Peter

  9. 9 Vito May 18th, 2008 at 12:19 am

    To answer Joe’s question:
    Module vs. Application
    I turned the VideoModule into an application by just changing the module tags and then loaded it via a swf loader in the main.mxml application.

    What happens is your module and main application aren’t able to talk to each other as easily anymore. Not to mention the size of a module is about 10 times smaller than a application. You have to load all the application framework if you swf load an app but you don’t have to do that if you load a module.

    Size differences:
    [SWF] VideoApp.swf - 624,958 bytes after decompression
    [SWF] ApplicationLoader.swf - 681,000 bytes after decompression

    [SWF] VideoModule.swf - 63,301 bytes after decompression
    [SWF] main.swf - 670,323 bytes after decompression

    You can also use modules as building blocks in one application to make a modular application.

  10. 10 prasanth May 18th, 2008 at 10:39 pm

    Hey thanks a lot Peter for the snippet .It worked for me.

  11. 11 Dan D. Jun 4th, 2008 at 8:25 am

    Thank you for this very handy example. It was very useful for me while implementing Flex modules.

  12. 12 Pascal Jun 23rd, 2008 at 9:14 am

    Is there a way to load an MXML module compiled SWF into an actionscript only project?

  13. 13 saul Nov 19th, 2008 at 6:45 am

    What i’ve realised about flex is that as a concept it has been mis-sold.

    Flex has been sold to developers and designers as a tool that offers a great deal of flexibility and ease of use, abstracting out, particularly with respect to visual components, many of the more difficult aspects of flash gui design.

    This is a useless example Peter because the most important aspect about modules and flex into flex is unloading and garbage collection.

    I’m really upset at the moment because i have spent 3 months building my first flex app (something i realise i could have done nearly as well in 2 weeks using html and elements of flash) and i’m stuck.

    I’m stuck because i’m building an app that loads swfs into it using swfloader. I’m stuck because the mythical moses like unloadAndStop isn’t cutting it. I’m stuck because memory just keeps rocketing up and gc is anarchic. The gc hacks don’t work for me. Also, Flex is really tough and really buggy. Its like a year or two from actually working properly.

    I’m so dissolusioned with flex at the moment Peter. And, am viewing you and people who are responsible for marketing this tool as nothing more than doorstep salespeople.

    Why should i have to recreate the wheel to get the darn thing to give me back the memory. I’m not interested in the inner workings of the flash player. I’m not interested in cairngorm or mvc. That was never the promise.

    Peter can you pls, if you really care about this thing, show me how to unload an swf and have it give back the memory. I don’t care if its done through moduleloader or swfloader or loader. I could not care less at the moment. Ideally it would be through swfloader. Or, simple educate me on whether this can be done relatively easily with swfloader and what approach is best for people who are not as3 rocket scientists! Roger that.

  14. 14 saul Nov 20th, 2008 at 9:31 am

    The person above aka mor.on who wrote this, me says…

    …SORRY Peter!

    I was irrational and wrong, well kinda.

    unloadandStop missing TriangleMesh3D

    I am using Gumbo 4.0 SDK - Flex Project, targeting FP10.

    I am using a simple states based model (using enterstate and mouseclick events to execute the loading and unloading of swfs into my main application (aState) at runtime). If i had more time and researched better in the first place i may have invested in a better mvc strategy.

    I am loading papervision3d swfs created in flex mxml/as3.

    The 3d models i use are made with as3 geom and are classes that extend TriangleMesh3D and use jpg skins using the embed/class technique.

    (TriangleMesh3D Inherits from: Vertices3D

    ………………………………………….. …..
    ………………………………………….. …..

    Here is the code of the incoming SWF:

    ……………………………………….
    ……………………………………….

    Here is a code portion of the 3d car model class

    package objects
    {
    import org.papervision3d.core.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.core.geom.renderables.Triangle3D ;
    import org.papervision3d.core.geom.renderables.Vertex3D;
    import org.papervision3d.core.math.NumberUV;
    import org.papervision3d.core.proto.*;

    public class CarFinal extends TriangleMesh3D
    {

    public var verts :Array;
    public var faceAr:Array;
    public var uvs :Array;

    private function v(x:Number,y:Number,z:Number):void
    {
    verts.push(new Vertex3D(x,y,z));
    }

    private function uv(u:Number,v:Number):void
    {
    uvs.push(new NumberUV(u,v));
    }

    private function f(vn0:int, vn1:int, vn2:int, uvn0:int, uvn1:int,uvn2:int):void
    {
    faceAr.push( new Triangle3D( this, [verts[vn0],verts[vn1],verts[vn2] ], null, [uvs[uvn0],uvs[uvn1],uvs[uvn2]] ) );
    }

    public function cobraCarFinal( material:MaterialObject3D=null, initObject:Object=null )
    {
    super( material, new Array(), new Array(), null );
    verts = this.geometry.vertices;
    faceAr= this.geometry.faces;
    uvs =new Array();
    v(108.544,-31.9748,-101.242);
    ………………………
    f(1248,5195,5196,1248,5195,5196);
    this.geometry.ready = true;
    }

    }

    }

  15. 15 saul Nov 20th, 2008 at 9:34 am

    ..I have managed to load child apps/swfs into the main app using SWFLoader. Testing went well with two browser exceptions (opera and chrome).

    However, they all failed on

    …The problem: When the swf is unloaded the ram used (lets say 30 mb) stays. As the swfs load and unload without the ram being taken back that ram keeps going up. A ram/gc/listener/referencing/EventDispatcher problem?

    Using unloadAndStop(true) sorted out the cpu usage that unload and FP9 were not doing, which is interesting because cpu usage goes to 0 on unloading so are my loaded swfs/references/listeners getting unloaded/killed properly…Well they can’t be.

    The garbage collector does not free any of the ram that is used to render the loaded swf (the swf contains 3d data as described above).

    The TriangleMesh3D is still being referenced

  16. 16 saul Nov 20th, 2008 at 9:36 am

    i don’t think its on adobes priority list for flash player 10s unloadAndStop method.

    So Let me just test…

    …10 mins later.

    Thats interesting i took the 3d as3 geom model away and left the plane with a bitmap on it. When i clicked in and out to load/unload the memory rose to about 250mb then it started to drop and level off at 230 (i am reading the memory through windows task manager), i think unloadAndStop and gc set to true is doing its job(s) but gc took a little time to kick in. It didn’t go back to the original main app weight of about 170mb ram on first load either, which gives me a little concern that there is initial memory leakage or perhaps gc allocates a suitable byte allocation block on the flash player to that level after its loaded up everything?!

    Most importantly though the ram stabilised and even came back down a little. So its the 3d model thats the culprit i think!

    I’ve tried using the memory profiler in flex to look into this also but cannot get that to work - don’t ask - so i don’t know exactly but its becoming clear
    that the 3d model is still being referenced and maybe the skin to.

    Can you please help me with this problem.

    Help me define it and solve it. What is this problem exactly. Why is UnloadAndStop() not terminating the references/listeners generated by the 3d model on the loaded swf.

    Is the loaded swf reversing the referencing logic through EventDispatcher.

    How can I terminate the references and from where, which app, main or loaded.

    Pls help me.

  17. 17 Allen Nov 27th, 2008 at 5:17 am

    Hi,Petter!
    I come from China too,thank you for your tutals,but I still have diffficult in understanding modules applications.Using modules can decrease the file size of our swf,but Runtime Share can also do,what’s different between them,and what time should use the module?
    Thank you!

  18. 18 Tones411 Dec 18th, 2008 at 1:24 pm

    Keep in mind that if your main application tries to reference a component in a module that hasn’t loaded yet, you might have an error.

  19. 19 Agent X Mar 2nd, 2009 at 9:27 pm

    I’m in the process of modularizing my application using Flex’s ModuleManager. I’m able to load the module fine, but I can’t figure out how to properly listen for events generated from the class instantiated after the module is loaded. For example, the application I’m working on loads the user registration module when the user clicks on the ‘register now’ button and listens for a registration complete event so it can pass off control to another module after the user is finished registering. The problem is that the main application never hears the registration complete event, even though the event is definitely being dispatched and the main app has added an event listener to the module as follows:

    private function moduleReadyHandler( event:ModuleEvent ) : void {
      var component:UIComponent = moduleInfo.factory.create() as UIComponent;
      component.addEventListener( Event.COMPLETE, registrationComplete );
    }
    

    Any suggestions?

    Thanks,
    AX

  20. 20 amar shukla Mar 16th, 2009 at 12:57 am

    Hey Saul ,

    Why don’t you stop using flex for development if you hate it so much. Why don’t you go for SilverLight or JavaFX . I am sure if you will try once the other RIAs you will hate them like hell . So better try to understand the framework then only come to any conclusion And don’t think that I am doing marketing of flex by this statement but I like Flex.

    Great tutorial Peter !

  21. 21 nicemandan Apr 1st, 2009 at 2:45 pm

    Also one point about modules vs classes that has been missed is this: outsourced work. I’m building a framework for a games portal where most of the mini games are built by outsourced developers. Providing them with an API containing interfaces to the main application, built on top of mx.modules makes integrating their mini games a fairly easy process.

  22. 22 Nucles Apr 20th, 2009 at 10:42 am

    Hello Peter,

    thank you for this tutorial!
    For all other who would like to compare the module with application I would advise to the adobe doc:
    http://livedocs.adobe.com/flex/3/loading_applications.pdf

    See “Comparing loaded applications to modules” at page 13.

    Regards,
    Nucles

  23. 23 Panupan Sriautharawong May 16th, 2009 at 10:22 am

    Saul, you will have better results if inside your modules you write a cleanup method.

    You cannot rely solely on the module unloading to take care of your mess (at the moment anyway). The cleanup method should remove all event listeners, and manually try to free as much memory as possible. Before you unload your module you must call this cleanup method first. You must also be sure to remove any references to the unloaded module inside your application, otherwise the memory won’t get freed.

    You’ll notice in the memory profiler that even if your cleanup method is perfect, the memory usage will continue to rise. This is OK. If you notice the memory will reach a plateau. This means the memory isn’t leaking. However, if you notice the memory continue to rise indefinitely, you have a memory leak.

    Good luck.

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".




Badge Farm

  • Powered by Redoable 1.2
  • Cornify
  • Feeds burnt by Feedburner
  • Feed