Posts Tagged ‘Flex’

Inverted Mask in Flex

Monday, March 17th, 2008

Today I took on the challenge of changing a component I built last year to fit into a new style our creative department just finished for a new website. The previous component had a drawn background and some text laid over it which was a different color. The new style called for the same thing with a different background color and the text cut out of the shape. The different background color was easy, I simply added a few styles (one for rollover too) and had it changing color. The harder part was cutting the text out of the background. I knew that this was possible in graphics programs by inverting the mask used or subtracting the shape from another shape and using that as the mask. I couldn’t find any options in Flex for inverting a mask and a google search provided nothing on inverting a mask. I did, however run into a graphics tricks article on InsideRIA. This reminded me of the blend modes that I’d played with in the San Francisco Papervision3D course.

Curious, I went looking and sure enough there was a BlendMode.INVERT. This didn’t, however, do what I wanted of course. This inverted the color values, not the mask. Looking further I found BlendMode.ERASE. This sounded promising but several iterations had it doing nothing, then showing as normal text, then “erasing” everything underneath it. I didn’t want my text to erase everything, just the shape behind it. After some more playing I found the key. cacheAsBitmap. Of course, cacheAsBitmap on one of the pieces didn’t work. Normal masking, for that matter, required cacheAsBitmap on both the mask and the maskee. The trick to make an inverse mask is to set cacheAsBitmap to true for the container of the things that are being masked.

I’m not sure what the performance implications of this are but the effect sure is nice. :-)

Example (click to invert, view source enabled):

The red horizontal lines are on the bottom level. The text and the green vertical lines are within containingCanvas on top of the red lines. The green lines are beneath the text and masked by the text by default. Click to have it mask the green lines in inverse.

Travian Resource Reallocator

Thursday, February 28th, 2008

Last but not least in this deluge of posts is a little utility I created to allow people to reallocate their resources efficiently in Travian. There is a feature in this game, for those who pay a little money, that allows you to change any type of resource (lumber, clay, iron, crop) into any other type. This is very useful for situations where you are producing way more of one resource than another or simply want to speed up your development but if you reallocate for one thing then want to use the remaining resources for another thing you would need to either calculate the amounts manually or reallocate multiple times (thus costing more “gold”). The resulting app allows you to reallocate your resources for any troop type in the game, allows for configuration of the # of them you wish to train, and lets you add any number of subsequent reallocations with the remaining resources.

Travian Tool

3D Sierpinski Gasket

Thursday, February 28th, 2008

Let’s keep the ball rolling with another fractal creation. I’ve been playing with Papervision3D lately due to its use in a recent site I worked on and the San Francisco Papervision3D class I attended a few weekends ago. This latest is a verson of the sierpinski gasket which follows the same ideas as the last one I made but using 4 points to make a tetrahedron in 3 space. The same symmetry is applied but 4-fold and the lines are drawn but soon after removed as they quickly overshadow the pixels and slow the rendering down quite a bit once there are more than a few. Also notice that the pixels have some nice effects applied to them, making a kind fo vortex. Thanks to Andy Zupko for the Effects branch of Papervision3D and his part in the class I attended.

Sierpinski3D

The Dragon (in Flex)

Thursday, February 28th, 2008

Ever snce I got my tattoo(s) I have been explaining the fractal known as the dragon to anyone who takes an interest in it. I’ve even named some of my villages in Travian after the turns you take to create some of them. While explaining the fractal yet again I remembered the way that I originally learned to build it: draw the next iteration over the old one. I originally found this fractal at the beginning of each chapter in Jurassic Park. Since it had a regular box shape I used to use graphing paper to draw it, then after time realized that I could turn the paper over and draw the next iteration over the old one using a simple algorithm. Start by drawing a right angle to one side of the first line, then draw a righ angle to the other side of the next line, and repeat. I have programmed this fractal many times before but I had never actually coded up this algorithm before. I also wanted it to animate so as to show the drawing steps. Without further ado:

Dragon

Sierpinski Gasket (in Flex)

Thursday, February 28th, 2008

While on the plane back from Indianappolis I had two new ideas for generation of a Sierpinski Gasket: 3-way symmetry and line display. For those that don’t know what a sierpinski gasket is, it is a fractal that starts as an equilateral triangle with another one inscribed inside it. The next iteration adds triangles inscribed in the 3 “edge” triangles. This continues over and over (forever).

This implementation uses a different method of generation. You start at a random corner of the triangle, choose a random corner, move halfway to it, and draw a dot. Continue to randomly choose a corner, move halfway to it, and draw a dot, and you get the same thing as above.

Sierpinski Gasket+

String.split() bug should be fixed in Flash Player 9.1

Tuesday, December 4th, 2007

My bug was marked a duplicate of ASC-1739, which is slated to be fixed in Flash Player 9.1. I’m glad that others found this issue too.

No loading of Flex within AIR beta 2

Wednesday, November 14th, 2007

I’ve been trying to load a Flex application which is hosted on a website from within an AIR application which is also built with Flex. Things looked good when an HTML component displayed the website the application was on and allowed me to interact with the page through the DOM (automatically filling out form fields and submitting while listening for a load is a nice hack to avoid rewriting code for webservices :-). Once I got to the page with the flex application on it, however, I got nothing but the “install flash” message we show in the div that is usually replaced by SWFObject. No problem, SWFObject probably wasn’t up to it. Alas, a simple object/embed tag also failed to show the flex aplication. Somewhat disheartened, I also tried SWFLoader but got a security error when the swf tried to access its parent (ugh). A little searching showed some posts on Adobe’s forum and some bugs in their bug system that showed that neither of these things were supported. Flash files aren’t loaded in the HTML component in AIR because they haven’t figured out how to deal with it yet and Flex apps can’t be loaded into Flex apps due to the security sandbox and a Flex bug that triggers it. Oh well, I’ll have to settle for opening up a web page.

AS3 can solve more brain teasers than AS2

Wednesday, November 7th, 2007

In one of my flash applications I take in some text (HTML) and do some processing (convert to plaintext). Since this was written in AS2, which doesn’t have regular expressions or a String.replace() function we came up with a simple alternative. split().join(). This worked exactly as we wanted, replacing the text passed to split() with the text passed to join(). Part of this conversion was to compress 3 or more newlines into only 2 newlines. This would be easy with a regular expression but with only split().join() I had to run this through a while loop in order to compress 3 or more newlines into only 2 newlines. This was the code:

while (str.indexOf("\n\n\n") != -1) {
      str = str.split("\n\n\n").join("\n\n");
}

A very simple loop that, if it works correctly, will compress any number of 3 or more consecutive newlines into only 2 newlines. Needless to say it did work correctly in our AS2 application.

In January of this year I started converting our AS2 application to AS3 and Flex. Since we still had need of this conversion and the code should have worked fine in AS3 I copied it over and all seemed well. However, after testing for a while we started to get hangs of the application at a certain point. One of our developers traced it to an infinite loop….the while loop above. He then debugged into the loop, found that the array returned by split() had an empty string in it, and added some code to remove an empty string, should one be found.

When I saw the commit I was baffled. This looked like added code to solve a problem that didn’t exist. After all, this code had worked fine in AS2 and it was self-evident that the number of newlines would always reduce, as 3 newlines were always replaced by 2……or were they?

After a back and forth with the developer in question I had a small reproduction script which would loop infinitely, despite the fact that it was replacing 3 newlines with 2. I decided to write my own simple test case and check the output in AS2 and AS3. To simplify things I used simple characters instead of newlines:

trace("abbbbc".split("bbb").join("bb"));

Run in AS2 I get “abbbc”, a reduction of 1 ‘b’ from the string, as expected. Run in AS3, however I get back the exact same string: “abbbbc”. Curious, I tried the following:

trace("abbbc".split("bb").join("b"));

This produced the same result in both AS2 and AS3, “abbc”, a reduction of 1 ‘b’, as expected. I then tried the next case up:

trace("abbbbbc".split("bbbb").join("bbb"));

This code returned “abbbbc” in AS2, again as expected, but in AS3 returned “abbbbbbc”, an increase of 1 ‘b’!

Well, I had obviously found a regression in AS3 vs AS2. I then tried regular expressions to see if the same thing happened with them:

trace("abbbbc".split(/bbb/).join("bb"));

This, (in AS3 of course, AS2 doesn’t have regular expressions) produced the desired output of “abbbc”. In my searching I also noticed that String has a replace() method in AS3 which will do global replacements if the regex has a ‘g’ modifier. Now that I had found a solution I switched all of our split().join() mess to use replace() with a global regex. Furthermore I replaced the while loop above with a single replace call with a regular expression, as I had wanted to do when I first wrote it, hence:

str = str.replace(/\n\n\n+/, "\n\n");

I also tried replace to see if ir exhibited the same problem as split().join():

trace("abbbbc".replace("bbb", "bb"));

AS3 reported “abbbc”, the wanted output, so the problem is specifically in split() in AS3 and only when used with a string and not a regular expression. Of course this is somewhat obvious as replace() only replaces the first occurance of a string unless a regex with ‘g’ is used.

Further testing revealed an interesting anomaly if my replacement text used a different character than the text I was searching for:

trace("abbbbc".split("bbb").join("zz"));
trace("abbbc".split("bb").join("z"));
trace("abbbbbc".split("bbbb").join("zzz"));

In AS2 this outputs:

azzbc
azbc
azzzbc

leaving the last ‘b’ untouched, as we would expect; but in AS3:

azzzzc
azzc
azzzzzzc

….where did all of the ‘b’s go?

The more algorithmic among you (wait, is anyone actually reading this?) will have figured it out by now but a look at the output of split() makes this much more obvious. If you run:

trace("abbbbc".split("bbb"));
trace("abbbc".split("bb"));
trace("abbbbbc".split("bbbb"));

you get this in AS2:

a,bc
a,bc
a,bc

and this in AS3:

a,,c
a,,c
a,,c

The arrays are the same for all 3 runs but the interesting part is that in AS3 all traces of ‘b’ disappear and we get an empty string in between the “bookend” ‘a’ and ‘b’. From this output we can deduce that AS3 is finding 2 copies of the search string as the resulting array is 3 elements long; vs. AS2’s 2 element array showing that it is finding 1 match. Logically, and from a brain teaser perspective, there are actually 2 “matches” for “bbb” in the string “abbbbc”. There’s the first 3 ‘b’s and the last 3 ‘b’s. This isn’t how we were expecting split() to function, though, as the semantics of split() are supposed to be such that if you do a split() followed by a join() with the same string you should get the same string back again. In the case of AS3 “abbbc”.split(”bb”).join(”bb”) will actually increase the length of the string by one ‘b’.

Another simple test shows that the same thing happens with a multicharacter repeating pattern:

trace("a-_-_-_-_d".split("-_-_-_").join("-_-_"));

A little cogitation reveals how this could happen given a simple splitting algorithm. Here’s some AS code which exhibits the same problem as AS3’s String.split():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function brokenSplit(str : String, needle : String) : Array {
	var output : Array = new Array();
	var lastFound : Number = 0;
	for (var i : Number = 0; i < str.length; ++i) {
		if (str.substr(i, needle.length) == needle) {
			output.push(str.substr(lastFound, i - lastFound));
			lastFound = i + needle.length;
		}
	}
	if (lastFound < i) {
		output.push(str.substr(lastFound, i));
	}
	return output;
}

and here is the same code with only 3 characters added which outputs the same as AS2’s String.split():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fixedSplit(str : String, needle : String) : Array {
	var output : Array = new Array();
	var lastFound : Number = 0;
	for (var i : Number = 0; i < str.length; ++i) {
		if (str.substr(i, needle.length) == needle) {
			output.push(str.substr(lastFound, i - lastFound));
			lastFound = (i += needle.length);
		}
	}
	if (lastFound < i) {
		output.push(str.substr(lastFound, i));
	}
	return output;
}

The only difference between the two is that fixedSplit() increments the iterator (i) by the length of the needle when a match is found. brokenSplit() naively keeps looking for a match on the very next character even though it is inside a match.

Here is a swf running the various test cases in AS2:

Here is a swf running the various test cases in AS3:

I’ve tested in Flash versions: 9,0,28,0 (debug player for Flex Builder 2), 9,0,47,0 (current release player as of this post), 9,0,60,235 (debug player for Flex Builder 3 beta 2), and 9,0,98,0 (MovieStar). The same output displays in all 3 versions.

I have opened a bug report in Adobe’s bug system: ASC-2936.

UPDATE: fixed the swf links so you should be able to see the tests working again.
UPDATE: My bug was marked a duplicate of ASC-1739, which is slated to be fixed in Flash Player 9.1. I’m glad that others found this issue too.

How do you catch remote FMS method calls with complex prefixes?

Tuesday, October 9th, 2007

Apparently there is no way.

The way to catch server-side Flash Media Server client.call() calls with complex prefixes is not documented. The Flex2 NetConnection docs say that NetConnection.client can be used to catch server-side calls but a call with slashes (as used for the components shipped with FMS) is not documented.

For instance, the cursor.asc server-side component calls:
client.call( this.callPrefix + “attachYourself”, null, clocal.id, cglobal.username, this.layer, cglobal.usercolor);
where this.callPrefix is by default “FCCursor/_DEFAULT_/” so the full call is “FCCursor/_DEFAULT_/attachYourself”.
In AS2 this could be caught by the object in:
netConnection["FCCursor"]["_DEFAULT_"]

The obvious place to catch it in AS3 would be:
netConnection.client["FCCursor"]["_DEFAULT_"] but this does not seem to work.

The LiveDocs also have a comment which asks this same question but the answer is not sufficient.

The only way to work around this seems to make the prefix a parameter in the call instead of prefixing the function name. This takes changing server-side and client-side code and the server code is no longer backwards compatible…..but at least it works.

I have a bug open at Adobe for this one too: FLEXDOCS-94.

Update: The bug has been answered. Slash syntax is, indeed, not supported in AS3.

Grabbing the swf’s URL when the swf is loaded

Tuesday, October 9th, 2007

I finally got fed up with recompiling our Flex application for the different servers I had to deploy to and decided to have it automatically figure out where it is and configure itself. This should have been relatively simple as the swf’s URL is known by the Flash player and was always available in Flash as _root._url (or _root[”_url”]). I knew that Flex had to have this information available so I looked it up.

Sure enough, there is a place in the DisplayObject where you can get this info. DisplayObject.loaderInfo.url. Further looking showed that the Application object should have the loaderInfo. I added some code to test this in a function which was run on the “creationComplete” event and….the loaderInfo object is null.

I then looked further to see if there was another object that maybe had the loaderInfo I needed. The root proprty is supposed to give you the root object of the SWF and this should have the right loaderInfo, right? Nope, still null on “creationComplete”.

I now got suspicious and added some code to look at the URL on the click of a button. Sure enough this code was able to access the loaderInfo and hence get the URL.

So why is the loaderInfo not loaded when the application is created? If I can’t get the URL I can’t do my configuration as there is no other event I know of which I can listen for to set the configuration.

I now dove into the Application code in the Flex framework. I soon found the _url property which is declared as mx_internal. I remembered reading Daniel R’s blog post about mx_internal and quickly set up my code to use mx_internal::_url. Success, this is set on creationComplete.

Now to ask Adobe why we don’t have access to loaderInfo until after the creationComplete event….

UPDATE: After more searching I found the FlexEvent.APPLICATION_COMPLETE event. If you try to access Application.loaderInfo.url when this event is called it is set.