Friday, April 16, 2004

Wacky instance variable initialization

Came across something that is so wacky its hard to believe its true.

We had a component where we initalize an instance variable to an empty object in the class declaration as in:

var myVar = {};

Nothing too earth shattering here!

So its clear we should have an instance variable intialized to an empty object, so I could then do something like this;

myComp.myVar.empty=true;
or this
myComp.myVar.name=_name;

and then trace(myComp.myVar.name) will display the components instance name.

OK so whats the issue .. well it seems that the object that myVar points to is static (or global if you will) so now every instance will see myVar.name as the same name and NOT its own instance name.

We thought we must be missing something about using "{}" so we tried using new Object() instead but to no avail, the object created is always static and all instances will be pointing at the same object.

We resolved it in the end by leaving the var as undefined and then in the ancestor "init" method setting it to an empty object, then it all works correctly or I should say works as expected.

Ok there maybe be some obscure explanation for why this behavior is correct but at least its not obvious nor is it in line with what you would expect in other languages and could catch you out in building you own components so beware...

unless of course its a neat trick you would like to exploit...

Thursday, April 1, 2004

HTML and the standalone player

Ran into a quirky thing today, is it me or are the standalone player and the web player handling HTML slightly differently?

Trying making a movie that loads HTML using the XML object from an external file and insert it into a TextField(there is a sample app that does this in MX2004).

Running this in the web player and it works as you might expect but in the standalone player it seems that it recognises CRLF's in the text as well as BR tags. Thinking about it the problem could be in the XML object... is the XML object stripping CRLF's from the HTML that is being loaded in one version but not the other.

Ok so I guess the two players are different versions, I think from memory the standalone is 7014 and the web is 7019... have things changed?

Anyway if I am right, you need to be carefull about your HTML content if you think someone might be viewing using the standalone player as otherwise your pretty formatting will get screwed up.

Whilst we are talking about HTML and TextFields.. Since we can now load jpg's into the TexField and since these are usually being pulled over the web it can take some time to load. Wouldnt it be nice if there was some event to tell us the TextField had finished loading/rendering. As far as I know there isn't and the result is you must let the user watch your TextField rendering itself as the images are loaded one by one and so alter the layout.



Sunday, February 22, 2004

Writing Documentation Sucks

As a few people noticed we were asking for beta testers for our XPComponents last week.

Well first we were stunned by the response, thought it would take weeks to get the people we wanted, instead it took hours!

Of course then we were caught wrong footed, the docs were not ready to start the beta!!

So this week has been a week of writing docs. Boy does it suck. You seem to write forever and still there is a mountain to climb.

Now I understand why MX2004 got released befor the docs were ready lol!!

I have to mention here JellyVision's ActionDoc it is a superb tool for building documentation for AS2 classes even though its still in an early beta phase.

If you havent got it ... get it now!


Actually, confession time, the last few months of building our components has given me a lot of understanding for WHY MM did certain things the way they did. Sometimes we would find after doing something we swore we wouldn't do that MM had done something quite similar, its like developing incrementally you can end up at a point where there is no way out but to do what at the outset you thought was unecessary

Having said that, it hasn't changed my views on the MM Framework, concept excellent, implemantation flawed, sorry for that!

Inspectable Getters and Setters and Live Preview

I saw an interesting article over at Bit-101 about this subject.

Well its true, as they have found, the Live Preview in MX2004 is pretty screwed up (to use the correct technical term), leading to some convaluted and weird code trying to get things to work, we almost thought about knocking LivePreview on the head at one time!

The basic rule we have now settled on is that setters should never do anything except set an internal variable and then call invalidate(), nothing more... and you should never call draw() directly.

Regardless of how many times invalidate gets called in a frame it will only ever result in a single call to draw() on the NEXT frame, so the constructor, setters or whatever can fire as many times as they like in whatever order they like... and you just do your real work in the draw() function in the following frame.

This does away with the need to check for whether initialization is complete, and solves most of the problem cases.

For those complex situations that need more, there is also a boolean variable childrenCreated that tells you whether the initialisation has occured and you have passed through the creatChildren function. This can be used to allow you to abort functions when they are being called in the incorrect state.

We also decided in our own XPComponents (since were not using the MM framework we can do what we like) to add an initComplete() call to the end of construction process to help resolve one niggling problem, though I have noticed that in the last update to MX2004 they have now built in an _endInit() method which essentialy does the same thing. Except in an isolated case I am really sceptical of the need for this function.


There are a few other things that you should do that solve some other niggling issues that can drive you up the wall trying to resolve...

Place the getter first and put the metadata tag on the getter.

(Helps with getting the inspector to implicitly recognise non string props)

If you extend another class dont use the full path to the class you are extending, first import it using the full path and then extend using just the class name.
i.e
import com.mydomain.mycomp;
class newone extends mycomp{}

DONT do this
import com.mydomain.mycomp;
class newone extends com.mydomain.mycomp{}

(Helps with getting inherited props to be recognised by the inspector)