Posts by author:

josefchutka

Licensing All My Software

by josefchutka on June 29, 2010

I have decided to license the majority of my software under MIT License (X11). I hope this license makes all the permissions clear, and gives you enough space to use my code in your projects. I will do my best to add the license text to all the libraries and software stuff as soon as possible. So If you do not find license in particular file or article, please do like it contains this one. It is also possible that some software will be released under different license, in that case the particular software will contain license text in it. Thank you.

Copyright (c) 2009-2010 Jozef Chúťka

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Anaglyphs With Pixel Bender & Depth Map

by josefchutka on June 28, 2010

Pixel Bender and displacement maps were so much fun to develop that my next experiment led me to create some more advanced effects. Do you know anaglyphs? Anaglyph images are used to provide a stereoscopic 3D effect, when viewed with 2 color glasses. There are multiple types of glasses (colors), but the most comon is red-cyan combination. So, I have created this simple pixel bender kernel that makes anaglyph images based on original image and its depth map (just like those used in displacement maps)

Take on your red cyan glasses and lets see the result:

I have been asked to make it also work for other types of glasses, so I made left/right glass matrices dynamic, now you can define any values you like (based on your glass color). The default matrices are:

shader.data.matrixLeft = [0.0, 0.0, 0.0, 0.7, 0.0, 0.0, 0.3, 0.0, 0.0];
shader.data.matrixRight = [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];

… these values are taken from optimized method for red cyan combination. There are some more for this color combination.

There is also the zBase parameter that takes values from 0.0 to 1.0. Defaul value is 0.5. With 0.0, the scene appears to be in front of monitor, with 1.0 depth goes behind the monitor. With 0.5 closer objects appears to be before monitor, distatnt ones behind:

shader.data.zBase = [0.5];

Take care so your head will not explode :-) Download pixel bender kernel (.pbk) file for anaglyphs here.

Where to go from here:

Switching Flex Builder To Flash Builder Issues

by josefchutka on June 24, 2010

Finally I managed to switch from Flex Builder 3 to Flash Builder. Altought, most of the workspaces, projects and casual things were running after switch just fine, there were some issues that made me mad. Some of them I was able to fix, some keep fuss me. I decided to write this post so it may help someone with dealing the same issues…

Additional Source Folders

I used to keep all the .swc libraries together with .as classes in one folder structure. While in old Flex Builder, it was as simple as adding source folder (Project / Properties / … Build Path / Source Path / Add Folder) to make all common libraries work, in Flash Builder, problems occured – after adding additional source folder, the IDE stoped code completion etc. It were not worth those loosed hair when it suddenly appeared that problem is in the structure of the folder, especialy mixed .swc and .as files. From now on, folder is separated into /src (all .as files) and /swc (all .swc files) folders. Credentials go to my friend David Engelmaier, who helped me out of the misery.

HTML Editor

I did not solved this issue yet. I really would like to have some code highlighting editor in Flash Builder.

Creating Files

In order to create a new file (.as class) I used to right-click on folder / new / ActionScript Class. It was simple and fast. Now in Flash Builder, there is no quick option to do that. You have to create “Other …” and select desired option in opened dialog.

Software Updates

After installing, there were no sites defined to check the most common software installation/updates for eclipse (subclipse etc.), I guess one have to add those himself. Here is a list of sites I use:

Europa Discovery Site : http://download.eclipse.org/releases/europa
PBDT                  : http://pbdt.joa-ebert.com/update
Subclipse             : http://subclipse.tigris.org/update_1.6.x

Manage links in Window / Preferences / Install/Update / Available Software Sites

Resource ‘/ProjectXY/…/SomeClass.as’ does not exist

Flash Builder keeps telling me that my file does not exist although it does exist in Project Explorer. When I move this file into another folder, it opens, move back to original place, not exist again … Flash Builder restart required

F5 does not refresh Project Explorer

F5 does not work at all, I can not refresh assets folder, I have to close and reopen the project … Flash Builder restart required

Change!!!

I tried to install Aptana:

  1. Plugging Aptana into an existing Eclipse configuration
  2. Install New Software / Add: http://update.aptana.com/install/studio
  3. Install Aptana – Fail
  4. noticed new available software sites added but disabled, enable all
  5. everything fails to install but Aptana Studio Pro, ok lets try this one
  6. done, need restart flash builder? ok…
  7. starting flash builder: “An error has occured. See the log file C:/…./ANYPROJECT/.metadata/.log”
  8. again and again, all workspaces :-( I am doomed
  9. http://kb2.adobe.com/cps/405/kb405285.html suggested to remove “\.metadata\.plugins\org.eclipse.core.resources”
  10. restarting… no success
  11. removing everything from C:\Program Files\Adobe\Adobe Flash Builder 4\plugins with name Aptana
  12. restarting… success!!! but wait! where are all the projects from my workspace? And why is everything changed? All the icons, all the tabs and views, what happend?

It seems that by removing org.eclipse.core.resources all the old Flex Builder things get removed, new (I guess) Flash Builder appearance got on scene, new Package Explorer with working quick options for .as, .css everything wow!!! My final suggestion for switching from Flex Builder to Flash Builder is: use new workspaces, new projects, do not import the old ones!

Extending FacebookOAuthGraph Class

by josefchutka on June 22, 2010

While The Facebook Graph API article becomes pretty popular and a lot of developers keep asking me to publish some practices I use, I managed to create this blog post. Here is a list o some functions you may want to extend FacebookOAuthGraph Class with.

Extending & Singletonize

First, lets make our class singleton, so the whole flash project can simply access and use one instance

public class Facebook extends FacebookOAuthGraph
{
    private static const _instance:Facebook = new Facebook();
    public function Facebook()
    {
        super();
        useSecuredPath = true;
        if(instance)
            throw new Error("Use Facebook.instance!");
    }

    public static function get instance():Facebook
    {
        return _instance;
    }
    ....
}

Now anywhere in your project:

var facebook:Facebook = Facebook.instance;

Auto Execution After Authorization:

Lets say, when user clicks on publish post before your application is connected, just make connect() followed by desired function:

if(!facebook.authorized)
    facebook.connect();
facebook.publishPost(...)

publishPost() automatically executes again after connected thanks to Callbacks class

import sk.yoz.utils.Callbacks;

private function onAuthorized(event:FacebookOAuthGraphEvent):void
{
	Callbacks.execute("FBstuff");
}

public function publishPost(...):void
{
    if(!authorized)
        return Callbacks.add(this, arguments.callee, arguments, "FBstuff");

    // here continues the function code
    ...
}

Application Friends

Lets get list of friends using the application:

private function getAppFriends():void
{
	var data:URLVariables = new URLVariables();
	data.query = "SELECT uid, name, pic_square " +
			"FROM user " +
			"WHERE uid IN " +
				"(SELECT uid2 FROM friend WHERE uid1=" + me.id + ") " +
				"AND is_app_user";

	var loader:URLLoader = call("method/fql.query", data,
		URLRequestMethod.POST, null, "https://api.facebook.com");
	loader.addEventListener(FacebookOAuthGraphEvent.DATA, onGetAppFriends);
}

private function onGetAppFriends(event:FacebookOAuthGraphEvent):void
{
	var xml:XML = new XML(event.rawData);
	var ns:Namespace = xml.namespace();
	default xml namespace = ns;
	xml.namespace(ns.prefix);
	xml.ignoreWhite = true;
	for each(var user:XML in xml.user)
	{
		user.uid.toString();
        user.name.toString();
		...
    }
    default xml namespace = new Namespace("");
}

Publishing Feeds

Publish feed with image:

public function publishPost(message:String, attachmentName:String,
	attachmentDescription:String):void
{
	var media:Object = {};
	media.src = "http://mydomain.com/feedimage.jpg";
	media.href = "http://apps.facebook.com/myapp";
	media.type = "image";

	var attachment:Object = {};
	attachment.name = attachmentName;
	attachment.href = "http://apps.facebook.com/myapp";
	attachment.description = attachmentDescription;
	//attachment.caption = "test caption";
	attachment.media = [media];

	var data:URLVariables = new URLVariables();
	data.message = message;
	data.attachment = JSON.encode(attachment);

	call("method/stream.publish", data, URLRequestMethod.POST,
		null, "https://api.facebook.com");
}

Publish feed with flash:

public function publishFlash(message:String, href:String, swfSrc:String,
	mediaSrc:String, attachmentName:String, attachmentCaption:String,
	attachmentDescription:String, properties:Object=null):void
{
	var media:Object = {};
	media.type = "flash";
	media.swfsrc = swfSrc;
	media.imgsrc = mediaSrc;
	//media.width = "80";
	//media.height = "80";
	media.expanded_width = "460";
	media.expanded_height = "460";

	var attachment:Object = {};
	attachment.name = attachmentName;
	attachment.href = href;
	attachment.caption = attachmentCaption;
	attachment.description = attachmentDescription;
	attachment.media = [media];
	attachment.properties = properties; // action links
	// properties {prop1:{text: "value 1", href:"http://"}, prop2:...};

	var data:URLVariables = new URLVariables();
	data.message = message;
	data.attachment = JSON.encode(attachment);

	call("method/stream.publish", data, URLRequestMethod.POST, null,
		"https://api.facebook.com");
}

Publish feed with action links:

var properties:Object = {};
properties.MOVE = {
	text: "mouse drag",
	href:config.urlManager.boardURL};
properties.ZOOM = {
	text: "double click, [Page Up], [Page Down]",
	href:config.urlManager.boardURL};
properties.ROTATE = {
	text: "[Ctrl] + mouse move",
	href:config.urlManager.boardURL};

attachment.properties = properties;

Uploading Photo

This is a piece of working code from Sean, more upload handling functions and album creating can be found here. thnx Sean:

// MultipartURLLoader by Eugene Zatepyakin can be found here: http://bit.ly/9wx4q7
public function uploadImageCall(path:String, ba:ByteArray, message:String, token:String=null):MultipartURLLoader
{
    var mpLoader:MultipartURLLoader = new MultipartURLLoader();
    mpLoader.addVariable("message", message);
    mpLoader.addFile(ba, "image.jpg", "image");
    loaderAddListeners(mpLoader.loader);
    mpLoader.load(apiSecuredPath + "/me/photos?access_token="+ token);
    return mpLoader;
}

Palming Token

When localy debuging your app you may want to palm off custom access_token:

if(parameters.debug)
    facebook.hackToken(parameters, "110363ABXY..."); // copypaste from callback.html hash
facebook.autoConnect(parameters);

in Facebook.as:

public function hackToken(parameters:Object, token:String):Object
{
	if(!parameters.session)
		parameters.session = JSON.encode({
			access_token:String(token).replace(/\%7C/g, "|")});
	return parameters;
}

Advanced Crossdomain Working Authorization

Or if you prefer or need advanced callback, that works crossdomain, and also for local debuging: callback.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="sk" lang="sk" dir="ltr">
<head>
	<script type="text/javascript" src="js/swfobject.js"></script>
	<script type="text/javascript">
	<!--
		if(window.opener && window.opener.confirmFacebookConnection){
			window.opener.confirmFacebookConnection(window.location.hash);
			self.close();
		}else{
			var flashvars = {};
			flashvars.connectionName = "_facebookConnector";
			flashvars.methodName = "confirmConnection";
			flashvars.hash = window.location.hash;

			swfobject.embedSWF("flash/Callback.swf", "flash", "1", "1", "10.0.0",
				"expressInstall.swf", flashvars, {}, {});
		}
	//-->
	</script>
</head>
<body>
	<p>You may now close this window.</p>
	<div id="flash"></div>
</body>
</html>

universal callback.swf (741 Bytes) main class:

package
{
    import flash.display.Sprite;
    import flash.net.LocalConnection;

    public class Callback extends Sprite
    {
        public function Callback()
        {
            super();
            var parameters:Object = loaderInfo.parameters
            var localConnection:LocalConnection = new LocalConnection();
            localConnection.send(
                parameters.connectionName,
                parameters.methodName,
                parameters.hash);
        }
    }
}

facebook.as class:

private var localConnection:LocalConnection;

override public function connect():void
{
	super.connect();

	if(!localConnection)
	{
		localConnection = new LocalConnection();
		localConnection.client = this;
		localConnection.allowDomain("*");
		localConnection.allowInsecureDomain("*");
		localConnection.connect("_facebookConnector");
	}
}

private function onAuthorized(event:FacebookOAuthGraphEvent):void
{
	// listener defined in Facebook constructor:
	// addEventListener(FacebookOAuthGraphEvent.AUTHORIZED, onAuthorized);

	try
	{
		localConnection.close();
		localConnection = null;
	}
	catch(error:Error){}
}

Getting All The Photos Of All Albums Of 1 User

Credits to Etienne, thnx

function getAllphotos(uid:String):void {
	var data:URLVariables = new URLVariables();
	data.query = "SELECT src_small, src_big " +
		"FROM photo " +
		"WHERE aid IN ( SELECT aid FROM album WHERE owner='"+HERE PUT THE USER ID+"' )"
	var loader:URLLoader = facebook.call("method/fql.query", data,URLRequestMethod.POST,
		null, "https://api.facebook.com");
	loader.addEventListener(FacebookOAuthGraphEvent.DATA, onGetAllphotos);
}

Numeric Sequence In SQL

by josefchutka on June 18, 2010

Few years ago I came accross an issue, when I needed to find smallest continuous integer in a sequence. My data were like 1, 2, 3, 100, 101, 102, 520, 521, 530 and the task to find lets say next continuous bigger than 100. Long story short, fastest and the final SQL was:

SELECT t1.num+1 FROM table AS t1
WHERE NOT EXISTS
   (SELECT t2.num FROM table AS t2  WHERE t1.num+1 = t2.num)
   AND t1.num>=100
GROUP BY t1.num ORDER BY t1.num LIMIT 1

Today, the issue was a little more difficult. I have to find smallest continuous 2D sequence in any direction.

The data are:

x       y
-1000   -1000
 -200    -100
 -100    -100
 -100       0
   0      100
 100      100
...

This data creates some kind of grid. By direction it is meant that you want to find the closest unset grid position starting from [0, 0] going to any direction defined by random vector [53, -45]. Grid size is 100. This issue required also dynamic table name what brings prepared statements into the scene. There may exist even a simplier solution, but this procedure executes in a 0.000something sec. when crawling more than a few thousands of entries.

CREATE PROCEDURE `getEmpty`(IN `tbl` VARCHAR(50), IN `ix` FLOAT, IN `iy` FLOAT, OUT `ox` INT, OUT `oy` INT)
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT ''
label:BEGIN
	DECLARE px INT DEFAULT 0;
	DECLARE py INT DEFAULT 0;

	WHILE TRUE DO
		SET @res = NULL;
		SET @dsql = CONCAT('SELECT x INTO @res FROM ', tbl,
				' WHERE x = FLOOR(', px,' / 100) * 100 AND y = FLOOR(', py, ' / 100) * 100');
		PREPARE stm from @dsql;
		EXECUTE stm;
		DEALLOCATE PREPARE stm;

		IF
			@res IS NULL
		THEN
			SELECT FLOOR(px / 100) * 100, FLOOR(py / 100) * 100 INTO ox, oy;
			LEAVE label;
		END IF;

		SET px = px + ix;
		SET py = py + iy;
	END WHILE;
END

Now all you have to do is call created procedure:

CALL getEmpty("myTable", RAND() * 200 - 100, RAND() * 200 - 100, @x, @y);
SELECT @x, @y;

While testing it on my favourite HeidiSQL tool, everything worked like a charm. The real usage issue appeared when I tried it in PHP I received an error message saying:

1312: can't return a result set in the given context

The error is caused by prepared statements. PHP MySQL extension doesn’t support features like prepared statements and stored procedures. For using these features you have to use mysqli extension. So I switched to mysqli and everything worked.

Quick tip: Fastest ActionScript PNGEncoder

by josefchutka on June 17, 2010

Here are some benchmark tests for current available PNGEncoders. Sync encoding tested on 2 real bitmap images (500×300px, 256×256px) on Intel Core 2 Duo @ 2.80GHz, win XP:

encoder / image                         500x333 px  256x256 px
by.blooddy.crypto.image.PNG24Encoder     78ms       125ms
dsk.PNGEncoder							140ms		141ms
net.kaourantin.PNGEnc					188ms		187ms
mx.graphics.codec.PNGEncoder			203ms		172ms
com.adobe.images.PNGEncoder				219ms		172ms
org.aswing.image.png.AsPngEncoder		234ms		172ms
ru.inspirit.encoders.png.PNGEncoder		391ms		203ms

by.blooddy.crypto.image.PNG24Encoder worked fastest for me.

download sources:

Quick tip: Ports Required For RTMFP

by josefchutka on June 17, 2010

In order to be able to use P2P communication within flash apps, you need to have opened UDP ports in range 1024..65535. First, to connect stratus server, you need UDP ports 1935 and 10000..10100, then the communication between peers (Flash Players and AIR) goes through random UDP port in range 1024..65535. In detail:

UDP port 1935 and ports 10000+ are used by the Stratus servers. the UDP ports used on client computers could be any port from 1024..65535.

in order to just connect to the Stratus servers, you must be able to send and receive UDP packets with any UDP port on your client computer (source port for outgoing, destination port for incoming) and port 1935 and ports 10000+ on the Stratus server computers (destination port for outgoing, source port for incoming).

*just* connecting to Stratus isn’t useful, though, since all it can do is help you to connect directly to other clients running Flash Player or AIR. other client computers, just like your client computer, will be using a random UDP port in the range 1024..65535. therefore, in order to communicate P2P with other client computers using RTMFP, you must do one of the two following things:

1) allow all UDP with a source or destination port from 1024..65535.

2) have a “stateful firewall” that allows bidirectional UDP connections to and from any UDP ports in the range 1024 through 65535 inclusive as long as a first packet is sent outbound through the firewall. this is commonly called “allowing outbound UDP”. sending the first packet outbound through your firewall to allow return packets is commonly called “UDP hole punching”. searching on these terms should give you more information.

in general, a firewall that blocks UDP will block RTMFP communication.

Read more about PORT NUMBER of RTMFP.

Callbacks Class To Store Your Wishes In Time

by josefchutka on June 11, 2010

Things are much easier when they works synchronously, you just ask for what you want and thats it, but with flash you always have to count on with asynchrony. For example you are waiting on some requests to complete or 3rd party to log you on etc. The issue is, you know you want to execute something, with custom properties, but you have to do that just after some asynchronous event dispatched. E.g. you want to update status with some message, but you need to connect to facebook first. Here comes the handy Callbacks class. What it does is, it stores your wishes and executes when things are prepared.

public function Test():void
{
    updateStatus("new message");
    facebook.addEventListener(FacebookOAuthGraphEvent.AUTHORIZED, onAuthorized);
    // now click on connect button to get connected
}

private function onAuthorized(event:FacebookOAuthGraphEvent):void
{
    // now you are connected, execute waiting functions
    Callbacks.execute("facebookFlag");
}

private function updateStatus(message:String):void
{
    if(!facebook.authorized)
    {
        // if you are not connected, store callback with the exact same arguments
        Callbacks.add(this, arguments.callee, arguments, "facebookFlag");
        // Callbacks.add(this, arguments.callee, arguments) ...
        // ... is universal call, and it does the same as:
        // Callbacks.add(this, updateStatus, [message])
    }
    else
    {
        // if you are connected, execute whatever you have to
        trace("... changing status");
    }
}

flag parameter is optional. When calling:

Callbacks.execute()

… all stored is executed, even those with flags. When calling

Callbacks.execute("customFlag")

… only the callbacks with customFlag are executed

Just for the record and myself (I should read all the documentation, also the long sentences :-) … Make sure you always check hitTestPoint() against global coordinates of some point.

// we are somewhere deep in myObject.myObject2.myInnerObject
var point:Point;
var someMovingObject:DisplayObject;
var hitShape:DisplayObject;

point = localToGlobal(new Point(someMovingObject.x, someMovingObject.y));
point = someMovingObject.localToGlobal(new Point());
// both give us same results,
// 2nd method is faster in loops while it can use predefined zero point

hitShape.hitTestPoint(point.x, point.y, true);

Even hitShape object is not directly on a stage (but on myInnerObject), you have to use global points for testing hits.

In a lot of projects we need to embed czech and slovak characters. Here is a list of those I mostly embed:

ÁáÄäČčĎďÉéĚěÍíĺĹľĽŇňÔôÓóŘřŠšŤťÚúŮůÝýŽž !”#$%&’()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}<=>'