6 Replies Latest reply on Jan 23, 2008 10:20 AM by cicnats

    class instance at edit time

    cicnats
      I'm having a bit of a problem with this:

      I have a movieclip, which is defined to be of a certain class, that extends MovieClip. Now.. if I use attachMovie to attach a new instance, it's constructor executes and I can immediately call it's methods.. But if I have an instance of it created at edit time, I have to wait for a frame, because it's methods aren't available right away (they are undefined) and the constructor executes after the outer code.

      Is there a way to tell it immediately what class it is? My current workaround is to hide the instance and attach a new one and use the first one as positioning reference.. but that's not really optimal..

      Any ideas?

      and, erm, yes, since the project is in a bit of a hurry I have temporarily given up on learning as3 and am instead discovering the wonderful world of as2 classes.. :)

      edit:
      Uh, actually it's more complicated... it works with objects on stage, but doesn't with objects inside other objects that were put on stage at edit time...
      something like this: (the _root. notation is just to show where is what, not actual code of anything)

      _root.myObject:MyClass - it works, I can call eg myObject.doSomething() and it does

      _root.myObject2:MyClass2, which contains
      _root.myObject2.myObject:MyClass - doesn't work, myObject2.myObject.doSomething is undefined

      however

      myObject2.attachMovie("MyClass", "myObject", 1, {_y:myObject2.myObject0._y});
      myObject2.myObject0._visible = false;
      then
      myObject2.myObject.doSomething works

      I'm completely confused now..

      edit2:
      I think even that is not the case, but this:

      _root.attachMovie("MyClass2", "myObject2", 1, {})

      then

      myObject2.doSomething2() works, but
      myObject2.myObject.doSomething is undefined.. (the constructor hasn't even executed yet, but executes before the next frame)

      yes, that's the case I think.
        • 1. Re: class instance at edit time
          kglad Adobe Community Professional & MVP
          no. the code attached to your frame executes first. then any code attached to objects on-stage in that frame begins to execute in a certain order.

          and i'm not sure what you're doing with the rest of your example. but you can always use trace() functions to determine in what order flash is executing your code.
          • 2. Re: class instance at edit time
            cicnats Level 1
            Yes, I've tried tracing, that's how I noticed that it executes after the frame code..

            This is roughy what I'm doing:
            I made a movieclip containing a textfield, and made it into a class. This is simply to wrap several things you can do with a textfield and textformat and do it in a single call.. for example .init("Hello", {size:12, autoSize:true, _width:200, align:"left"}) And to have a certain font and character range embedded and defined at one single place.

            Now when I build other objects, like for example a labeled input field, that contains two of my text objects.. and I create the input fields dynamically, like for a form, every input object that I attach constructs when attached, but the text objects inside it construct only after the code doing the attaching, so I can't for example set the labels..

            So what I do instead is when doing an .init for the created input fields, I hide the text objects inside that were created at edit time, and attach two new ones and give them appropriate parameters to mimic the old ones..

            Not really pretty, but it works..
            • 3. Re: class instance at edit time
              kglad Adobe Community Professional & MVP
              why not assign the labels in your class. it's just one more parameter to pass.
              • 4. Re: class instance at edit time
                cicnats Level 1
                I'm not sure I understand what you mean..

                Do you mean giving the instance some default value parameter, so it can set itself to that, when it constructs?
                • 5. Re: class instance at edit time
                  Level 7
                  Hi cicnats,

                  If I understand you correctly, you're talking about the difference
                  between assigning a class to the movie clip in the Linkage (or Component)
                  definition dialog box, and creating a class instance on the first frame of
                  the movie, correct? The second type of class, techically, is not defined to
                  be a Movie Clip or, in fact, anything but a generic class object because
                  you're not extending the clip but rather creating an instance *in* it. This
                  also makes it more difficult to detect (as you've noted) since it doesn't
                  exist until some time after the clip is instantiated, has a timeline, and
                  the class instance is there (which could take a while). I typically do a
                  looped funcion to check for a variable (or function) within the class
                  instance before attempting to call it. It looks something like this (in a
                  very generic form):

                  this.onEnterFrame=function() {
                  //Assuming myClip is the clip with the class instance, myInstance is the
                  class, and myVar is some variable in the class
                  if ((myClip.myInstance.myVar!=undefined) &
                  (myClip.myInstance.myVar!=null)) {
                  myclip.myInstance.doSomething();
                  this.onEnterFrame=undefined;
                  }//if
                  }

                  It's a bit clunky but it works. However, because of this uncertain chain
                  of events I created a de-coupled event broadcaster for my BNMAPI that works
                  in a more elegant (and sure) way. Within the class constructor, I would add:

                  API.broadcast({message:"Class.READY",sender:this});

                  ...and in the clip that needed to get called I would add:

                  function onClassread(eventObj:Object) {
                  var classInstance=eventObj.sender;
                  classInstance.doSomething();
                  }
                  API.addEventListener(this.onClassRead,this,"Class.READY",null,true);

                  Now when the class is created, an event is broadcast and the event listener
                  function is called. Note that this is different from the built in Flash
                  event listener in that it doesn't need to be bound to the broadcaster. If it
                  did, you would run into the same problem (can't bind to a broadcaster that
                  doesn't exist yet). Email me if you're interested in the API...it's open
                  source and using it would add literally one extra line of code to the
                  example you see above. patrick (AT) baynewmedia (dot) com

                  Regards,
                  Patrick Bay
                  BAY NEW MEDIA


                  "cicnats" <webforumsuser@macromedia.com> wrote in message
                  news:fn4i5j$qaj$1@forums.macromedia.com...
                  > I'm having a bit of a problem with this:
                  >
                  > I have a movieclip, which is defined to be of a certain class. Now.. if I
                  > use
                  > attachMovie to attach a new instance, it's constructor executes and I can
                  > immediately call it's methods.. But if I have an instance of it created at
                  > edit
                  > time, I have to wait for a frame, because it's methods aren't available
                  > right
                  > away (they are undefined) and the constructor executes after the outer
                  > code.
                  >
                  > Is there a way to tell it immediately what class it is? My current
                  > workaround
                  > is to hide the instance and attach a new one and use the first one as
                  > positioning reference.. but that's not really optimal..
                  >
                  > Any ideas?
                  >
                  > and, erm, yes, since the project is in a bit of a hurry I have temporarily
                  > given up on learning as3 and am instead discovering the wonderful world of
                  > as2
                  > classes.. :)
                  >

                  • 6. class instance at edit time
                    cicnats Level 1
                    Hm, thanks, but I'm not too keen on using a delayed action like onEnterFrame or events.. I need some information about the instance right away, for example, a thumbnail movieclip class, that has a mouse sensitive background, an image object and text object.. I need to know the height of the text object, so I can resize the background to cover the entire text object plus image, and to correctly position the next thumbnail (stacked thumbs)

                    I think I'm almost (almost ) happy with what I said before - placing objects at edit time to visually define a layout (instead of doing all at runtime with numbers), then hiding them when dynamically creating the entire object and attaching instances using the static ones as reference. In practice this is just doing

                    instance_ref._visible = false;
                    SomeClass.create(... {_x:instance_ref._x, _y:instance_ref._y}, params); // static function

                    instead of

                    instance.init(params);

                    If I don't like having extra instances, I could make a static function
                    SomeClass.replace(target, params)

                    that would move the reference movieclip to a positive depth, remove it (If I'm not mistaken, statically created instances have a negative .getDepth and can't be removed, like also dynamic ones given a negative depth.. but can be removed if .swapDepth-ed to a positive depth..) and place the new attached instance at it's depth and position, and .init it ..

                    In fact thinking about it.. I almost feel like giving this a try..

                    edit:

                    yep, it works