views:

93

answers:

1

In a sane world, this works as expected:

var array:Array = ['a','b','c'];
trace(array.indexOf(array[0])); // returns 0

In an insane world, this happens:

trace(Screen.screens.indexOf(Screen.screens[0])); // returns -1

... if Screen.screens is an Array of the available instances of Screen, why can't that array give an accurate indexOf one of its own children?

edit - To take it a step further, check this out:

for each(var i:Screen in Screen.screens){
 for each(var j:Screen in Screen.getScreensForRectangle(this.stage.nativeWindow.bounds)){
  trace(i, j, i == j); // returns false
  trace(i.bounds, j.bounds, i.bounds == j.bounds); // returns false
 }
}

At least one Screen listed in Screen.screens should be identical to a Screen in Screen.getScreensForRectangle(this.stage.nativeWindow.bounds) - but even if you compare the Screen.bounds, it still doesn't match up, despite the two Rectangle objects having the same dimensions!

Insanity, ladies and gentlemen! You don't even want to see the workaround I put together (hint: it involves comparing the values of Screen.bounds.toString() for the contents of Screen.screens)

+1  A: 

This is an educated(?) guess, but since Screen.screens is read only, and modifying the array it returns has no effect, I think it's a fairly safe bet that internally, every time you call it Flash generates and returns a new array of Screen objects (rather than keeping an internal set of Screen objects and giving you access to them). When you call:

Screen.screens.indexOf(Screen.screens[0])

you make two separate accesses to Screen.screens, so if each of those calls is returning a different array of objects, it's easy to see why you don't find any matches - because the indexOf method tests for === equality, so two different Screen objects won't match, even if they happen to contain information about the same physical screen.

The solution is to grab a copy of the screens array and use it. This works fine:

var scr:Array = Screen.screens;
trace( scr.indexOf(scr[0]) ); // returns 0
fenomas
Nice - I bet you're totally right, that's what's going on. Does that follow some sort of standard practice, I wonder? Because while the read-only array part makes sense, I'd expect it to be an array that was updated behind the scenes whenever the screens were changed around, instead of re-building the array every time it was requested... anyway, thanks, that's just what I wanted.
matt lohkamp
I think it's something generally to be wary of when testing objects for equality... whether an API gives you a reference to the same object as last time, or a new object, is ultimately a detail of the API's implementation that it's always safest not to have a dependency on. After all, you don't *really* care whether you have two references to the same object, what you care about is whether they refer to the same physical screen... which is kind of hard to determine in this case, but semantically you see what I mean. ;)
fenomas
But to answer your question, generally I'd guess that something like Screen, which is just a lump of informational properties, is likely to be a throwaway object. Something like NativeApplication.openedWindows, which gives you very complex NativeWindow objects, might be more likely to give references to a persistent object. And after a quick test, it looks like it does. But better not to rely on it if you can avoid it, of course..
fenomas