16 Replies Latest reply on Jan 20, 2007 10:59 AM by Peter Lorent

    architecture question...where to put the code

    SPGAnne Level 1
      Newbie here, so please be gentle and explicit (no detail is too much to give or insulting to me).

      I'm hoping one of you architecture/design gurus can help me with this. I am trying to use good principals of design and not have code scattered all over the place and also use OO as much as possible. Therefore I would appreciate very much some advice on best practices/good design for the following situation.

      On my main timeline I have a frame where I instantiate all my objects. These objects refer to movieClips and textFields etc. that are on a content frame on that timeline. I have all the instantiation code in a function called initialize() which I call from the content frame. All this works just fine. One of the objects on the content frame is a movieClip which I allow the user to go forward and backward in using some navigation controls. Again, the object that manages all that is instantiated on the main timeline in the initialize() function and works fine too. So here's my question. I would like to add some interactive objects on some of the frames of the movieClip I allow the user to navigate forward and backward in (lets call it NavClip) . For example on frame 1 I might have a button, on frame 2 and 3 nothing, on frame 4 maybe a clip I allow the user to drag around etc. So I thought I would add a layer to NavClip where I will have key frames and put the various interactive assets on the appropriate key frames. So now I don't know where to put the code that instantiates these objects (i.e. the objects that know how to deal with the events and such for each of these interactive assets). I tried putting the code on my main timeline, but realized that I can't address the interactive assets until the NavClip is on the frame that holds the particular asset. I'm trying not to sprinkle code all over the place, so what do I do? I thought I might be able to address the assets by just providing a name for the asset and not a reference to the asset itself, and then address the asset that way (i.e. NavClip["interactive_mc"] instead of NavClip.interactive_mc), but then I thought that's not good since I think there is no type checking when you use the NavClip["interactive_mc"] form.

      I hope I'm not being too dim a bulb on this and have missed something really obvious. Thanks in advance to anyone who can help me use a best practice.
        • 1. Re: architecture question...where to put the code
          kglad Adobe Community Professional & MVP
          you can do something similar to what you've already done. keep all the important code in one location on your main timeline in an initialize() function (different from your current one(s) ).

          you'll call that function (or those functions) when the objects are on-stage using code attached to the frame where those objects appear on-stage.

          if you were using oo coding that initializing code would be called automatically when your objects loaded.
          • 2. Re: architecture question...where to put the code
            SPGAnne Level 1
            Dear Mr/Ms kglad

            Thank you so much for your reply. Could you clarify your statement:

            "if you were using oo coding that initializing code would be called automatically when your objects loaded. "

            Thank you.

            Also If I understand your advice correctly then on frame 1 of NavClip I would say something like _root.initNavAsset1(); Then on frame 4 I would have something like _root.initNavAsset2(); etc. If that is right, 2 questions arise.
            1) since users can go forward and backward in the NavClip and I only want to initialize the objects once, do you recommend that I put code on NavClip or code in the initNavAssetn functions to see if the object already exists before instantiating. It would seem to me the latter is the better practice.
            2) I had been told that using _root is generally a bad idea in case you wind up doing some dynamic loading of .swf's since you can lose track of who _root really is. If that is the case how should I pass a reference to the NavClip of where the initNavAssetn() functions are?

            Thank you again for your patient help.
            • 3. Re: architecture question...where to put the code
              kglad Adobe Community Professional & MVP
              1. put all your initNavAsset() functions in frame 1 of your _root timeline with no graphics on-stage. start your graphics and other code beyond the first frame.

              2. i start all my projects with the following on timeline that will contain all my code:

              tl = this; // where i think of tl as shorthand for timeline.

              and then i use tl to prefix all references that need prefixing.

              3. what i meant about oo coding was, if you were creating object classes and placing them in a class file, those classes would be initialized when the objects from the classes loaded.
              • 4. Re: architecture question...where to put the code
                Peter Lorent Level 2
                But why do you need the timeline in the first place? Remember, a key frame is just an event that controls the state of the movie and in true OOP that event should be broadcasted by an object (class) to objects that subscribed to the event.
                In general there should only be one (or two using the import statement) line of code on that first frame of the main timeline:
                var my_app:App=new App();
                While not my personal preference but if you want to draw your interface in the IDE, an option is to extend the MovieClip Class (as kglad mentioned).
                And yes, the compiler skips datatype checking when using the array notation.
                • 5. Re: architecture question...where to put the code
                  MotionMaker Level 1
                  Another approach can be to create Classes for the button clips and tie each button's class in with the library properties plus a linkage id. If the class is generic enough then the buttons clips could share the class - depends on the OOD.

                  Have the button clips classes dispatch events. You want to include the EventDispatcher and Delegate classes found in the Components documentation.

                  Create a class for the navClip and tie in with the library.

                  Have the navClip instantiate the buttons and become a listener to the buttons and then dispatch events based on the buttons activity.

                  So for example a "home" button might have an onRelease event that is dispatched that the navClip listens for and it in turn dispatches an event (say onNewPage) that some other code (content loading code say) listens to hear and then does its thing.

                  With this approach when you are done, all code is external and non of the objects are depending on the timeline paths in code so the clips symbols are reusable in other arrangements.
                  • 6. Re: architecture question...where to put the code
                    Peter Lorent Level 2
                    With all due respect, that's not another approach. That is what kglad has explained: extending the MovieClip Class.
                    • 7. Re: architecture question...where to put the code
                      MotionMaker Level 1
                      Well consider it a contribution to elaborate on the details.
                      • 8. Re: architecture question...where to put the code
                        kglad Adobe Community Professional & MVP
                        i think spganne is laying low to avoid fallout.
                        • 10. Re: architecture question...where to put the code
                          SPGAnne Level 1
                          First, thank you all VERY much for you help. Lon, your elaborate details were much appreciated and made kglad's comment clearer to me. (As I mentioned in my original post, no amount of detail is too much for the likes of me. Sometimes, I think I'm quite a dim bulb and need things spelled out.) Also, LuigiL your help is always wonderful. I am pondering all that you guys have said, and will do some experiments now. Just a warning to all of you, that I'm pretty sure I'm going to have some follow-on questions.

                          For example, yesterday I tried kglad's suggestion and put a statement on the NavClip frame that had a draggable item on it (draggable_mc). The statement was: _root.initNavClipAsset(draggable_mc); And then I put some code in the initNavClipAsset(...) function to check to see if the object had been instantiated already (if myDraggable != undefined)...myDraggable = new Draggable(draggable_mc). I thought I should do this so that the object is only instantiated once, not if the user goes in and out of that frame. Well the logic worked fine, HOWEVER the second time I came into the frame, the draggable item no longer worked. I figured that was because it didn't know how to address draggable_mc anymore. So I found that I needed to reinitialize everytime I go into the frame of NavClip that had the draggable item on it. So that brought up a question about garbage collection.

                          Do I need to first delete myDraggable if it is NOT UNdefined or if I just do another myDraggable = new Draggable(draggable_mc) will the object currently assigned to myDraggable get cleaned up properly?
                          • 11. Re: architecture question...where to put the code
                            SPGAnne Level 1
                            oops, just noticed a typo...I meant to say:
                            if (myDraggable == undefined){
                            myDraggable = new Draggable(draggable_mc);
                            }
                            • 12. Re: architecture question...where to put the code
                              Peter Lorent Level 2
                              Your class Draggable should have a method destroy() that deletes the assets when they are no longer needed.
                              Garbage collection: local variables are deleted automatically but everything else... the fun ain't over untill you put your proverbial toys away.
                              If you want to make sure only one instance is alive... Singleton.
                              • 13. Re: architecture question...where to put the code
                                SPGAnne Level 1
                                LuigiL - I want to make sure I REALLY understand since I may be misusing terminology.
                                Here's a more specific example.
                                Suppose I have a movie clip (myClip_mc) in the symbol library (I call this clip an asset) AND I have that movie clip on the stage.
                                Suppose I have the following code:
                                var myDraggable:Draggable;
                                initDraggable = function() {
                                myDraggable = new Draggable(myClip_mc);
                                }
                                Whenever I enter the frame that has the actual myClip_mc on it I call initDraggable.
                                1) Do I wind up with another object each time this function is called, even though I have only one variable (myDraggable) that is storing the reference to the object?
                                2) If that is the case, then should I have logic that says if myDraggable != undefined then myDraggable.destroy();?
                                3) I would assume the destroy method would say delete this but would NOT delete the myClip_mc.

                                Thanks again for your patient help.
                                • 14. Re: architecture question...where to put the code
                                  Peter Lorent Level 2
                                  1. First of all, the code should be:
                                  var myDraggable:Draggable=new Draggable(myClip_mc);
                                  myDraggable.initDrag();
                                  Where initDrag() is defined in the Draggable class. When you start coding functions on the timeline... that's asking for problems.
                                  >>Do I wind up with another object each time this function is called
                                  Well, no, but. That would totally depend on the code in the (Draggable) class. Let's say you would have a private static var counter (private static, so a class property instead of an instance property) and you would increment that counter using a setInterval(). The second time you enter the frame and create a new Draggable object... the counter starts at the last value of the 'old' object. So, you don't get another object with your function literal but you still end up with a faulty program. And the same goes for listener objects that are not removed, tweens that are running and so on.
                                  The destroy() method in a custom class (=object, I can't stress that enough...) needs to do the cleanup, removing anything you don't need anymore.
                                  2. if myDraggable != undefined
                                  You shouldn't be using that, period. If you don't need the asset anymore, delete it using the destroy() method. Again, if you want to make sure only one instance of a custom object is alive, use the Singleton design pattern. To elaborate on inheritance: define the Draggable class (class Draggable extends MovieClip) and connect it to the myClip_mc using the linkage identifier in the library). In the Draggable class you can define a function unOnLoad (an event fired when myClip_mc is removed using myClip_mc.removeMovieClip()...) and do the cleanup there.
                                  3. A destroy() method performs a cleanup of any assets we don't need anymore to make sure we don't end up with all kinds of stuff hanging around in the memory. When you extend the MovieClip Class you can (additionally) use the onUnLoad event. And with the code you posted, no it wouldn't delete the myClip_mc unless you program it to do so.

                                  • 15. Re: architecture question...where to put the code
                                    SPGAnne Level 1
                                    Dear LuigiL,
                                    Thank you so much for your long and detailed tutorial. I have read it many times now and hope I fully understand. I need to ponder some more to see how this applies to my particular situation. If I'm still confused on what to do, do you mind if I contact you off list?
                                    • 16. Re: architecture question...where to put the code
                                      Peter Lorent Level 2
                                      That's fine by me.
                                      As a rule of thumb in true OOP: stay away from the timeline as much as possible. I only use the timeline when I must create an animation that either needs to be done quickly or when coding it would be very hard to do (walking characters, cartoons or sequences in games just to give some examples).