« April 2004 | Main | October 2004 »

May 25, 2004

Draw/Size model in MX2004

This has been bugging me for a while now, there is something fundamentally wrong with the Draw/Size model of MX2004.

Bear with me as I may ramble a bit as I just try to get some ideas down!!

I mean that, currently in almost every case Draw simply defers to Size which does all the work, which is simple yes, but it does mean that you get Size related methods being fired when size never changed which is inefficient

Fundamentally we have 2 different types of changes to a component, dimensional changes i.e. size and visual i.e. style. TO be efficient we should be able to separate the two types and invalidate and validate the two independently or both together.

We probably need a master method above this that can determine which needs to be called and when.

There is also an issue of timing, if a components has siblings it can be important that any dimensional changes are made immediately so that the components dimensions can be known by its parent i.e. think of cells in a grid, although we can be more relaxed when style changes are effected.

Come to think of it, it isn't that the dimensional changes need to be effected immediately as much as the boundary dimensional values need to be known now!

Also I think part of the issue is that setSize() always calls size()... Yes I know I sound stupid but what I am getting at here is that we sort of have linked in our mind that size() actually does the sizing of the component whereas I think a more useful way of looking at it is that setSize is the one that actually caries out the size operation and it does that by simply changing the height and width properties and nothing else i.e. the properties ARE the size of a component whereas the size() method is an adjustment of the internals of a component in response to dimensional changes, the difference may be too subtle and you might not follow it but I think conceptually there is a big difference here.


I don't think I have this thought through yet but I believe somewhere out there, there is a better model than the current Draw/Size model or at least its current implementation.

Associate a class with a dynamically created movieClip?

I have seen talk around for quite a while about how to associate a class with a dynamically created MovieClip, but I must say I have yet to see a practical example of where you might need to apply this technique, most so far have struck me as hammers looking for nails if you know what I mean.

The techniques all seem to originate from Peter Hall's original idea to use the hidden class package symbols. Some people have commented this is a bit of a hack, is not supported and could cause your applications to fail in the future.

Although I am not really convinced that there is that much danger in this approach (supported or not) of using the package symbol I don’t really understand why it is even necessary.

Basically at the end of the day all you are trying to do is to "borrow" a known library symbol long enough to be able to call attachMovie.

In the technique used by Peter first you have to "find" the hidden package, this entails searching the entire tree from _global on down to find the class you want, a very expensive thing to do, so for efficiency this path is then stored in a hidden property of the target symbol.

So firstly why bother with this - why not use the class SymbolName property? If its your own class then I don’t see why you cant make the SymbolName the same as the class path and this would then obviate the need for such a search. Ok for MM's own classes its wont work (go figure) because for some reason they decided to give classes like mx.controls.Button a SymbolName of Button (maybe someone could enlighten me as to why they did that?).

So ok then the search is required if you are going to use this technique on MM's own classes or are too lazy to define a full SymbolName property in your own class, but wait a minute, we said we were just doing this so that we could borrow a known symbol, why do we need to borrow the package symbol, surely ANY symbol will do?

So if any symbol will do there are other symbols that we know exist, firstly what about UIObject, unless you aren't using any MM components UIObject surely must be there some where, ok its still a bit of a hack but at least its not dependent on some unsupported fudge but ok lets suppose for arguments sake that’s you aren't using the MX2004 FrameWork, well why don’t we put a known symbol into the library ourselves and then use that symbol. As its path is know in advance there is no need for an expensive search or a need to cache the path and its only one symbol, that’s not much work surely?

Yes I hear you say, that is too much like hard work!

Ok lets take this one step further, why not make that symbol into a component of our own!

We could create a faceless component associated with a very small class, lets call it for example, ClassLoader.
Now ClassLoader is a pretty dumb component it extends MovieClip so that it doesn’t use the MX2004 framework, it has no instance methods, no face, nothing except a single static method called createDynamicClass.

You drag ClassLoader on to the stage and then delete it - that gets it into your library.

Now the static method ClassLoader.createDynamicClass actually does the work to instantiate your class and associate it with clip. To do this is needs to "borrow" a symbol... So it borrows its own symbol "ClassLoader" well since ClassLoader will never be instantiated why does it care that someone borrows its Symbol right? So in the createDynamicClass call its registers the symbol to the target class and then calls attachMovie, once attachMovie is finished then it can release the registration, if you wish by calling register passing null for the target class.

Now as I see it this results in a technique that is supported, doesn’t use any hacks, can be readily included in any movie you like simply by dragging the ClassLoader component on stage and the component is also so tiny (less than 600bytes) I doubt you will ever notice its size.

Now all I need is for someone to tell me what I need this component for!
Rob

May 21, 2004

Casting and Array's

I came across a small problem the other day while trying to keep the AS2 compiler happy.

I needed to call a method that took an Array as a param. The object I was passing to the method was actually an Array of Arrays (rows and columns) but for one reason or another it was already typed as a generic Object by the time it got to this point in my code.

Ok its a fairly simple thing to do I know but the compiler wouldn't accept it and complained of a Type Mismatch as I was passing a generic Object.

myMethod(obj) <<mismatch obj is an Object and the param should be an Array
So the obvious answer in AS2 is to cast the Object to an Array.

myMethod(Array(Object))

Now when I wrote that alarm bells went off and I thought I am sure this isn't going to work and sure enough it didn't!

You see unfortunately Array() is already a method defined in AS2 to quote the dictionary:
Array(): Conversion function; creates a new, empty array or converts specified elements to an array.
Using this function is similar to creating an array with the Array constructor.

Normally doing a cast results in a CastOp but Array() results in a callFunction, clearly two very different things.

So what I was doing here was not a cast but a conversion of the original object to a new Array object and it was not simply a copy of my original Array either (which would have worked but would still be a BAD thing) my array of rows seemed to get turned on its side and become an array of columns, whatever happened, the data was screwed up and the results were wrong.

So I pondered whether there is a way to cast something to an an Array? As far as I can see the answer is no!

In the end I came up with a solution, though I felt this was a bit of a hack, using an untyped variable.

var x = obj<

myMethod(x)<<compiler happy with the untyped variable

So I asked around and I received a number of suggestions but most were on the basis of changing the method signatures which sort of misses the point and wouldn't be possible in this case anyway but no suggestion for how you can cast an object to an Array.


The problem I assume also applies to all the intrinsic or Built-In classes that also have methods like this, so String() and Number() also are problems in that they dont cast the object they produce a new object, though maybe these go unnoticed as they effectively produce an exact copy of the original whereas Array does not.
Rob

May 12, 2004

WSDL download failed for the following URLs:

This has been bugging me for a few days and I still can't figure it out.

Everything seems ok, I can even compile and run Mike Chambers MXNA Scroller application.

But can I create a WebService app of my own? No way!

In the flash ide i just cant get the WSDL download to work which sort of cripples you before you even begin.

I even tried putting the WSDL on an Apache server running on my local PC and it still failed!

Interestingly despite Flash saying it failed the Apache WebLog recorded the WSDL was accesed and sucessfully returned to the caller. So that should mean the problem is somewhere inside the ide.

But so far no luck and no one else seems to be that interested (do you really expect otherwise :-) ), actually I found a couple of people who had the same issue but they both had it fix itself and had no clue as to how i got fixed....

Makes u wanna cry....lol... and here's me saying MX2004 is the answer to WebService front ends!

May 06, 2004

When null is not quite null

Well maybe this is obvious to you but it threw me for a while.

Lets say you have an object and you want to check whether it is null...

trace(x==null)

and this shows true.

Its clear that the object x is empty and contains nothing isn't it.

Well actually no.

If x just happens to be an attributes array from an XMLNode it so happens that it will be equal to null and at the same time can contain values...

var x= node.attributes
trace(x==null) // display true
trace(x.age) //displays a valid value for an assigned age attribute..

So does this mean there is no way of finding out if the attributes array is empty without looping over all the attributes with a for(x in attributes) type of check?