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.

37 thoughts on “Building a simple Flex module

  1. 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?

  2. 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?

  3. 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().

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

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

  6. 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

  7. 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.

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

  9. 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.

  10. 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;
    }

    }

    }

  11. ..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

  12. 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.

    1. I have had problems with memory suck and papervision. I would guess that you memory suck problems are related to papervisions poor garbage collection and not tho module loading in flex. I saw this problem twice with papervision once it was related to how and when the rendering of 3d shapes was handled. The other time was a “ghost” type memory suck related to 3dMesh and collada files unfortunately I can’t remember the specific fix for this one.

  13. 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!

  14. 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.

  15. 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

  16. 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 !

  17. 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.

  18. 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.

  19. Hi Peter,

    Could you please explain and example with more detail how to call parent application from the modules. In my case i have a login module which is used by 3 different mxml applications within the same project. MXML applications are user/manager/admin interfaces which is seperated for simplicity…

    Calling parent application from within the module is not easy, or i could not figure out:
    in Live docs it says parentApplication calls the loader application, but it always addresses the default mxml???
    I tried using Application.application.mymxml_app1 but it did not work.

    In Short, how do we use a module shared by different applications, and how do we call parents from within the module?

    Thanks…

    PS: blog is more readable with this theme, but it needs a contact form or a dummy blog post four our questions ;)

  20. hi,
    Is it possible to load a Module from different folder other than the main application’s folder or its sub folder?

    since, i’m unable to load a module in the following case,
    my main app is in “root/swf/” folder
    my modules are in “root/modules/” folder
    my index page is in “root/htms/” folder
    i’m loading the main app into the index page,

    but the module are not getting loadded and it says something like , “the swf is not loadable”, what is the problem here. can you please guide me?

    thanks
    S. Jagan

  21. Hi all, please help if you can:

    New to flex, I’m trying to compile the SimpleModule example from the Flex 3 (and 4) SDK documentation. In both the Flex 4 and Flex3 SDK’s (command line), the module compiles fine, but the application does not. I get the error: “Access of undefined property: SimpleModule” because of this line:

    sm = assetModule.factory.create() as SimpleModule;

    If I remove that line, the app compiles, and I can run and see that the module loads.

    I’ve tried moving the module source around into different folders, keeping it at the root of the app, and nothing seems to work. Do I need to use a config file somewhere that tells the app how to use the module? do I need to include/import SimpleModule.mxml in SimpleMXMLApp.mxml? That would seem to contradict the purpose of modules. Maybe I’m missing a compiler option?

    Thanks for any help.

  22. I should clarify: Creating the simplest possible module and the simplest possible app, I can get everything to compile as long as the app doesn’t try to call a method on the module. And it runs: I can confirm that the module loads with debug output. But as soon as I add a line in the app that calls a method on the module, I get this type of error. I’m worried that the cited example assumes you already know to use a certain compiler option, or have some other file somewhere providing the information that tells the app.mxml how to access methods on the module.

  23. How is he passing in the m1.child into the videoModule variable? I try to do this but with my own module. It is a windowedApplication as opposed to an Application for my main with the module loader, and I am running on Adobe AIR.

    private var login:loginScreen;

    public function init():void
    {
    login = new loginScreen(mainML.child);
    .
    .

    and then here is my loginScreen (i realize that by naming convention it’s wrong I don’t care though, just trying to learn and hack something together for now).

    Once again, I realize that I am using a “login” with incorrect naming convention as well as doing a log in as a module when I should just do a popup box, but I am experimenting more than anything.

    for some reason this tells me that the loginScreen only allows 0 arguments in the constructor call.

    Another thing that I am wanting to do is resize the main application window to match that of my login screen when the module loads but I haven’t been able to get the correct size thus far. any tips?

    1. Dustin,

      The problem is that you are passing mainML.child to the the loginScreen constuctor as opposed to casting it to a loginScreen type.

      Instead of
      login = new loginScreen(mainML.child);
      try
      login = loginScreen(mainML.child);

  24. Flex 4.0 ,about Module to use,is not different Flex3.0,it not have atterbute “implements”,I don’t know to use it.

  25. Hello,

    Thanks for a good example.I am trying to use this module concept but i am not sure why I am getting Module value as null.Not sure how to use it exactly.

  26. Hello sir,
    this code is running in Flex 3 but it is not running in flex 4, i have some changes of Module with simple two buttons with click Event but its running in Flex 3 not in Flex4, the error is coming “call to undefined or null object reference”.
    Thank you.

  27. Thanks a lot for the tutorial.
    I am having an issue and tried my best but couldnt able to resolve it. Actually i am developing a nested modules application. And when i use “parentApplication” it takes me to the main module. But i only wanted to go one level up module and communicate with the properties of only one level up module.
    So i can be able to do so.

    Thanks a lot for the help.

    Regards,
    Faisal

  28. Thanks a lot for the tutorial.

    I am having an issue and tried my best but couldnt able to resolve it. Actually i am developing a nested modules application. And when i use “parentApplication” it takes me to the main module. But i only wanted to go one level up module and communicate with the properties of that module only.

    So how can i do so?

    Regards,
    Faisal

Comments are closed.