<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Thiên Hạ Flash</title>
	<atom:link href="http://thienhaflash.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thienhaflash.wordpress.com</link>
	<description>cuộc đời sự nghiệp ước mơ và tất cả</description>
	<lastBuildDate>Tue, 24 Jan 2012 01:05:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='thienhaflash.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Thiên Hạ Flash</title>
		<link>http://thienhaflash.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://thienhaflash.wordpress.com/osd.xml" title="Thiên Hạ Flash" />
	<atom:link rel='hub' href='http://thienhaflash.wordpress.com/?pushpress=hub'/>
		<item>
		<title>[haxe] HDictionary</title>
		<link>http://thienhaflash.wordpress.com/2012/01/24/hdictionary/</link>
		<comments>http://thienhaflash.wordpress.com/2012/01/24/hdictionary/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 00:45:44 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Haxe]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=477</guid>
		<description><![CDATA[When trying to implement a new event system that support custom parameters in Haxe, I come across the need of AS3 Dictionary. After doing a quick search I found that there are no Haxe equivalent (yes, there is TypedDictionary but &#8230; <a href="http://thienhaflash.wordpress.com/2012/01/24/hdictionary/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=477&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When trying to implement a new event system that support custom parameters in Haxe, I come across the need of AS3 Dictionary. After doing a quick search I found that there are no Haxe equivalent (yes, there is TypedDictionary but it&#8217;s only available if you are targeting Flash). To me, there is no point to write in Haxe if we can only target one platform, so I bring it up to create a HDictionary that works similar to AS3 Dictionary in pure Haxe hopefully this will be helpful to someone out there.</p>
<p>The basic idea is simple, as we do not has any kind of object signature (a unique string equivalent, usually its memory address) to use as the key, we need to store both key and value and then make a loop through all the items, doing comparison until we come across the correct one. You might think that this will cause much overhead (searching a lot) but remember that whatever type of script we used, this overhead can not be avoided.<br />
<span id="more-477"></span><br />
For better performance (prevent searching whenever possible), I added a property checkExistance when adding a key (default to true) so you can turn off the default behavior by setting it to false if you sure that the key has not yet been used (of course, this can break the code if you don&#8217;t use it correctly so be careful when using this).</p>
<p>Here is the usage syntax (it&#8217;s quite similar to AS3) :<br />
<pre class="brush: as3;">
var d = new HDictionary();

//to set a key :
d.setKey(key, value, checkExistance);

//to get value from a key :
d.getValue(key); //should return value

//to check for key existance
d.hasKey(key); //return true / false

//to delete a key
d.deleteKey(key);
</pre><br />
Here is the class itself (quite simple, though) :<br />
<pre class="brush: as3;">
package vn.core;

class HDictionary {
	private var _map 	: List&lt;Pair&gt;;
	
	public function new() {
		_map  = new List&lt;Pair&gt;();
	}
	
	private function getPair(key: Dynamic): Pair {
		for (p in _map) {
			if (p.key == key) return p;
		}
		return null;
	}
	
	/*******************************
	 * 		PUBLIC APIS
	 ******************************/
	
	public function hasKey(key: Dynamic): Bool {
		var p = getPair(key);
		return p != null;
	}
	
	public function deleteKey(key: Dynamic): Void {
		var p = getPair(key);
		if (p != null) _map.remove(p);
	}
	
	public function getValue(key: Dynamic): Dynamic {
		var p = getPair(key);
		return p == null ? null : p.value;
	}
	
	public function setKey(key: Dynamic, value: Dynamic, checkExistance: Bool = true): Void {
		if (!checkExistance) {//prevent looking up overhead
			_map.push( { key: key, value: value} );
		} else {
			var o = getPair(key);
			if (o != null) {//modify value if key already exist
				o.value = value;
			} else {//create new Pair if key not yet exist
				_map.push( { key: key, value: value} );
			}
		}
	}
}

typedef Pair = { key: Dynamic, value: Dynamic }
</pre><br />
so, that&#8217;s it, try out and let me know if it&#8217;s working for you. Happy haxing everyone !</p>
<p><a href="http://dl.dropbox.com/u/10796188/wp/source/HDictionary.hx" title="HDictionary.hx">Download HDictionary.hx</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/477/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/477/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/477/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=477&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2012/01/24/hdictionary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>[AS3] Input</title>
		<link>http://thienhaflash.wordpress.com/2011/10/20/as3-input/</link>
		<comments>http://thienhaflash.wordpress.com/2011/10/20/as3-input/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 23:51:57 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=464</guid>
		<description><![CDATA[In the efforts to unify the AS3 libraries i realized that writting too many files (each file is specific for one functionality) though very clear and easy, maintainable is a big issue. I usually need to bring the whole library, &#8230; <a href="http://thienhaflash.wordpress.com/2011/10/20/as3-input/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=464&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the efforts to unify the AS3 libraries i realized that writting too many files (each file is specific for one functionality) though very clear and easy, maintainable is a big issue. I usually need to bring the whole library, which caused conflicts to another project when there might be other versions of utils classes (btw, i used to put package&#8217;s function for each utility) happen to be there. This caused too much headaches as the old ones will might not work the way we expected with the new ones, overwrite is not an option, especially when the classes was patched for bugs in different projects. Of course, life should be easier if you track down everything you modified to a class got used in the real project or got simple unit test for each file, but still, the portability is not that great.</p>
<p>One class for one thing should be the way to go, though it&#8217;s heavier in term of code base, the maintainable process should be easy enough, just move it somewhere, rename the package once if needed. No missing or conflicted dependencies to worry about &#8230;</p>
<p>One cool thing in this version is that you don&#8217;t need to cancel out theme configuration : if a state used bold = true, we don&#8217;t need to cancel out for other state, aka, doesn&#8217;t need to put bold=false for each other states. Another one is that we can do input configuration from timeline.<br />
<span id="more-464"></span><br />
There is simple usage syntax :</p>
<ul>
<li>From code :<br />
<pre class="brush: as3;">
var input : Input = new Input().setConfig( { hint:'hello, input something here !' } );
addChild(input.skin);
</pre></li>
<li>From timeline textfield / timeline MovieClip</li>
<p><pre class="brush: as3;">
new Input()	.setConfig( { hint:'hello, input something here !' } )
		.setSkin(mc);
</pre></p>
<li>From timeline textfield / timeline MovieClip</li>
<p><pre class="brush: as3;">
//we need firstly create a new theme
Input.addTheme(	'dark',	{color: 0xFFFFFF} //input
		,	{color: 0x555555, italic: true} //hint
		,	{border: true, borderColor: 0xff0000, color: 0xFF0000} //invalid
		,	{color : 0xAAAAAA}
		);

//then use it
input.themeId = 'dark';
</pre>
</ul>
<p>And as usual, code for the ones who don&#8217;t want to download just to read : In this class, the main class is Input, other internal classes are utilities</p>
<p><pre class="brush: as3;">
package {
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.ui.Keyboard;
	import flash.utils.setTimeout;

	public class Input {

		public static function addTheme(id: String, inputFormat: Object, hintFormat: Object
				, inValidFormat: Object, validFormat: Object, useAsDefault: Boolean = false): void {
			InputTheme.newTheme(id, inputFormat, hintFormat, inValidFormat, validFormat, useAsDefault);
		}

		public function Input() {
			_config		= new InputConfig();
			_content	= '';
		}

	/***************************
	 * 	SHORT CUT / CALLBACK
	 *
	 ***************************/

		private var _onChange_Func 		: Function;
		private var _onChange_Params 	: Array;

		private var _onComplete_Func	: Function;
		private var _onComplete_Params	: Array;

		public function onInputChange(func: Function, params : Array = null): Input {
			_onChange_Func		= func;
			_onChange_Params	= params;
			return this;
		}

		public function onInputComplete(func: Function, params : Array = null): Input {
			_onComplete_Func	= func;
			_onComplete_Params	= params;
			return this;
		}

	/********************
	 * 		TARGET
	 ********************/

		private var _skin			: DisplayObject;
		private var _textfield		: TextField;

		public function get skin():DisplayObject {
			if (!_skin) setSkin(InputUtils.getDefaultTextField());
			return _skin;
		}

		public function set skin(pdo:DisplayObject):void { setSkin(pdo); }

		public function setSkin(pdo:DisplayObject):Input {
			if (_textfield) removeTextField(_textfield);
			if (!pdo) return this;

			_textfield	= pdo as TextField;
			if (!_theme) _theme = InputTheme.getTheme(null); //get default theme

			if (_textfield) { //use default settings
				addTextField(_textfield);
			} else if (pdo is MovieClip) {
				var mc : MovieClip = pdo as MovieClip;
				_textfield = (mc.txt || mc.getChildAt(0)) as TextField;
				addTextField(_textfield);
				setConfig(mc.inputConfig);
			} else {
				trace(this, 'Error trying to setSkin to an invalid target, named ', pdo.name);
				return this;
			}
			_skin = pdo;
			return this;
		}

		private function addTextField(tf: TextField): void {
			tf.blendMode	= BlendMode.LAYER;
			oProps			= _theme.saveOriginalProps(_textfield);

			tf.text			= (_content == '') ? _config.hint : _content;
			refreshTheme();

			tf.addEventListener(FocusEvent.FOCUS_IN,		_onGainFocus);
			tf.addEventListener(FocusEvent.FOCUS_OUT,		_onLooseFocus);
			tf.addEventListener(KeyboardEvent.KEY_DOWN,		_onKeyDown);
			tf.addEventListener(Event.CHANGE,				_onTextChanged);
		}

		private function removeTextField(tf: TextField): void {
			_theme.revert2OriginalProps(tf, oProps);//return properties

			tf.removeEventListener(FocusEvent.FOCUS_IN,		_onGainFocus);
			tf.removeEventListener(FocusEvent.FOCUS_OUT,	_onLooseFocus);
			tf.removeEventListener(KeyboardEvent.KEY_DOWN,	_onKeyDown);
			tf.removeEventListener(Event.CHANGE,			_onTextChanged);
		}

		private function _onKeyDown(e: KeyboardEvent): void {
			if (e.keyCode == Keyboard.ENTER &amp;&amp; !_textfield.multiline) {//apply new content
				killFocus();

			} else if (e.keyCode == Keyboard.ESCAPE) {//revert to old content
				_textfield.text	= _content;
				killFocus();
			}
		}

		private function _onTextChanged(e: Event): void {
			//TODO : adding support for delay
			if (_onChange_Func != null) _onChange_Func.apply(null, _onChange_Params);
		}

	/********************
	 * 		FOCUS
	 ********************/

		private var _isFocus 	: Boolean;

		public function get isFocus():Boolean { return _isFocus; }
		public function set isFocus(value:Boolean):void { value ? gainFocus() : killFocus(); }

		private function gainFocus(): void { _textfield.stage.focus = _textfield; }
		private function killFocus(): void { if (_textfield.stage.focus == _textfield) _textfield.stage.focus = null; }

		private function _onGainFocus(e: Event): void {
			_isFocus = true;
			if (_content == '') _textfield.text = ''; //clear hint
			refreshTheme();
		}

		private function _onLooseFocus(e: Event): void {
			_isFocus = false;
			if (_content != _textfield.text) {
				_content = _textfield.text;
				if (_onComplete_Func != null) _onComplete_Func.apply(null, _onComplete_Params);
			}

			if (_content == '') _textfield.text = _config.hint;
			refreshTheme();
		}

	/********************
	 * 		THEME
	 ********************/

		private var _theme		: InputTheme;
		private var oProps		: Object;

		public function get themeId():String { return _theme.id; }

		public function set themeId(value:String):void {
			if (_theme) _theme.revert2OriginalProps(_textfield, oProps);
			_theme	= InputTheme.getTheme(value);
			oProps	= _theme.saveOriginalProps(_textfield);
			refreshTheme();
		}

		protected function refreshTheme():void {
			if (_config.regExp) _config.regExp.lastIndex = 0;
			_vContent = (!_config.regExp || _config.regExp.test(_content)) ? _content : null;
			_theme.apply(_textfield, oProps,	_isFocus		? InputState.INPUT	:
												_content == ''	? InputState.HINT	:
												_vContent		? InputState.VALID	: InputState.INVALID);
		}

	/********************
	 * 		CONFIG
	 ********************/

		private var _config : InputConfig;

		public function setConfig(cfg: Object): Input {
			_config.reset(cfg);
			return this;
		}

	/********************
	 * 		API
	 ********************/

		private var _content	: String;
		private var _vContent	: String;

		public function get content():String { return _isFocus ? _textfield.text : _content; }

		public function set content(value:String):void {
			_content = value || '';
			_textfield.text = _content;
			refreshTheme();
		}

		public function get validatedContent(): String {
			if (_isFocus) killFocus();
			return _vContent;
		}
	}
}
[sourcecode language=&quot;Actionscript3&quot;]
//4 different states to apply different formats
class InputState {
	public static const HINT	: int = 0;
	public static const INPUT	: int = 1;
	public static const VALID	: int = 2;
	public static const INVALID	: int = 3;
}
</pre></p>
<p>//Configuration for Input field &#8211; restrict input someway</p>
<p><pre class="brush: as3;">
class InputConfig {
	public var isRequired	: Boolean;
	public var trimSpaces	: Boolean;
	public var liveDelay	: Number; // call onInput for every text changes happens in every _liveDelay seconds
	public var hint			: String;
	public var regExp		: RegExp; //array of expressions

	public function reset(cfg: Object): void {
		hint			= cfg.hint || '';
		isRequired		= cfg.isRequired == true;
		trimSpaces		= cfg.trimSpace	!= false;
		regExp			= cfg.regExp;
		liveDelay		= parseFloat(cfg.liveDelay || '0.5');
	}
}
</pre></p>
<p>//Save the 4 state format information</p>
<p><pre class="brush: as3;">
class InputTheme {
	private static var dict			: Dictionary;
	private static var defaultTheme	: InputTheme;

	public static function newTheme(id: String, hint: Object, input:Object, valid:Object, invalid:Object, useAsDefault: Boolean = false): InputTheme {
		if (!dict) dict = new Dictionary();
		if (dict[id]) trace('[InputTheme :: overwritting the existed theme with id=' + id + ']');

		var theme : InputTheme = new InputTheme(id, hint, input, valid, invalid);
		dict[id] = theme;
		if (useAsDefault) defaultTheme = theme;

		return theme;
	}

	public static function getTheme(id: String = null): InputTheme {
		var theme : InputTheme = dict &amp;&amp; id ? dict[id] : null;
		if (!theme) {
			if (!defaultTheme) {
				defaultTheme = new InputTheme('default',
						{ textColor: 0x888888 , italic : true, border: true, borderColor:  0x888888},
						{ textColor: 0x555555, border: true, borderColor: 0x0000ff },
						{ textColor: 0x000000, border: true, borderColor: 0x000000 },
						{ textColor: 0x880000, border: true, borderColor: 0x880000 }
					);

			}
			return defaultTheme;
		}
		return theme;
	}

	private var format		: Array;
	public var id			: String;

	public function InputTheme(id: String, hint: Object, input:Object, valid:Object, invalid:Object) {
		this.id = id;
		format = [hint || {}, input || {}, valid || {}, invalid || {}];
	}

	public function apply(tf: TextField, oProps : Object, type:int): void {
		var obj :Object = InputUtils.copyProps(oProps);
		obj = InputUtils.copyProps(format[type], obj)
		InputUtils.formatText(tf, obj);
	}

	public function saveOriginalProps(tf: TextField): Object {
		var propList : Object = { };

		//values are not important !
		InputUtils.copyProps(format[0], propList);
		InputUtils.copyProps(format[1], propList);
		InputUtils.copyProps(format[2], propList);
		InputUtils.copyProps(format[3], propList);

		return InputUtils.getDefaultProps(tf, propList);
	}

	public function revert2OriginalProps(tf: TextField, oProps: Object): void {
		InputUtils.formatText(tf, oProps);
	}
}
</pre></p>
<p>//Various utilities use internally &#8211; duplicated to be stand alone</p>
<p><pre class="brush: as3;">
class InputUtils {

	private static var txtFormat : Object = { bold: 1, italic: 1, underline : 1, color : 1, font : 1, size : 1, align : 1, blockIndent : 1, indent : 1, kerning : 1, leading	: 1, leftMargin : 1, rightMargin : 1, tabStops : 1, letterSpacing : 1, bullet : 1, url : 1, target : 1 };

	public static function formatText(txt: TextField, props: Object): TextField {
		var formatObj : Object = { };

		for (var prop : String in props) {
			trace('formatting :: ', prop, props[prop]);
			if (prop in txtFormat) {
				formatObj[prop] = props[prop];
			} else {//set direct
				txt[prop] = props[prop];
			}
		}

		var tf : TextFormat = txt.getTextFormat();
		for (prop in formatObj) {
			tf[prop] = formatObj[prop];
		}
		txt.setTextFormat(tf);
		txt.defaultTextFormat = tf;

		return txt;
	}

	public static function copyProps(src: Object, tar: Object = null): Object {
		if (!tar) tar = { };
		for (var s : String in src) { tar[s] = src[s]; }
		return tar;
	}

	public static function getDefaultProps(tf: TextField, src: Object): * {
		var tfm		: TextFormat = tf.defaultTextFormat;
		var props	: Object = {};

		//trace('here is default props :: ');

		for (var s: String in src) {
			props[s] = (s in txtFormat) ? tfm[s] : tf[s];
			//trace('s :: ', s, props[s]);
		}

		return props;
	}

	public static function getDefaultTextField(): TextField {
		return formatText(new TextField(), { type: TextFieldType.INPUT, multiline: false, width: 150, height: 25, size: 16 } );
	}
}
</pre></p>
<p>I found this class still missing some of the basic features like supportting for password (in configuration). There should be an update once i got to use it in a real project, stay tune !</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/464/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=464&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/10/20/as3-input/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>Batch publish .fla files</title>
		<link>http://thienhaflash.wordpress.com/2011/10/19/batch-publish-fla-files/</link>
		<comments>http://thienhaflash.wordpress.com/2011/10/19/batch-publish-fla-files/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 00:36:33 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[jsfl]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=455</guid>
		<description><![CDATA[JSFL is the way to automate tasks in Flash CS IDE, you can write extensions to do the repeating works like export fonts, open files, create symbols, read graphics datas, build multiple .fla files &#8230; The one thing i got &#8230; <a href="http://thienhaflash.wordpress.com/2011/10/19/batch-publish-fla-files/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=455&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>JSFL is the way to automate tasks in Flash CS IDE, you can write extensions to do the repeating works like export fonts, open files, create symbols, read graphics datas, build multiple .fla files &#8230; The one thing i got astonished about is that there are no built-in way (no jsfl api) to know if there are errors during compilation of an .fla file. Hit ctrl+enter, you see that even if there are errors in code, the Flash IDE still trying to launch the .swf file. Hit build from an .flp project, the compiling process won&#8217;t stop when errors occurs for files, it just clear the log everytime a new file need to build, so we end up with a bunch of errors in files which we never where they are to apply the fixes.</p>
<p>I don&#8217;t know how hard it is for the Flash CS team to add an api allowing us to catch and stop when there are errors building .fla file, but this surely make enough troublesome for me : Once there are errors, i need to wait for the batch building complete then compile one by one manually&#8230; so finally decision, there must be a way to do it in jsfl.<br />
<span id="more-455"></span><br />
The basic idea is although we can&#8217;t know directly if there are errors in the building process, we can save the compile errors into a temporary file, then read it back, parse the string and find if there are errors before trying to build the next one. Here is the simplest form :</p>
<p><pre class="brush: jscript;">
function exportAll(){ 
	var docs=fl.documents;
	var docs_length=docs.length;
	for (var i=0; i&lt;docs_length; i++) {  
		var doc=docs[i];
		doc.publish();
		
		var docErrorURI= &quot;file:///c|/&quot;+doc.name + &quot;.errors&quot;;
		fl.compilerErrors.save(docErrorURI);
		var contents	= FLfile.read(docErrorURI);
		var arr	= contents.split(&quot;\n&quot;);
		var errorCount	= arr[arr.length-1].split(&quot; &quot;)[0];
		FLfile.remove(docErrorURI);
		
		if (errorCount == 0){
			doc.close(false);
		} else {
			break;
		}
	}
}
exportAll();
</pre></p>
<p>There are many other features you may want to add like open all .fla files inside a folder (with exceptions ?), delete .aso files, save file open state, monitor building log and allow continue build after errors for specific module is fixed or a specific .swf file to run after the build completes &#8230;</p>
<p>I might update the file with new features in future releases, but as it&#8217;s for now doing the job, i will stick with it at least for sometime. (there won&#8217;t be any planned updates in near future)</p>
<p>UPDATE 05.NOV.2011 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>For files that are not yet open, we have a way to build them directly, this resulted in faster compiled time. Using the method above to break the building stack if there are errors, we can now build a list of fla files within a single click. Remember that this is only available for flash CS4 10.0.2 and later. For earlier version of the IDE, you will still need to open the file before publish it.</p>
<p>And here is the code, you can change the basePath and the fileList once for each project and then you are good to go.</p>
<p><pre class="brush: jscript;">
basePath	= &quot;file:///D:/&quot;
fileList	=	[	'file1.fla',
				'file2.fla'
			];

//CS5 :
for (i=0; i&lt;fileList.length; i++){
	fl.publishDocument(basePath + fileList[i]);
	var docErrorURI= basePath + fileList[i].split(&quot;.fla&quot;)[0] + &quot;.errors&quot;;
	fl.compilerErrors.save(docErrorURI);
	var contents	= FLfile.read(docErrorURI);
	var arr	= contents.split(&quot;\n&quot;);
	var errorCount	= arr[arr.length-1].split(&quot; &quot;)[0];
	FLfile.remove(docErrorURI);
	if (errorCount &gt; 0) break;
}
</pre></p>
<p>Once again, this is not the ultimate solution, there are other features to add like checking for the IDE version by parsing fl.version so it will compatible with all IDEs. But at least it&#8217;s doing right for my need, i will keep this simple version.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/455/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=455&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/10/19/batch-publish-fla-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>MultiKey Dictionary</title>
		<link>http://thienhaflash.wordpress.com/2011/07/26/multikey-dictionary/</link>
		<comments>http://thienhaflash.wordpress.com/2011/07/26/multikey-dictionary/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 17:09:12 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=435</guid>
		<description><![CDATA[While developing some kind of event monitoring Manager class i come across a problem of too many Object used : Each IEventDispatcher source can dispatch multiple eventNames, each eventName can have several function attached to it. The popular approach is &#8230; <a href="http://thienhaflash.wordpress.com/2011/07/26/multikey-dictionary/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=435&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>While developing some kind of event monitoring Manager class i come across a problem of too many Object used : Each IEventDispatcher source can dispatch multiple eventNames, each eventName can have several function attached to it. The popular approach is using nested Dictionary/Object as the main data structure :<br />
<pre class="brush: as3;">
_sourceDict : Dictionary; /* map IEventDispatchers to _eventObjects */
_eventObject : Object; /* map eventName to _handlerDict */
_handlerDict : Dictionary; /* map handler to its params */
</pre></p>
<p>For faster check and overwrite the existed _handler for a specific source and eventName we need to use a Dictionary for _handlerDict instead of an Array, and by the way, add support for user parameters.</p>
<p>This data structure of course will still work without any problem even though the code looks busy by nested properties access. We might also got slow down by looping through those nested structure. Let&#8217;s have a look through another implementation where we save multiple values as the key instead of only one.<br />
<span id="more-435"></span><br />
<pre class="brush: as3;">
//how about :
function addListener(source, eventName, handler, params): void {
	mkd.setValue(function (e: Event): void {
		handler.apply(null, params);
	}, source, eventName, handler); // --&gt; value, key1, key2, key3
}

//instead of 
function addListener(source, eventName, handler, params): void {
	var evtObj	: Object = _dict[ source] ||= {};
	var handlerDict	: Dictionary = evtObj[eventName] || new Dictionary();
	handlerDict[handler] = function (e: Event): void {
		handler.apply(null, params);
	}
}

</pre></p>
<p><pre class="brush: as3;">
package vn.core.data 
{
	import flash.utils.Dictionary;
	/**
	 * ...
	 * @author thienhaflash
	 */
	public class MultiKey 
	{
		private var keys 		: Dictionary;
		private var keyCnt		: int;
		private var key2Value	: Dictionary; /* Object should also be fine here */
		
		private function combineKeys(autoNew: Boolean, keyList: Array): Array {
			if (!keys) return null;
			var arr	 : Array = [];
			var ckey : * ;
			var l	 : int = keyList.length;
			
			for (var i: int = 0; i &lt;l; i++) {//keep the order !
				ckey = keys[keyList[i]];
				if (!ckey) { //skip zero !
					if (autoNew) {
						keys[keyList[i]]	= ++keyCnt;
						keys[keyCnt]		= keyList[i];
						ckey				= keyCnt;
					} else {
						return null;
					}
				}
				arr.push(ckey);
			}
			//arr.sort(Array.NUMERIC); /* so the key is unique */
			return arr;
		}
		
		private function isValidKey(keys : Array, combine: Array): Boolean {
			var l: int = combine.length;
			for (var i: int = 0; i &lt; l; i++) {
				if (keys.indexOf(''+combine[i]) == -1) {//can not found some key
					return false;
				}
			}
			return true;
		}
		
		public function break2Key(s: String): Array {
			var arr : Array = s.split('*');
			for (var i: int = arr.length - 1; i &gt; -1; i--) {
				arr[i] = keys[arr[i]];
			}
			return arr;
		}
		
		public function removeValue(...keyList): * {
			var s 		: String = combineKeys(false, keyList).join('*');
			var value	: * ;
			if (s) {
				value = key2Value[s];
				delete key2Value[s];
			}
			return value;
		}
		
		public function filterValues(keyList: Array, returnValues: Boolean = true): Array {
			var combined	: Array = combineKeys(false, keyList);
			var result		: Array = [];
			for (var s : String in key2Value) {
				if (isValidKey(s.split('*'), combined)) {
					result.push(returnValues ? key2Value[s] : s);
				}
			}
			return result;
		}
		
		public function removeValues(keyList: Array, returnValues: Boolean = true): Object {
			var combined	: Array = combineKeys(false, keyList);
			var result		: Object = {};
			for (var s : String in key2Value) {
				if (isValidKey(s.split('*'), combined)) {
					result[s] = key2Value[s];
					delete key2Value[s];
				}
			}
			return result;
		}
		
		public function getValue(...keyList): * {
			var combined	: Array = combineKeys(false, keyList);
			return combined ? key2Value[combined.join('*')] : null;
		}
		
		public function setValue(value: *, ...keyList): void {
			if (!keys) {
				keys = new Dictionary();
				key2Value = new Dictionary();
			}
			key2Value[combineKeys(true, keyList).join('*')] = value;
		}
	}
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/435/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=435&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/07/26/multikey-dictionary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>Indexed Linked List</title>
		<link>http://thienhaflash.wordpress.com/2011/07/03/indexed-linked-list/</link>
		<comments>http://thienhaflash.wordpress.com/2011/07/03/indexed-linked-list/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 12:48:06 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=357</guid>
		<description><![CDATA[Indexed Linked List is an improved version of Single Linked List that enable random access (can only found on Array) and fast item splicing (can only found on Linked List). We can use it for prioritized queues where items often &#8230; <a href="http://thienhaflash.wordpress.com/2011/07/03/indexed-linked-list/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=357&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Indexed Linked List is an improved version of Single Linked List that enable random access (can only found on Array) and fast item splicing (can only found on Linked List). We can use it for prioritized queues where items often got inserted / removed at arbitrary positions. Some popular applications are loading queue manager (sort by priority), delayed tween list (sort by delay), or custom Event Dispatcher (addListeners with priority).</p>
<h4>I. THE GENERAL IDEA :</h4>
<p>We have a single linked list (to cut memory cost 30% compared to double linked list), every item has a {.next} pointer point to the next item in the list. Every item has a {.priority} property to be used as mandatory sort term, a {.time} stamp for secondary sort term, this way, every item is unique and can be compared to each other without equality worries.</p>
<p>Besides the normal linked list implementation we have another Array {_grid} to keep track of pivots items at some rough space {_gridSize}, that means for every roughly {_gridSize} items in the list we save an item into the {_grid}. This kind of indexing will enable binary search for position of any item in the list which means fast random access to items (fixed (and small) time to reach any item in the list). Of course, this won&#8217;t beat Array&#8217;s random access, but it&#8217;s fast enough for practical use !<span id="more-357"></span></p>
<h4>II. THE LAZY PIVOT CREATION STRATEGY :</h4>
<p>We don&#8217;t need to refresh the pivot table for every item insert / remove as it&#8217;s not efficient.  As a new pivot can be introduced for every {_gridSize} items added, we only need to refresh the {_grid} for every {_gridSize } items added to the list. Besides that simple check, we can add others checks for special case when new items are always added to the last position (and this seems to be the most popular case in practice) :  we will only need to push new pivots  items into the {_grid} instead of refresh the whole list.</p>
<p>When we iterate through the list using iterStart(), iterNext(), the indexes and pivots will also be updated if needed.</p>
<h4>III. THE LAZY DIRTY MARKING / CLEANING STRATEGY :</h4>
<p>We divide the _dirty status into 3 states :</p>
<ul>
<li>NONE &#8211; no dirty at all, all items&#8217; indexes are correct</li>
<li>SIMPLE &#8211; items comes after dirty position {_dirty} have the same index offset {_offset}</li>
<li>COMPLEX &#8211; items comes after _dirty have non-ordered indexes (arbitrary).</li>
</ul>
<p>So, first thought in your mind : <strong>Why should we care about SIMPLE or COMPLEX dirty state instead of just a simple boolean _dirty flag, it&#8217;s dirty anyway, what&#8217;s the different</strong> ? Well, if you have a closer look about SIMPLE you might see that we can know the correct index immediately by a simple check : if the items is before _dirty, its index is correct, if not, the index should be + an offset. So we don&#8217;t need to update every _dirty items for every changes and this will improve the performance very much.</p>
<p>Now, second question might raise up : <strong>But the SIMPLE case is rare, as we insert/remove two (or more) items into the NONE dirty list, we get COMPLEX dirty and there are no use for SIMPLE at all, right ?</strong>  No, it&#8217;s not that simple, when a new  item {_new} is insert into the list, we will update the items between {_new} and {_dirty}. After that, we update the _dirty and _offset to the correct values. This way, the list will be at the SIMPLE state almost all the time.</p>
<p>Third question : <strong>What if the space between the {_dirty} and {_new} is too large, might be approximated to the length of the whole list ? Isn&#8217;t that mean we need to travel through the whole list when that item being inserted ?</strong> Well, in the implementation we have a range check, if the number of items need to be updated is more than some specific value {_maxUpdate} we just skip the update and change the _dirty state to COMPLEX. We also have another refined check to keep the list at SIMPLE dirty state for this case : if the {_dirty} or the {_new} is really near to the last item in the list {_last} we will update items from it (the item that is very near to {_last}) to {_last} instead of update the items between {_dirty} and {_new}. We can see that we will never need to update more than {_maxUpdate} items for every item insert / remove</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/357/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/357/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/357/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=357&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/07/03/indexed-linked-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>onDataStructure();</title>
		<link>http://thienhaflash.wordpress.com/2011/07/02/on-data-structure/</link>
		<comments>http://thienhaflash.wordpress.com/2011/07/02/on-data-structure/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 09:40:40 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=308</guid>
		<description><![CDATA[One of the most common data structure in Flash is Array, which provides a fast way to construct a list of data items with compact memory cost. This data structure is working fine and rather fast, except for some operations, &#8230; <a href="http://thienhaflash.wordpress.com/2011/07/02/on-data-structure/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=308&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the most common data structure in Flash is Array, which provides a fast way to construct a list of data items with compact memory cost. This data structure is working fine and rather fast, except for some operations, for example, insert / remove items randomly (splice) or pushing things to the beginning of the Arrays (unshift). Because of the compact memory implementation, all the existed items after the insert position will need to be migrated. With o(n) complexity, operated time goes up linearly with the number of items. And it&#8217;s just the same for Vector, although Vector is way faster than Array as there are no dense checking and converting between Dense Array &amp; Hash Table (there are more reasons ? ). In short : <strong>Array is slowing down by items migration</strong></p>
<p>A rather popular solution is using Linked List &#8211; either double or single. Linked list has ability to add and remove items very fast at an arbitrary position as no item is being migrated. Double linked list cost more memory (~ 1.5x ) and a bit slower than single Linked List (which, consume 2x more memory than Array) but it allows traversing in both direction. For some operations, the doubles run faster (~ 2x faster) than single ones. But as we won&#8217;t have random access to items by numeric indexes like Arrays, it&#8217;s really slow if we need to skip forward / backward to get to some random position. In short : <strong>Linked List is slowed down by skipping to specific position </strong><span id="more-308"></span></p>
<p>In the classic presentation of Array and Linked List above, Array performs better than Linked List. It&#8217;s a popular fact that Linked List out performs Array in term of inserting / removing items at specific position, <strong>remember that it&#8217;s only true if our current position is also the needed-to-be remove item&#8217;s position</strong> (<em>a popular case is we are trying to remove a dead item at current position while traversing through the whole linked list</em>). Randomly remove an item in linked list will be much slower than that as we need to skip to the delete item&#8217;s position.</p>
<p>So if you have a fixed set of data items like book indexes, address indexes &#8230; using Array will be fit for most of the case. Prevent using Linked List unless you really know how it works, as the rule of thumb : <strong>Never try random access on a Linked List. </strong>There are also cases that we don&#8217;t have all data items available at the beginning as items getting added to / removed from the list at random position, random time : a delayed tween queue or a loading queue. In this case, using Array.sort() once for every insertion or call Linked List&#8217;s insert() won&#8217;t yield any in good performance as the complexity of inserting n items randomly in both case is o(n^2).</p>
<p>We definitely have some better way doing that !</p>
<ul>
<li>With Array, we can use a binary search for position and insert new items using splice(). The complexity is now o(log2(n)) + o(n) = <strong>o(n)</strong>.</li>
<li>With Linked list, we have several options to choose from, regarding <strong>Binary Tree</strong>, <strong>Bias Linked List</strong>, or <strong>Indexed Linked List</strong>. These methods use various strategies to index items so we can both traverse to a specific position faster than linked list, with<strong> o(l0g2(n))</strong> complexity.</li>
</ul>
<p>The Linked List speed gains come with some memory suffers (2x more) for saving indexes positions, initialization (the structure is more complex and heavy) and maintain works (some kind of tree status checking and make changes in the structure as data items come in / out). To minimize the initialization delay and maintain works, Linked List should implements lazy-loading to minimize the works needed for performance gains. Without lazy loading implemented, Linked List is not really a considerable option to choose.</p>
<p>I might update this post with some performance benchmark so you guys can see how each one performs yourself. Specific details on how Linked List being implemented might not fit into a single post so let&#8217;s wait for some other ones &#8230;.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/308/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=308&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/07/02/on-data-structure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>A better AS3 Singleton implementation</title>
		<link>http://thienhaflash.wordpress.com/2011/06/20/a-better-as3-singleton-implementation/</link>
		<comments>http://thienhaflash.wordpress.com/2011/06/20/a-better-as3-singleton-implementation/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 05:29:20 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Actionscript 3]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[better]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=326</guid>
		<description><![CDATA[As a developer we usually need to create libraries to reuse in various projects, most of them are of the manager style : one class (or instance) to handle all in coming tasks from various places, popular examples are : &#8230; <a href="http://thienhaflash.wordpress.com/2011/06/20/a-better-as3-singleton-implementation/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=326&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As a developer we usually need to create libraries to reuse in various projects, most of them are of the manager style : one class (or instance) to handle all in coming tasks from various places, popular examples are : Tween engines, Loading services, 3D libraries, Sound processing library &#8230; The simplest implementation is the static-class-methods way.</p>
<h1>I. THE STATIC CLASS METHODS IMPLEMENTATION :</h1>
<p>Let&#8217;s have a look through a simple library class :</p>
<p><pre class="brush: as3;">
package {
	public class MyUtility {
		public static function methodA(): void {
			//do A things here
		}
		public static function methodB(): void {
			//do B things here
		}
	}
}
</pre></p>
<p>And its simple usage syntax</p>
<p><pre class="brush: as3;">
MyUtility.methodA();//call method A
MyUtility.methodB();//call method B
</pre><br />
<span id="more-326"></span><br />
<strong>This approach, though very clear and simple, in both implementation and usage introduces several problems :</strong></p>
<ol>
<li><strong>Memory cost :</strong> Static class members will need memory to store all the data, just as class instances, the problem is, the memory got allocated by static class should never be disposed, as its method can be called any time from various places in your (or other guy&#8217;s ) code. How can we be able to clear references to static methods of a class ? We can&#8217;t. <strong>This single factor will degrade our application dramatically over time, as modules get loaded, more and more static classes being deployed got stuck in the memory, and memory footprint raised up</strong>.</li>
<li><strong>Modules file size :</strong> all class libraries got compiled into every modules used them, that means there might be many library duplication over modules, of course, it&#8217;s not very efficient if the size of library is big or you are using a lot of static libraries &#8211; <strong>you force users waiting for things you already have, to be loaded again and again.</strong></li>
<li><strong>Rigid binding between these libraries :</strong> this will not only disable the ability to unit test them, but also, disable developer to change the dependent libraries later on. Let&#8217;s say, if we have a Transition library TransA that got to use a tween engine TweenA then if we are referencing TweenA directly from TransA, TransA will never be able to live without TweenA. That say, if user want to use TransA with some other TweenB engine, he just can&#8217;t do that without modify TransA heavily. <strong>That&#8217;s bad, strong coupling like this is very bad practice and needless to say, we must avoid it.</strong></li>
</ol>
<p>There is also another popular library implementation : <strong>Singleton</strong>.</p>
<h1>II. THE POPULAR AS3 SINGLETON IMPLEMENTATION :</h1>
<h1><span class="Apple-style-span" style="color:#333333;font-weight:300;">Basically singleton is just as simple as &#8220;prevent user to instantiate a Class and use the only one instance provided instead&#8221;. Let&#8217;s have a look through the most popular singleton implementation in AS3.</span></h1>
<p><pre class="brush: as3;">
package {
	public class MyUtility {
		function methodA(): void;
		function methodB(): void;

		public function MyUtility(){
			if (_instance) throw
				new Error(&quot;MyUtility is singleton and can not be instantiated !&quot;);
		}

		protected var _instance : MyUtility = new MyUtility();
		public static function getInstance(): MyUtility { return _instance; }
//you can also change the static function getInstance() to a getter instance for shorter syntax, but the getInstance() is more popular as from my awareness ...
	}
}
</pre></p>
<p>Ok, for perfectionist : this is NOT the perfect singleton implementation, yet, as user can still instantiate the class by using try / catch. But it&#8217;s non sense fighting for the perfect version as developers won&#8217;t use our library just for breaking purpose. As long as they can&#8217;t instantiate, they will know it&#8217;s singleton and use .getInstance(), that&#8217;s enough&#8230; Think ! Don&#8217;t put your-smart-codes in just to make the library more complex. There are no need for any kind of SingletonEnforcer or secretKey here.</p>
<p>What&#8217;s good here is that MyUtility now has only one static method (and one variable) to keep reference to an instance of MyUtility and as long as we want to dispose the Utility we can dispose the only _instance and get back the memory cost (but i don&#8217;t see that it will happen very often).</p>
<p>What&#8217;s bad here is the usage syntax :</p>
<p><pre class="brush: as3;">
MyUtility.getInstance().methodA();
MyUtility.getInstance().methodB();
</pre></p>
<p>Why should i need to .getInstance() all the time ? If there are only one thing to choose from, why should we need to choose? Hey, we don&#8217;t need to type that !</p>
<p>Other bad things like module file size cost and rigid binding is still remains.This implementation only solves one problem (memory cost) while introduces another one (stupid syntax).</p>
<p>That&#8217;s why you are being told that static is bad and devil and you should keep away from it. Well, i don&#8217;t really think that we should keep away from it, but just be careful when it comes to static cases. Static is a language feature, it&#8217;s exist for some reasons but it matters how you used it, so again, be careful !</p>
<h1>III. A BETTER WAY AROUND :</h1>
<p>First thought comes to our mind is that we need to implement an Interface to have Strong typing and smaller file size for modules, basically, modules will only have reference to the Interface instead of the implementation class, the implementation classes will only get compiled into main module. We modify the Singleton a little bit to implements IMyUtility !</p>
<p><pre class="brush: as3;">
package {//first, the interface
	public interface IMyUtility {
		function methodA(): IMyUtility;
		function methodB(): IMyUtility;
	}
}
</pre><br />
<pre class="brush: as3;">
package {//second, the class implementation
	internal class MyUtilityCore implements IMyUtility {
		public function methodA(): IMyUtility {};
		public function methodB(): IMyUtility {};
	}
}
</pre></p>
<p>At this point we have a normal class library implementation with with the present of an interface. You may have noticed that we now have a better jQuery style syntax where methods can be chained. The MyUtilityCore class is now internal, completely prevent users to accidentally instantiate it.</p>
<p>To prevent the heavy MyUtilityCore class gets into the compiled modules, we make another two classes, one for modules to get access to MyUtilityCore functionalities through IMyUtility interface, one for main module to initialize (do inject MyUtilityCore implementation to MyUtility). Here is the simplest version !</p>
<p><pre class="brush: as3;">
package {//fourth, the initialize package function
	public var myUtility : IMyUtility; /* [GETTER] don't change this variable ! */
}
</pre><br />
<pre class="brush: as3;">
package {//fourth, the initialize package function
	public function initMyUtility(): IMyUtility {
		if (!myUtility) myUtility = new MyUtilityCore();
		return myUtility;
	}
}
</pre></p>
<p>For simplicity purpose we don&#8217;t want to force myUtility to be a getter as it should be (in that case, we will need another internal class to save the reference to the MyUtilityCore instance because we can not declare a package variable together with a package function in the same file). Make a caution for our developers, that&#8217;s enough.</p>
<p>Let&#8217;s see what we have up to now. We need to init MyUtility before use, call it only once from the main Module, where the MyUtilityCore class got injected :</p>
<p><pre class="brush: as3;">
initMyUtility();//only call once in the main module
</pre></p>
<p>And for each modules, the usage is just the same as the static class method implementation (well, actually a bit better with j-Query chain) :</p>
<p><pre class="brush: as3;">
//use extensively in modules
myUtility.methodA()//call method A
		.methodB();//then call method B
</pre></p>
<p><strong>As a brief  conclusion about this implementation :</strong></p>
<ol>
<li>We replace one heavy class (MyUtilityCore) in modules by several lightweight one (myUtility, IMyUtility) to minimize file size in modules.</li>
<li>We may keep memory low by disposing the only the instance of MyUtilityCore at anytime by setting myUtility = null.</li>
<li>We prevent the rigid classes binding by using interface, later on, if user don&#8217;t like our myUtilityCore implementation they can change to another one without worring about code overlaps / fightings.</li>
<li>We will need to write more code for each library as there are now 4 instead of just one class. The implementation is a bit more complex, but for me, as long as the result looks best to our users, it&#8217;s worth implemeting this !</li>
</ol>
<p>And that&#8217;s it &#8211; A better AS3 Singleton implementation. If you have any idea about improving this implementation or a better way doing it, don&#8217;t hesitate to raise up your voice, we are all ears listening !</p>
<p>You can also <a href="http://dl.dropbox.com/u/10796188/wp/source/MyUtility.zip" target="_blank">download the sample code FD project </a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/326/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=326&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/06/20/a-better-as3-singleton-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>onGaiaFramework();</title>
		<link>http://thienhaflash.wordpress.com/2011/05/31/on-gaia-framework/</link>
		<comments>http://thienhaflash.wordpress.com/2011/05/31/on-gaia-framework/#comments</comments>
		<pubDate>Tue, 31 May 2011 02:30:17 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=270</guid>
		<description><![CDATA[After using Gaia for a long time with numerous websites built, i can tell you that completely like it as the workflow is simplified so much, i really love the scaffolding, assets managements, contextMenu, event hijacking, routing, assetPath, tracking, binding &#8230; <a href="http://thienhaflash.wordpress.com/2011/05/31/on-gaia-framework/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=270&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After using <a href="http://www.gaiaflashframework.com/" target="_blank">Gaia</a> for a long time with numerous websites built, i can tell you that completely like it as the workflow is simplified so much, i really love the scaffolding, assets managements, contextMenu, event hijacking, routing, assetPath, tracking, binding expression, the complete integration of SWFAddress, SEO &#8230; everything ! But that&#8217;s not to say there are no more room to get improved. Let&#8217;s dig in for more details !</p>
<ol><span id="more-270"></span></p>
<li><strong>A little bit more on deeplink, ApplicationDomain, and Scaffold </strong>:</li>
<ul>
<li>When a page is not yet load, we tell Gaia to go to a page with some deeplink, the onDeepLink is not called, why not check and call it manually so developers don&#8217;t need doing that themselves ? &lt;<em>will i need to insert sample code here (?)</em>&gt;.</li>
<li>The domain in <strong>site.xml</strong> should be &#8220;<em>current</em>&#8221; by default as that&#8217;s beginner assumption if they don&#8217;t know anything about <strong>ApplicationDomain</strong>. I myself don&#8217;t use domain other than &#8220;<em>current</em>&#8221; very often.</li>
<li>How about one toggle button to <strong>enable / disable scaffolding</strong> in Gaia panel instead of // on every file in the constructor to toggling them on/off ?</li>
</ul>
<li><strong>Better templating creation</strong> : How about we just need to specify a layout folder, Gaia will automatically generate the <strong>site.xml</strong> based on the pngs / jpgs files in that folder, we can add some naming rules for these files, of course ? And in the generated flas, a layer is also created with the corresponding layout file so we can have a quick reference, we can make an option for user to choose if they want to guide the layer or not ? And of course we can always change the <strong>site.xml</strong> file then sync if the generation is not perfectly match our idea.</li>
<li><strong>Visual pages creation in Gaia panel</strong> : It&#8217;s easy to open <strong>site.xml</strong> and edit it, yep, but why should i leave Gaia panel ? How about adding a visual tree then we can add pages just as <em>folders</em> (index should be the root and can not be replaced ? ) and assets can be represented just as <em>files</em> ? Adding / Removing (or even disable items are now visual and quick). This will make Gaia even easier to beginners. For advanced options (other node properties beyond id, src, title) we can either have a datagrid that only show when a page is selected (hey, this is visual, quick, easy and safe as we don&#8217;t need to remember the node&#8217;s properties) or ignore these and let developers change the <strong>site.xml</strong> file whenever they need. For temporary removing a page, we can uncheck the box that goes before each page (equivalent to commented out in site.xml ?)</li>
<li><strong>Enable template for pages</strong> : There are many case that we have several pages with just the same or mostly the same (gallery, video for example), just different data. What if we can define template pages and then specify the template for each page created in site.xml ? This will minimize the efforts for creating multiple deeplink pages with the same structure, the only different is the asset data. If we agree on implementing the tree based pages creation above, we can add visual template binding to pages, too. &lt;<em>do i need to insert a suggested layout for this one here ?</em>&gt;. This also allow us to write simple site editor based on template pages. All we need to do is open site.xml and add more pages based on the existed templates, no rebuild needed to adding / removing pages that are based on the template !</li>
<li><strong>Enable option to switch transition style of a page between timeline / code </strong>: There are times when you need to do page animation by code (dynamic data, liquid size &#8230;) together with some kind of an intro page, so you will need to create pages using actionscript template except one or some pages, how can we do then ? We need to manually copy the frames in the template .fla files and paste ? Any better way?</li>
<li><strong>One more Build button</strong> : When we modify a page, most of the time we only need to build it then open main.swf, this works faster for big projects, especially for projects with many pages, so how about allow us to select the pages to rebuild for faster project test ? The idea is we will now have 2 build buttons, a big one for complete project rebuild and a smaller one to build only selected pages?</li>
<li><strong>Better layer settings</strong> : Gaia currently only allow one page to appear a time, what if we need some overlay content ? We mostly will need to implement it in the <strong>nav</strong> page with will available for all children pages. What if we need some background content ? We mostly will need to put it in to the index page. Why don&#8217;t let us specify layers in <strong>site.xml </strong>? and then for each layer, there are only one &lt;content&gt; to be shown at a time ? That means we can easily have multiple overlay contents, for a common setup we will have 3 layers : &lt;background&gt;&lt;content&gt;&lt;navigation&gt;</li>
</ol>
<div>There are several library i would like to add to Gaia, too, but it still seems better keeping them separated : Font creator, Liquid Manager, Language Manager, Menu system &#8230; Any other things you really want to add in this list ? Raise your voice !</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/270/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/270/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/270/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=270&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/05/31/on-gaia-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>First time on a Mac</title>
		<link>http://thienhaflash.wordpress.com/2011/05/23/first-time-on-a-mac/</link>
		<comments>http://thienhaflash.wordpress.com/2011/05/23/first-time-on-a-mac/#comments</comments>
		<pubDate>Mon, 23 May 2011 16:01:09 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Notes]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=212</guid>
		<description><![CDATA[Get used to Windows for many years and several times on Ubuntu but this is my first time to a Mac, i feel awkward getting the way through&#8230; there are some cool things and there are some bad things compared &#8230; <a href="http://thienhaflash.wordpress.com/2011/05/23/first-time-on-a-mac/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=212&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Get used to Windows for many years and several times on Ubuntu but this is my first time to a Mac, i feel awkward getting the way through&#8230; there are some cool things and there are some bad things compared to windows OS, see it for yourself !</p>
<ol>
<li>There are no shift-delete and i can&#8217;t find a way to delete a file without move it to trash first, it takes time and not efficient.</li>
<li>You can not show desktop (windows+D) without installing a utility (use F11 for quick windows hide)</li>
<li>You can not use function keys for functions, just you it for the brightness / volume adjust &#8230; you will need to install a utility then (try function flip).</li>
<li>You can force move files around by cmd+drag just like shift+drag/drop on windows</li>
<li>You can force copy files by alt+drag just like ctrl+drag/drop on windows</li>
<li>There are no end/home/pageUp/pageDown keys, use cmd+arrows instead</li>
<li>The delete button actually is backspace, there are no pc-like delete button</li>
<li>The mouse has only 1 button, want right click ? tap with two fingers</li>
<li>Replace cmd for pc&#8217;s ctrl : cmd+c for copy, cmd+v for paste, cmd+x for cut (editor only, won&#8217;t work on Finder), cmd+z for undo</li>
<li>Delete a file / folder : cmd+delete, just press delete won&#8217;t have any effect (why?)</li>
<li>Need to scroll down / up a file ? hold 2 fingers on the mouse pad and move at the same time &#8211; just works exactly like your mouse wheel.</li>
<li>Want to unzip a file ? double click onto it, the file will be extract to a folder. Want to view the content of the zip without extract ? you can&#8217;t do it without install a small utility. Want to zip a folder or a file ? right click, choose archive, a new archive.zip file will be created, you can change the name after that.</li>
<li>You can read an NTFS drive from Mac but can not write to it, use some utility to enable write (with slow speed to be cared about)</li>
<li>Disable creation of .DS_STORE and other .CLEAN_FILES files (only for network volumes): open terminal and type the following <strong>defaults write com.apple.desktopservices DSDontWriteNetworkStores true</strong> or use <a href="http://www.bresink.com/osx/0TinkerTool/download.php5" target="_blank">Tinker tool</a>, any suggestion for completely remove .FILES for shared volumes between Mac + PC ? BlueHarvest ?</li>
</ol>
<p>to be continued &#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/212/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/212/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/212/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=212&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/05/23/first-time-on-a-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
		<item>
		<title>Anh còn nhớ</title>
		<link>http://thienhaflash.wordpress.com/2011/05/21/anh-con-nh%e1%bb%9b/</link>
		<comments>http://thienhaflash.wordpress.com/2011/05/21/anh-con-nh%e1%bb%9b/#comments</comments>
		<pubDate>Sat, 21 May 2011 02:37:27 +0000</pubDate>
		<dc:creator>Thiên Hạ</dc:creator>
				<category><![CDATA[Truyện ngắn]]></category>

		<guid isPermaLink="false">http://thienhaflash.wordpress.com/?p=241</guid>
		<description><![CDATA[Trước mặt ba mẹ em, anh đã xiết tay em thật chặt, và luôn khẳng định sẽ ở bên, che chở cho em đến trọn đời. Lần em buồn khi công việc không như ý, anh đến công ty em &#8230; <a href="http://thienhaflash.wordpress.com/2011/05/21/anh-con-nh%e1%bb%9b/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=241&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Trước mặt ba mẹ em, anh đã xiết tay em thật chặt, và luôn khẳng định sẽ ở bên, che chở cho em đến trọn đời.</p>
<p>Lần em buồn khi công việc không như ý, anh đến công ty em chỉ để gửi lá thư, có một dòng: “Can đảm lên, người yêu! Anh luôn bên em!”.</p>
<p>Anh còn nhớ, với gương mặt hỉ hả anh xách về cho em một túi cà chua và không ngừng kể công: “Cà chua sạch đấy!”. Quên sao được cảnh thi thoảng anh thức dậy kê lại cái gối chân cho vợ đang có bầu khỏi mỏi. Anh còn đảm đang dậy sớm nấu ăn sáng, để vợ ngủ thêm chút nữa, vì thương vợ khó ngủ.</p>
<p>Anh còn nhớ lần em buột miệng than khi trời đã tối khuya, rằng xe máy phanh hơi sâu và vào số hơi nặng? Anh không quản ngại, lôi đồ nghề ra chỉnh lại luôn, bởi sáng hôm sau phải đi làm sớm nhỡ không kịp.</p>
<p>Từng hành động quan tâm nhỏ cùng những tháng ngày hạnh phúc ấy, chẳng khi nào em quên. Còn anh?<span id="more-241"></span></p>
<p>Ngày công ty khủng hoảng, hết việc, hơn tháng ròng đồng cam cộng khổ, chia ngọt sẻ bùi ấy, vợ chồng mình đã cùng sợ cho cảnh đứa con sắp chào đời bị nhếch nhác, thương cho tương lai mờ mịt, nhưng nước mắt đã được em lau khô mỗi buổi sáng và em cũng biết nỗi trăn trở mỗi đêm đã được anh giấu vào lòng. Anh lại ôm em thủ thỉ: “Cố gắng nào, chắc chắn gia đình mình sẽ mãi hạnh phúc”.</p>
<p>Vì không muốn để ba mẹ phải lo lắng nên mình giấu việc anh thất nghiệp, vậy là cuộc sống vốn bí bách lại càng thêm cùng quẫn khi vừa lo ăn từng bữa, vừa phải dành dụm rồi nói khó khi cứ bị ba mẹ giục giã mau trả nợ cô út để sắp tới cô xây nhà. Món nợ từ thời anh đi học văn bằng 2 đó treo lơ lửng trên đầu hai đứa.</p>
<p>Qua những ngày nín thở lo lắng, hồi hộp, bắt đầu đi làm, anh mừng rỡ báo tin về cho gia đình khiến họ càng thêm hãnh diện về anh. Nhưng anh lại “quên” không khai số lương thử việc ít ỏi anh được nhận trong hai tháng, khiến mẹ tưởng con trai mình tài hoa hơn người, kiếm bộn tiền lắm. Trong khi em vẫn phải đau đầu lo chi tiêu cho gia đình thì cạnh đó mẹ vẫn trách móc, con dâu chẳng biết điều, khiến em khổ tâm muốn khóc. Thôi thì đã có lời anh an ủi: “Anh hiểu em là đủ”, dĩ nhiên rồi, nếu không có người chồng tâm lý, yêu thương vợ hết mực ở bên, làm sao em vượt qua được bao sóng gió.</p>
<p>Anh còn nhớ từng nói với em, sẽ không bao giờ để vợ con phải khổ, sau này con sẽ tự hào vì có người cha như anh. Em sẽ không phải hối hận vì đã quyết tâm lấy anh, chịu đựng cuộc sống ban đầu thiếu thốn.</p>
<p>Và những vất vả dần được tháo gỡ, anh đã sáng suốt khi đi theo một minh quân, sếp anh là người xuất chúng, có tầm nhìn xa trông rộng, những kế hoạch của ông từ to đến bé đều ít nhiều thành công. Vậy là những “công thần” bên ông cũng được đãi ngộ xứng đáng. Công sức của anh đã được nhìn nhận và coi trọng. Sự nghiệp đã khiến anh đạt được những gì mình mong muốn, giúp đỡ gia đình, anh em hai bên, rồi đến “một người làm quan, cả họ được nhờ”.</p>
<p>Song các cuốn sách luyện lý trí, rèn nghị lực, gương danh nhân… giờ có còn chút nào đọng lại trong suy nghĩ của anh? Anh còn nhớ ngày anh miệt mài đọc chúng, tâm đắc đến nỗi còn dành thời gian đánh máy thành ebook để gửi lên thư viện, anh còn nhớ đã từng nói: “Chúng sẽ là cẩm nang để anh vượt qua những cám dỗ tầm thường, tránh đi theo vết xe đổ của những kẻ lắm tiền đi ruồng rẫy vợ con”.</p>
<p>Những điều đó có lẽ anh đã quên cả rồi, thì cô ấy mới có thể xen vào cuộc sống hạnh phúc của vợ chồng mình như thế!</p>
<p><strong>Link bài viết gốc : </strong> <a href="http://dantri.com.vn/c130/s130-386524/anh-con-nho.htm" target="_blank"></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/thienhaflash.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/thienhaflash.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/thienhaflash.wordpress.com/241/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=thienhaflash.wordpress.com&amp;blog=3875128&amp;post=241&amp;subd=thienhaflash&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://thienhaflash.wordpress.com/2011/05/21/anh-con-nh%e1%bb%9b/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>0.000000 0.000000</georss:point>
		<geo:lat>0.000000</geo:lat>
		<geo:long>0.000000</geo:long>
		<media:content url="http://0.gravatar.com/avatar/24f08e2e214efb782af34dbb58c9b3c2?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thienhaflash</media:title>
		</media:content>
	</item>
	</channel>
</rss>
