<?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/"
	>

<channel>
	<title>.:: klr20mg ::. Una dosis diaria de .... &#187; ActionScript</title>
	<atom:link href="http://klr20mg.com/category/actionscript/feed/" rel="self" type="application/rss+xml" />
	<link>http://klr20mg.com</link>
	<description>Blog acerca de desarrollo orientado hacia Flash, Flex y Actionscript.</description>
	<lastBuildDate>Wed, 26 May 2010 21:59:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Air 2.0 Conexi&#243;n IMAP mediante SecureSocket</title>
		<link>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/</link>
		<comments>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 01:56:24 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Ejemplos]]></category>
		<category><![CDATA[Flex 4]]></category>
		<category><![CDATA[AIR 2.0]]></category>
		<category><![CDATA[FlashBuilder]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=546</guid>
		<description><![CDATA[Una de las nuevas características de Adobe Air 2.0 es la conexión a servidores mediante sockets encriptados (SSL). Uno de los servicios mas comunes que utiliza una conexión encriptado son los proveedores de correo usando IMAP. Para este ejemplo vamos a conectarnos al servidor IMAP de Gmail y obtener el numero de mensajes nuevos y [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://klr20mg.com/wp-content/uploads/2010/02/Adobe_Air-logo-8BE840B3A1.gif" alt="" title="Adobe_Air-logo-8BE840B3A1" width="200" height="200" class="alignright size-full wp-image-548" /><br />
Una de las nuevas características de Adobe Air 2.0 es la conexión a servidores mediante sockets encriptados (SSL).</p>
<p>Uno de los servicios mas comunes que utiliza una conexión encriptado son los proveedores de correo usando IMAP.</p>
<p>Para este ejemplo vamos a conectarnos al servidor IMAP de Gmail y obtener el numero de mensajes nuevos y mensajes en total que existen en nuestra cuenta.</p>
<p>Para fines prácticos de este ejemplo necesitamos:</p>
<ul>
<li>Una cuenta de Gmail, <a href="http://mail.google.com/mail/#settings/fwdandpop">con IMAP habilitado</a></li>
<li><a href="http://labs.adobe.com/technologies/flashbuilder4/">FlashBuilder</a></li>
<li><a href="http://labs.adobe.com/technologies/air2/">Adobe AIR 2.0</a></li>
</ul>
<p><span style="font-family: Georgia;">Lo primero es crear una interfaz sencilla en donde se pueda insertar el nombre de usuario, la contraseña, campos de output y un boton para iniciar el proceso.</span></p>
<pre class="brush: xml; light: true;">
	&lt;s:Label x=&quot;10&quot; y=&quot;17&quot; text=&quot;Gmail username:&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;45&quot; text=&quot;Gmail password:&quot;/&gt;
	&lt;s:TextInput y=&quot;10&quot; id=&quot;username_txt&quot; change=&quot;_username = username_txt.text&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:TextInput y=&quot;40&quot; id=&quot;password_txt&quot; change=&quot;_password = password_txt.text&quot; displayAsPassword=&quot;true&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:Button y=&quot;70&quot; label=&quot;Tell me!!&quot; click=&quot;start()&quot; right=&quot;10&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;100&quot; width=&quot;280&quot; id=&quot;result_txt&quot;/&gt;
	&lt;s:TextArea id=&quot;out_txt&quot; editable=&quot;false&quot; right=&quot;10&quot; bottom=&quot;10&quot; top=&quot;130&quot; left=&quot;10&quot;/&gt;
</pre>
<p><span id="more-546"></span></p>
<p>El resultado de esto se ve de esta forma:</p>
<div align="center">
<img src="http://klr20mg.com/wp-content/uploads/2010/02/gmailSSL.png" alt="" title="gmailSSL" width="308" height="280" class="aligncenter size-full wp-image-547" />
</div>
<p>Despues de tener nuestra interfaz vamos a declarar todas la variables y constantes que vamos a necesitar:</p>
<pre class="brush: as3; light: true;">
			/******************************************************************
			 *	Datos de la cuenta (Gmail IMAP)
			 * ***************************************************************/

			private static const INCOMING_SERVER:String = &quot;imap.gmail.com&quot;;
			private static const PORT:int = 993;
			private var _username:String = &quot;&quot;;
			private var _password:String = &quot;&quot;;

			/******************************************************************
			 * Socket &amp;&amp; Stuff
			 * ***************************************************************/ 

			private var _server:Socket;
			private var _buffer:ByteArray;
			private var _action:String;
			private var _totalMessages:String;
			private var _newMessages:String;

			/******************************************************************
			 * Respuestas del servidor (para filtar el contenido)
			 * http://tools.ietf.org/html/draft-gahrns-imap-namespace-00
			 * ****************************************************************/

			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
			private static const CRLF:String = &quot;\r\n&quot;;
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);
</pre>
<p>Aqui hay un par de cosas que debo resaltar:</p>
<pre class="brush: as3; light: true;">
			private var _buffer:ByteArray;
</pre>
<p>En esta variable almacenaremos las respuestas que nos envié el servidor.</p>
<pre class="brush: as3; light: true;">
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);
</pre>
<p>Con esta expresion regular verificaremos si el mensaje que recibimos del servidor es util para nosotros.</p>
<pre class="brush: as3; light: true;">
			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
</pre>
<p>Estas constantes son los identificadores de los mensajes que se mandan desde y hacia el servidor para saber mas de estos identificadores recomiendo esta lectura <a href="http://tools.ietf.org/html/draft-gahrns-imap-namespace-00">http://tools.ietf.org/html/draft-gahrns-imap-namespace-00</a></p>
<p>Ahora nos queda inicializar nuestro socket y crear los eventos que usaremos para comunicarnos con el servidor</p>
<pre class="brush: as3; light: true;">
				_server = new SecureSocket();
				_server.addEventListener(Event.CONNECT, onConnect);
				_server.addEventListener(Event.CLOSE, onClose);
				_server.addEventListener(ProgressEvent.SOCKET_DATA, onData);
				_server.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
</pre>
<p>El único cambio con respecto a trabajar con Sockets sin encriptar es el constructor de la clase en lugar de usar </p>
<pre class="brush: as3; light: true;">
				_server = new Socket();
</pre>
<p>Ahora debemos utilizar</p>
<pre class="brush: as3; light: true;">
				_server = new SecureSocket();
</pre>
<p>Así de simple; Bien, hemos seteado los listeners para CONNECT, SOCKET_DATA, CLOSE y IO_ERROR vamos a concentranos solamente en SOCKET_DATA que es el evento que se dispara al momento de recibir un mensaje del servidor.</p>
<pre class="brush: as3; light: true;">
			private function onData(e:ProgressEvent):void
			{
				out_txt.text += &quot;Data &quot; + e+&quot;\n&quot;;
				var socket:Socket = e.target as Socket;
				var bufferString:String;
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
				bufferString = _buffer.toString();
				out_txt.text += &quot;SERVER: &quot; + _buffer.toString()+&quot;\n&quot;;
				if (  bufferString.search( _regSearch ) )
				{
					out_txt.text += &quot;Es una respuesta valida parsea\n&quot;;
					parseResponse();
				}
				cursorManager.removeBusyCursor()
			}
</pre>
<p>En esta función recibimos el evento y tomamos el contenido del mensaje mediante el método readBytes y lo almacenamos en la variable _buffer</p>
<pre class="brush: as3; light: true;">
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
</pre>
<p>Verificamos que el mensaje corresponda a nuestra petición, en este caso solo usamos 3 peticiones CONNECT, LOGIN, STATUS y si el mensaje es correcto parseamos el contenido.</p>
<p>El primer mensaje que recibimos del servidor es el de conexión</p>
<p><strong>SERVER: * OK Gimap ready for requests from 189.216.40.184 14if7528374pzk.62</strong></p>
<p>Una vez que estemos conectados mandamos nuestras credenciales para que el servidor nos autentique y cambiamos el mensaje a LOGIN indicando que estamos esperando el mensaje de respuesta de la solicitud de logueo.</p>
<pre class="brush: as3; light: true;">
				if ( _action == CONNECT )
				{
					out_txt.text += &quot;Es es tag de conexion manda login\n&quot;;
					_server.writeUTFBytes(LOGIN + &quot; LOGIN &quot; + _username + &quot; &quot; + _password + CRLF);
					_action = LOGIN;
					_server.flush();
					return;
				}
</pre>
<p>Se envia el mensaje y de inmediato recibimos la respuesta del servidor, en caso de login correcto:</p>
<p><strong>A002 OK tmeister@gmail.com authenticated (Success)</strong></p>
<p>Si es incorrecto:</p>
<p><strong>A002 NO [ALERT] Invalid credentials (Failure)</strong></p>
<p>Con esto es muy fácil saber el resultado de la operación, usemos indexOf para saber si la palabra &#8220;OK&#8221; existe</p>
<pre class="brush: as3; light: true;">
				if ( _action == LOGIN )
				{
					out_txt.text += &quot;Es la respuesta del login\n&quot;;
					if( bufferString.indexOf(&quot;OK&quot;) != -1 )
					{
						out_txt.text += &quot;El login es correcto, estamos autenticados - Pedir correos sin leer\n&quot;;
						_action = STATUS;
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
						_server.flush();
					}else
					{
						out_txt.text += &quot;Ooops!! Las credenciales no son validas.\n&quot;;
						Alert.show(&quot;Ooops!! Las credenciales no son validas.&quot;, &quot;Error&quot;);
						_server.close();
					}
					return;
				}
</pre>
<p>Excelente estamos autenticados, Ahora que? solo nos falta pedir el estatus de la cuenta pidiendo los mensajes totales y los mensajes nuevos de la carpeta Inbox</p>
<pre class="brush: as3; light: true;">
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
</pre>
<p>El ultimo paso es recibir el mensaje del servidor con la información que pedimos y parsearla, al ser texto solo tenemos que usar indexOf y substring para acceder a lo que nos interesa</p>
<p><strong>STATUS &#8220;inbox&#8221; (MESSAGES 61298 UNSEEN 5)</strong></p>
<pre class="brush: as3; light: true;">
				if( _action == STATUS )
				{
					out_txt.text += &quot;Es la respuesta del Status &quot; + bufferString+&quot;\n&quot;;
					var startSub:int = bufferString.indexOf(&quot;(&quot;);
					var endSub:int = bufferString.indexOf(&quot;)&quot;);
					var message:String = bufferString.substring(startSub+1, endSub);
					var slides:Array = message.split(&quot; &quot;);
					var count:int = 0;
					for each( var slide:String in slides )
					{
						switch( slide )
						{
							case &quot;MESSAGES&quot;:
								_totalMessages = slides[count + 1];
								break;
							case &quot;UNSEEN&quot;:
								_newMessages = slides[count + 1];
								break;
						}
						count++;
					}
					result_txt.text = _newMessages + &quot; mensajes nuevos, de &quot; + _totalMessages + &quot; en total&quot;;
					out_txt.text += _totalMessages;
					out_txt.text += _newMessages;
					_action = null;
					_server.close();
				}
			}
</pre>
<p>Sin duda, lo mas complejo al momento de trabajar con Sockets es saber utilizar e implementar el protocolo de comunicación pero esa ya es otra historia.</p>
<p>Por ultimo les dejo el código completo</p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;s:WindowedApplication xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
					   xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
					   xmlns:mx=&quot;library://ns.adobe.com/flex/halo&quot;
					   creationComplete=&quot;init(event)&quot;
					    width=&quot;300&quot; height=&quot;250&quot;&gt;
	&lt;fx:Script&gt;
		&lt;![CDATA[
			import flash.events.Event;
			import flash.events.IOErrorEvent;
			import flash.events.MouseEvent;
			import flash.events.ProgressEvent;
			import flash.net.SecureSocket;
			import flash.net.Socket;
			import flash.utils.ByteArray;

			import mx.controls.Alert;
			import mx.events.FlexEvent;

			private static const INCOMING_SERVER:String = &quot;imap.gmail.com&quot;;
			private static const PORT:int = 993;
			private var _username:String = &quot;&quot;;
			private var _password:String = &quot;&quot;;

			private var _server:Socket;
			private var _buffer:ByteArray;
			private var _action:String;
			private var _totalMessages:String;
			private var _newMessages:String;

			private static const CONNECT:String = &quot;*&quot;;
			private static const LOGIN:String = &quot;A002&quot;;
			private static const STATUS:String = &quot;A006&quot;;
			private static const CRLF:String = &quot;\r\n&quot;;
			private var _regSearch:RegExp = RegExp(&quot;\\&quot;+_action+&quot;\\r\\n&quot;);

			protected function init(event:FlexEvent):void
			{

				_server = new SecureSocket();
				_server.addEventListener(Event.CONNECT, onConnect);
				_server.addEventListener(Event.CLOSE, onClose);
				_server.addEventListener(ProgressEvent.SOCKET_DATA, onData);
				_server.addEventListener(IOErrorEvent.IO_ERROR, onIOError);

				_buffer = new ByteArray()
			}
			private function onConnect(e:Event):void
			{
				out_txt.text += &quot;Conexion establecida &quot; + e.toString()+&quot;\n&quot;;
			}
			private function onClose(e:Event):void
			{
				out_txt.text += &quot;Conexion cerrada &quot; + e+&quot;\n&quot;;
			}
			private function onData(e:ProgressEvent):void
			{
				out_txt.text += &quot;Data &quot; + e+&quot;\n&quot;;
				var socket:Socket = e.target as Socket;
				var bufferString:String;
				socket.readBytes(_buffer, _buffer.length, socket.bytesAvailable);
				bufferString = _buffer.toString();
				out_txt.text += &quot;SERVER: &quot; + _buffer.toString()+&quot;\n&quot;;
				if (  bufferString.search( _regSearch ) )
				{
					out_txt.text += &quot;Es una respuesta valida parsea\n&quot;;
					parseResponse();
				}
				cursorManager.removeBusyCursor()
			}
			private function onIOError(e:IOErrorEvent):void
			{
				out_txt.text += &quot;IOError &quot; + e+&quot;\n&quot;;
			}

			private function parseResponse():void
			{
				var bufferString:String = _buffer.toString();
				_buffer.clear();
				if ( _action == CONNECT )
				{
					out_txt.text += &quot;Es es tag de conexion manda login\n&quot;;
					_server.writeUTFBytes(LOGIN + &quot; LOGIN &quot; + _username + &quot; &quot; + _password + CRLF);
					_action = LOGIN;
					_server.flush();
					return;
				}
				if ( _action == LOGIN )
				{
					out_txt.text += &quot;Es la respuesta del login\n&quot;;
					if( bufferString.indexOf(&quot;OK&quot;) != -1 )
					{
						out_txt.text += &quot;El login es correcto, estamos autenticados - Pedir correos sin leer\n&quot;;
						_action = STATUS;
						_server.writeUTFBytes(STATUS + &quot; STATUS inbox (MESSAGES UNSEEN)&quot; + CRLF);
						_server.flush();
					}else
					{
						out_txt.text += &quot;Ooops!! Las credenciales no son validas.\n&quot;;
						Alert.show(&quot;Ooops!! Las credenciales no son validas.&quot;, &quot;Error&quot;);
						_server.close();
					}
					return;
				}
				if( _action == STATUS )
				{
					out_txt.text += &quot;Es la respuesta del Status &quot; + bufferString+&quot;\n&quot;;
					var startSub:int = bufferString.indexOf(&quot;(&quot;);
					var endSub:int = bufferString.indexOf(&quot;)&quot;);
					var message:String = bufferString.substring(startSub+1, endSub);
					var slides:Array = message.split(&quot; &quot;);
					var count:int = 0;
					for each( var slide:String in slides )
					{
						switch( slide )
						{
							case &quot;MESSAGES&quot;:
								_totalMessages = slides[count + 1];
								break;
							case &quot;UNSEEN&quot;:
								_newMessages = slides[count + 1];
								break;
						}
						count++;
					}
					result_txt.text = _newMessages + &quot; mensajes nuevos, de &quot; + _totalMessages + &quot; en total&quot;;
					out_txt.text += _totalMessages;
					out_txt.text += _newMessages;
					_action = null;
					_server.close();
				}
			}

			private function start():void
			{
				out_txt.text = &quot;iniciando Conexion\n&quot;;
				if( _server != null &amp;&amp; _server.connected )
				{
					_server.close();
				}
				if( _username.length &amp;&amp; _password.length )
				{
					_action = CONNECT;
					_server.connect(INCOMING_SERVER, PORT);
					cursorManager.setBusyCursor();
				}else
				{
					Alert.show(&quot;Escribe tus credenciales..&quot;, &quot;Error&quot;);
				}
			}

		]]&gt;
	&lt;/fx:Script&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;17&quot; text=&quot;Gmail username:&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;45&quot; text=&quot;Gmail password:&quot;/&gt;
	&lt;s:TextInput y=&quot;10&quot; id=&quot;username_txt&quot; change=&quot;_username = username_txt.text&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:TextInput y=&quot;40&quot; id=&quot;password_txt&quot; change=&quot;_password = password_txt.text&quot; displayAsPassword=&quot;true&quot; right=&quot;10&quot; left=&quot;120&quot;/&gt;
	&lt;s:Button y=&quot;70&quot; label=&quot;Tell me!!&quot; click=&quot;start()&quot; right=&quot;10&quot;/&gt;
	&lt;s:Label x=&quot;10&quot; y=&quot;100&quot; width=&quot;280&quot; id=&quot;result_txt&quot;/&gt;
	&lt;s:TextArea id=&quot;out_txt&quot; editable=&quot;false&quot; right=&quot;10&quot; bottom=&quot;10&quot; top=&quot;130&quot; left=&quot;10&quot;/&gt;
&lt;/s:WindowedApplication&gt;
</pre>
<h1>Descarga</h1>
<div style="width: 200px; margin: 10px; text-align: center">
	<p><a rel="nofollow" title="Download version 0.1 of Gmail-Imap.air" href="http://klr20mg.com/downloads/Gmail-Imap.air"><img src="http://klr20mg.com/wp-content/plugins/drain-hole/images/download.png" alt="download" width="128" height="128"/></a></p>

	<table class="download">
		<tr>
			<th>Download:</th>
			<td><a rel="nofollow" title="Download version 0.1 of Gmail-Imap.air" href="http://klr20mg.com/downloads/Gmail-Imap.air">Gmail-Imap.air</a></td>
		</tr>
		<tr>
			<th>Version:</th>
			<td>0.1</td>
		</tr>
		<tr>
			<th>Updated:</th>
			<td>February 26, 2010</td>
		</tr>
		<tr>
			<th>Size:</th>
			<td>870.16 KB</td>
		</tr>
	</table>
</div>

<p>Espero les sea de ayuda y nos estamos leyendo.</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2010/02/26/air-2-0-conexin-imap-mediante-securesocket/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flex Frameworks</title>
		<link>http://klr20mg.com/2009/11/19/flex-frameworks/</link>
		<comments>http://klr20mg.com/2009/11/19/flex-frameworks/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 04:47:51 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AMFPHP]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mate]]></category>
		<category><![CDATA[PureMVC]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=471</guid>
		<description><![CDATA[Esta es una excelente recopilación de Frameworks para trabajar con Flash/Flex, las categorías son: MVC frameworks and Dependency Injection Testing frameworks and code coverage Building and Continue Integration Flash 3D Engines Server side libraries/frameworks for Flex El texto introductorio dice: &#8220;Some say that if a technology has a lot of frameworks, then it is a sign of maturity. [...]]]></description>
			<content:encoded><![CDATA[<p>Esta es una excelente <span style="color: #551a8b;"><span style="text-decoration: underline;">recopilación</span></span><a href="http://corlan.org/flex-frameworks/" target="_blank"> </a>de Frameworks para trabajar con Flash/Flex, las categorías son:</p>
<ul>
<li>MVC frameworks and Dependency Injection</li>
<li>Testing frameworks and code coverage</li>
<li>Building and Continue Integration</li>
<li>Flash 3D Engines</li>
<li>Server side libraries/frameworks for Flex</li>
</ul>
<p>El texto introductorio dice:</p>
<blockquote><p><em>&#8220;Some say that if a technology has a lot of frameworks, then it is a sign of maturity. You might argue with that, but still I think it is interesting to know what are the available frameworks in the Flex/Flash world.&#8221;</em></p></blockquote>
<p>La información completa y links la pueden encontrar en el <a href="http://corlan.org/flex-frameworks/" target="_blank">blog de Mihai Corlan</a></p>
<p>Enjoy!</p>
<p>Link : <a href="http://corlan.org/flex-frameworks/" target="_blank">Flex Frameworks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/11/19/flex-frameworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Que tan subvalorado es el desarrollo web en Latinoamerica?</title>
		<link>http://klr20mg.com/2009/06/18/que-tan-subvalorado-es-el-desarrollo-web-en-latinoamerica/</link>
		<comments>http://klr20mg.com/2009/06/18/que-tan-subvalorado-es-el-desarrollo-web-en-latinoamerica/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 21:48:15 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=405</guid>
		<description><![CDATA[En estos últimos 2 días se han dado un par de eventos, los cuales me han puesto a pensar de una manera realmente concienzuda si el pago por los servicios de desarrollo en Latinoamerica, principalmente en México esta subvalorado, la verdad es que si, pero hasta que punto? ; Los eventos a los que me [...]]]></description>
			<content:encoded><![CDATA[<p>En estos últimos 2 días se han dado un par de eventos, los cuales me han puesto a pensar de una manera realmente concienzuda si el pago por los servicios de desarrollo en Latinoamerica, principalmente en México esta subvalorado, la verdad es que si, pero hasta que punto? ; Los eventos a los que me refiero son:</p>
<p>El día de ayer en la agencia en donde soy socio (AureaCode) no rechazaron un presupuesto para desarrollar un sitio para una compañía multinacional de mucho éxito (Fabricantes de Tenis ), El trabajo constaba de copiar literalmente el sitio oficial de EEUU. Este sitio consta de, entre lo obvio:</p>
<ul>
<li>Una tienda en linea, (Administrador, y Front-end)</li>
<li>Rastreo de pedido</li>
<li>Pasarela de pago integrada</li>
<li>Creación de crear tu propio tenis</li>
<li>Localización de revendedores cercanos mediante CP</li>
<li>Administrador de Noticias, Eventos</li>
<li>Integración de Blog</li>
<li>Todo lo anterior en Full-Flash</li>
</ul>
<p>Bien, Yo soy el encargado de estimar tiempos de esfuerzo y desarrollo, con esta información llegue a la conclusión de que el proyecto podría ser acabado en 60 días con el esfuerzo de 1 diseñador y 2 programadores, tratando de ajustar a lo menos para no inflar el precio final.</p>
<p>Esto dio como resultado un aproximado de 1440 horas de trabajo, a un coste de US$25 por hora.</p>
<p>Aquí lo que me hizo ruido, no fue que no aceptaran el presupuesto, sino como, diciéndonos que estábamos <em>&#8220;Fuerisisisisima&#8221;</em> del presupuesto literalmente.</p>
<p>Esto me hizo preguntar cuanto tenían de presupuesto, o cuanto les habían cotizado las demás &#8220;<em>Agencias</em>&#8220;.</p>
<p>El siguiente punto fue, que el día de hoy mediante un tweet veo los precios promedio que ofrecen las compañías americanas, entre US$60 y $US75 por hora.</p>
<p>Entonces, somos o nos hacemos.</p>
<p><strong>¿Solo por que estamos un poco mas al sur debemos regalar nuestro trabajo?</strong></p>
<p><strong>¿En verdad en México esta tan mal pagado el desarrollo web?</strong></p>
<p>Quiero hacer una encuesta rápida para ver, de una manera no muy científica <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , como anda en promedio, el costo de desarrollo por hora en LatinoAmerica. Así que por favor tómense un momento para responder, se los agradeceré.</p>
<p style="text-align: center;"><script src="http://twtpoll.com/js/badge.js" type="text/javascript"></script> <script src="http://twtpoll.com/badge/?twt=ecxcja" type="text/javascript"></script></p>
<p>Saludos!</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/06/18/que-tan-subvalorado-es-el-desarrollo-web-en-latinoamerica/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>AWI Evoluciona</title>
		<link>http://klr20mg.com/2009/03/04/awi-evoluciona/</link>
		<comments>http://klr20mg.com/2009/03/04/awi-evoluciona/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 03:08:27 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Awi]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=280</guid>
		<description><![CDATA[Recuerdan aquel proyecto  que es una integración entre WordPress y AMF (Action Message Format ) usando servicios de AMFPHP llamado AWI. Bien, este proyecto se quedo en la versión 2.3, si mal no recuerdo, de WordPress. Ahora desde la lista de correo de desarrollo me entero que se ha creado un fork de AWI haciendo [...]]]></description>
			<content:encoded><![CDATA[<p>Recuerdan aquel <a href="http://klr20mg.com/awi/">proyecto</a>  que es una integración entre WordPress y AMF (Action Message Format ) usando servicios de AMFPHP llamado <a href="http://klr20mg.com/awi/">AWI</a>.</p>
<p>Bien, este proyecto se quedo en la versión 2.3, si mal no recuerdo, de WordPress.</p>
<p>Ahora desde la<a href="http://groups.google.com/group/awi-dev?hl=en"> lista de correo de desarrollo</a> me entero que se ha creado un fork de AWI haciendo una actualización a WordPress 2.7 además de que se agregaron nuevos métodos.</p>
<p>El Fork fue creado por <a href="http://www.noponies.com/">Dale Sattler</a>  que en su<a href="http://www.blog.noponies.com/archives/257"> blog</a> nos cuenta de todos los cambios.</p>
<p class="MsoNormal">Así que ya saben si quieren hacer interfaces en Flash-Flex para WordPress esto es lo que están buscando</p>
<p>Saludos <img src='http://klr20mg.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2009/03/04/awi-evoluciona/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tequila Valley, Punto de encuentro de emprendedores.</title>
		<link>http://klr20mg.com/2008/11/19/tequila-valley/</link>
		<comments>http://klr20mg.com/2008/11/19/tequila-valley/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 19:13:29 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[emprendimiento]]></category>
		<category><![CDATA[mexico]]></category>
		<category><![CDATA[tequila]]></category>
		<category><![CDATA[valley]]></category>
		<category><![CDATA[web2.0]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=227</guid>
		<description><![CDATA[Leyendo mis feeds me entero que ha nacido una nueva Organización/Comunidad Mexicana enfocada al emprendimiento web, Tequila Valley. Sin duda este tipo de proyectos son necesarios y sobre todo útiles para todas aquellas personas que tienen una idea pero no saben cómo iniciar a cómo desarrollarla. Todos aquellos que alguna vez emprendimos un proyecto sabemos [...]]]></description>
			<content:encoded><![CDATA[<div align="center"><a href="http://klr20mg.com/wp-content/uploads/2008/11/tequila-valley.jpg"><img src="http://klr20mg.com/wp-content/uploads/2008/11/tequila-valley.jpg" alt="Tequila-valley" title="tequila-valley" width="520" height="365" class="size-full wp-image-230" /></a></div>
<p>Leyendo mis feeds me entero que ha nacido una nueva Organización/Comunidad Mexicana enfocada al emprendimiento web, <a href="http://www.tequilavalley.com">Tequila Valley</a>.</p>
<p>Sin duda este tipo de proyectos son necesarios y sobre todo útiles para todas aquellas personas que tienen una idea pero no saben cómo iniciar a cómo desarrollarla.</p>
<p>Todos aquellos que alguna vez emprendimos un proyecto sabemos que la idea es solo la base de nuestro proyecto, la forma en cómo ejecutemos dicha idea es lo que asegurara o no el éxito del mismo. Es aquí en donde este tipo de comunidades son realmente valiosas, ya que dentro de ellas obtendrás consejos, tips, asesoramiento de personas que han pasado por lo mismo que tu, recuerda el dicho, “Nadie escarmienta en cabeza ajena”, hombre pero es bueno que te digan por donde ir de vez en cuando ¿no? <img src='http://klr20mg.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>En lo personal, en México conozco <a href="http://cafedealtura.com/">Cafe de Altura</a> , pero el punto que no me convence mucho es que las reuniones son físicas. No hay un foro o algo así que lo apoye (Al menos no he encontrado alguno, perdón si no busque buen), al contrario de <a href="http://www.tequilavalley.com">Tequila Valley</a> en donde desde un inicio encontramos una <a href="http://groups.google.com/group/tequilavalley">lista de correo</a> y un <a href="http://foro.tequilavalley.com/">foro</a>.</p>
<p>Tequila Valley según sus creadores</p>
<p><strong><br />
<h3>¿Qué es Tequila Valley?</h3>
<p></strong></p>
<p><i>Corto y rapidito, con ayuda de varios, he aquí las tres reglas del club:</i></p>
<p><strong><br />
<h3>1. ES UNA AGRUPACIÓN MEXICANA</h3>
<p></strong></p>
<p>Neta, güey. Tequila Valley existe para fomentar nuestra nacionalidad como fuerte de desarrollo. Ojo que esto no quiere decir que tienes que estar pisoteando territorio azteca para poder hacer parte, sino que eres parte del club de mexicanos. Así estés en Tlalpán, Ushuaia, Washington o en el DF.</p>
<p><strong><br />
<h3>2. NO HAY JEFE, PRESIDENTE, DUEÑO, NI ACCIONISTAS (en serio, no insistan)</h3>
<p></strong></p>
<p>Tequila Valley es de todos. Para reunir un evento Tequila Valley no requieres permiso, autorización, visto bueno o carta apostillada del padre Benito, el de la iglesia de la esquina. De hecho, como otras organizaciones de este estilo lo dicen, es sólo un “estado mental”.</p>
<p><strong><br />
<h3>3. NO HAY REGLAS ESCRITAS EN PIEDRA</h3>
<p></strong></p>
<p>No, no las hay. De hecho, todo está abierto a discusión. Los invitamos a ser parte del grupo Google formativo de Tequila Valley, en donde a diario nos golpeamos la cabeza con temas banales como qué tipo de fuente  usar o si el logotipo obedece las leyes de distribución áurea o no.</p>
<p>Fuente : <a href="http://www.maestrosdelweb.com/actualidad/tequila-valley/">Maestros del Web</a><br />
Link del Proyecto: <a href="http://www.tequilavalley.com">Tequila Valley</a></p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/11/19/tequila-valley/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Acceder el Stage desde cualquier clase AS3</title>
		<link>http://klr20mg.com/2008/11/13/acceder-el-stage-desde-cualquier-clase-as3/</link>
		<comments>http://klr20mg.com/2008/11/13/acceder-el-stage-desde-cualquier-clase-as3/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 22:48:06 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Clases]]></category>
		<category><![CDATA[singlenton]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=224</guid>
		<description><![CDATA[Al trabajar con clases AS3 en nuestros proyectos hay ocasiones en los que debemos acceder al stage principal de nuestra aplicación desde clases que no extienden a “DisplayObject”, haciendo que debamos pasar como parámetro dicho stage a las clases, esto funciona pero en realidad es un poco “sucio”. Una solución simple es crear una clase [...]]]></description>
			<content:encoded><![CDATA[<p>Al trabajar con clases AS3 en nuestros proyectos hay ocasiones en los que debemos acceder al stage principal de nuestra aplicación desde clases que no extienden a  “DisplayObject”, haciendo que debamos pasar como parámetro dicho stage a las clases, esto funciona pero en realidad es un poco “sucio”.</p>
<p>Una solución simple es crear una clase singleton, en la cual, podemos almacenar no solo el stage principal, sino cualquier otro valor que necesitemos en varias clases. Algo así como _global de AS2, lo recuerdan?<br />
Aquí la clase</p>
<p>[as]<br />
package net.tmeister.utils<br />
{<br />
	public dynamic class Global<br />
	{<br />
		private static var global : Global</p>
<p>		public static function getInstance() : Global<br />
		{<br />
			if ( global == null )<br />
			{<br />
				global = new Global( arguments.callee );<br />
			}<br />
			return global;<br />
		}</p>
<p>		public function Global( caller : Function = null )<br />
		{<br />
			if ( caller != Global.getInstance )<br />
			{<br />
				throw new Error (&#8220;Global is a singleton class, use getInstance() instead&#8221;);<br />
			}<br />
			if ( Global.global != null )<br />
			{<br />
				throw new Error( &#8220;Only one Global instance should be instantiated&#8221; );<br />
			}<br />
		}<br />
	}<br />
}<br />
[/as]</p>
<p>Y su modo de uso.</p>
<p>[as]<br />
package<br />
{<br />
	import flash.display.MovieClip;<br />
	import net.tmeister.utils.Global<br />
	public class Main extends MovieClip<br />
	{<br />
		private var global:Global;</p>
<p>		public function Main()<br />
		{<br />
			global = Global.getInstance();<br />
			global.stage = stage<br />
			trace(&#8216;global.stage&#8217; + global.stage)<br />
			global.algunOtroValor = new MovieClip()<br />
			trace(&#8216;global.algunOtroValor &#8216; + global.algunOtroValor)<br />
		}<br />
	}<br />
}<br />
[/as]</p>
<p>Simple.</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/11/13/acceder-el-stage-desde-cualquier-clase-as3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Habemus  Flash Player 10 !!</title>
		<link>http://klr20mg.com/2008/10/15/habemus-flash-player-10/</link>
		<comments>http://klr20mg.com/2008/10/15/habemus-flash-player-10/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 17:04:33 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=214</guid>
		<description><![CDATA[Ya está disponible para su descarga la versión 10 de nuestro querido Flash Player, entre las características principales podemos encontrar: Efectos 3D Nativos Filtros y efectos personalizados Soporte de texto avanzado Generación de sonido dinámico Nuevo API de dibujo Aceleración por hardware Nuevo DataType Vector Streaming dinámico Y más más…. Ahora solo falta esperar el [...]]]></description>
			<content:encoded><![CDATA[<p>Ya está disponible para su descarga la versión 10 de nuestro querido Flash Player, entre las características principales podemos encontrar:</p>
<ul>
<li>Efectos 3D Nativos</li>
<li>Filtros y efectos  personalizados</li>
<li>Soporte de texto avanzado </li>
<li>Generación de sonido dinámico</li>
<li>Nuevo API de dibujo</li>
<li>Aceleración por hardware</li>
<li>Nuevo DataType Vector</li>
<li>Streaming dinámico</li>
</ul>
<p>Y más más…. Ahora solo falta esperar el release de FLASH CS4 <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>La información completa la pueden encontrar en la <a href="http://www.adobe.com/products/flashplayer/">página oficial del FlashPlayer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/10/15/habemus-flash-player-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash CS4, A la vuelta de la esquina.</title>
		<link>http://klr20mg.com/2008/10/10/flash-cs4-a-la-vuelta-de-la-esquina/</link>
		<comments>http://klr20mg.com/2008/10/10/flash-cs4-a-la-vuelta-de-la-esquina/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 23:14:09 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=213</guid>
		<description><![CDATA[Como ya sabrán, la nueva suite de Adobe esta por ser lanzada, y para abrir boca, la documentación ya esta disponible. Main help portal http://help.adobe.com/en_US/Flash/10.0_Welcome/ New features http://help.adobe.com/en_US/&#8230;html Programming ActionScript 3.0 http://help.adobe.com/&#8230;./ ActionScript 3.0 Language and Components Reference http://help.adobe.com/en_US/AS3LCR/Flash_10.0/index.html Extending Adobe Flash Professional CS4 http://help.adobe.com/&#8230;/index.html Con esto, sin duda, ya tenemos para entretenernos un bien [...]]]></description>
			<content:encoded><![CDATA[<p>Como ya sabrán, la nueva suite de Adobe esta por ser lanzada, y para abrir boca, la documentación ya esta disponible.</p>
<p><strong>Main help portal</strong><br />
<a href="http://help.adobe.com/en_US/Flash/10.0_Welcome/">http://help.adobe.com/en_US/Flash/10.0_Welcome/</a></p>
<p><strong>New features</strong><br />
<a href="http://help.adobe.com/en_US/Flash/10.0_UsingFlash/WS9F717870-8AED-438d-B324-44ACCE6871E8a.html">http://help.adobe.com/en_US/&#8230;html</a></p>
<p><strong>Programming ActionScript 3.0</strong><br />
<a href="http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/">http://help.adobe.com/&#8230;./</a></p>
<p><strong>ActionScript 3.0 Language and Components Reference</strong><br />
<a href="http://help.adobe.com/en_US/AS3LCR/Flash_10.0/index.html">http://help.adobe.com/en_US/AS3LCR/Flash_10.0/index.html</a></p>
<p><strong>Extending Adobe Flash Professional CS4</strong><br />
<a href="http://help.adobe.com/en_US/Flash/10.0_ExtendingFlash/index.html">http://help.adobe.com/&#8230;/index.html</a></p>
<p>Con esto, sin duda, ya tenemos para entretenernos un bien tiempo.</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/10/10/flash-cs4-a-la-vuelta-de-la-esquina/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Clase TiledBackground</title>
		<link>http://klr20mg.com/2008/07/04/clase-tiledbackground/</link>
		<comments>http://klr20mg.com/2008/07/04/clase-tiledbackground/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 23:00:11 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Background]]></category>
		<category><![CDATA[tiled]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=204</guid>
		<description><![CDATA[Que tal gente. Hace un buen rato que no posteo, pero aquí estoy de vuelta con algo sencillo. TiledBackground es una clase simple la cual toma una imagen externa (jpg, gif, png) y la repite tantas veces quepa en el navegador tal y como lo hiciéramos en CSS Además de que tiene un par de [...]]]></description>
			<content:encoded><![CDATA[<p>Que tal gente. </p>
<p>Hace un buen rato que no posteo, pero aquí estoy de vuelta con algo sencillo.<br />
TiledBackground es una clase simple la cual toma una imagen externa (jpg, gif, png) y la repite tantas veces quepa en el navegador tal y como lo hiciéramos en CSS <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Además de que tiene un par de parámetros, se puede sobreponer un gradiente radial para hacer un efecto sobre el fondo. Los colores y alphas del gradiente se pueden configurar.</p>
<p>TiledBackground<br />
[as]<br />
package net.tmeister.utils.background<br />
{</p>
<p>	import flash.display.BitmapData;<br />
	import flash.display.Loader;<br />
	import flash.display.Sprite;<br />
	import flash.display.Stage;<br />
	import flash.events.Event;<br />
	import flash.geom.Matrix;<br />
	import flash.net.URLRequest;<br />
	import flash.display.StageScaleMode;<br />
	import flash.display.StageAlign;<br />
	import flash.display.GradientType;  </p>
<p>	public class TiledBackground extends Sprite<br />
	{<br />
		private var _pattern:String;<br />
		private var _container:Sprite;<br />
		private var _image:Loader;<br />
		private var _stage:Stage;<br />
		private var _gradient:Boolean = true;<br />
		private var _gProperties:Object = {};</p>
<p>		public function TiledBackground(stage:Stage)<br />
		{<br />
			_stage = stage<br />
			_stage.scaleMode = StageScaleMode.NO_SCALE;<br />
			_stage.align = StageAlign.TOP_LEFT;<br />
			_stage.addEventListener(Event.RESIZE, resize);<br />
		}<br />
		public function set pattern (urlPattern:String):void<br />
		{<br />
			_pattern = urlPattern;<br />
			loadPattern();<br />
		}<br />
		public function get pattern():String<br />
		{<br />
			return _pattern;<br />
		}<br />
		public function set radialGradient(value:Boolean):void<br />
		{<br />
			_gradient = value;<br />
		}<br />
		public function get radialGradient():Boolean<br />
		{<br />
			return _gradient;<br />
		}<br />
		public function set gradientProperties(properties:Object):void<br />
		{<br />
			_gProperties = properties;<br />
		}<br />
		public function get gradientProperties():Object<br />
		{<br />
			return _gProperties;<br />
		}<br />
		private function loadPattern():void<br />
		{<br />
			var patternLoader:Loader = new Loader();<br />
			var patternUrl:URLRequest = new URLRequest(_pattern);<br />
			patternLoader.load(patternUrl);<br />
			patternLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onPatternLoaded);<br />
		}<br />
		private function onPatternLoaded(e:Event):void<br />
		{<br />
			_image = e.target.loader;<br />
			createBackground();<br />
			createRadialGradient()<br />
		}<br />
		private function createBackground():void<br />
		{<br />
			if (_container != null)<br />
			{<br />
				removeChild(_container);<br />
				_container = null;<br />
			}<br />
			var bitmap:BitmapData = new BitmapData (_image.width, _image.height);<br />
			bitmap.draw(_image)<br />
			_container = new Sprite();<br />
			_container.graphics.beginBitmapFill(bitmap);<br />
			_container.graphics.drawRect(0,0, _stage.stageWidth , _stage.stageHeight);<br />
			_container.graphics.endFill();<br />
			addChild(_container);<br />
		}</p>
<p>		private function createRadialGradient():void<br />
		{<br />
			if (! _gradient )<br />
			{<br />
				return;<br />
			}<br />
			var matrix:Matrix = new Matrix();<br />
			var gType:String = GradientType.RADIAL;<br />
			matrix.createGradientBox(_stage.stageWidth,_stage.stageHeight,0,0,0);<br />
			var gColors:Array = [(_gProperties.insideColor) ? _gProperties.insideColor : 0xffffff, (_gProperties.outsideColor) ? _gProperties.outsideColor : 0xffffff];<br />
			var gAlphas:Array = [(_gProperties.insideColorAlpha) ? _gProperties.insideColorAlpha : .15 ,(_gProperties.outsideColorAlpha) ? _gProperties.outsideColorAlpha : 0];<br />
			var gRatio:Array = [0,255];<br />
			var bound:Sprite = new Sprite();<br />
			bound.graphics.beginGradientFill(gType,gColors,gAlphas,gRatio,matrix);<br />
			bound.graphics.drawRect(0,0,_stage.stageWidth,_stage.stageHeight);<br />
			addChild(bound);<br />
		}<br />
		private function resize(e:Event):void<br />
		{<br />
			createBackground();<br />
			createRadialGradient()<br />
		}<br />
	}<br />
}<br />
[/as]<br />
Uso:</p>
<p>[as]<br />
package<br />
{<br />
	import flash.display.Sprite;<br />
	import net.tmeister.utils.background.TiledBackground</p>
<p>	public class sampleTiled extends Sprite<br />
	{<br />
		public function sampleTiled()<br />
		{<br />
			var background:TiledBackground = new TiledBackground(stage);<br />
			background.pattern = &#8220;bg1.gif&#8221;<br />
			background.gradientProperties = {insideColor:0xffffff, outsideColor:0xffffff, insideColorAlpha:.05, outsideColorAlpha:0}<br />
			addChild(background)<br />
		}<br />
	}<br />
}<br />
[/as]</p>
<p><a href="http://klr20mg.com/tiled/">Aquí el ejemplo</a> y como siempre los archivos fuente están disponibles.</p>
<div class="legend">
<h3 class="legend-title">Archivos para descarga</h3>
<table>
<tr>
<td><div style="width: 200px; margin: 10px; text-align: center">
	<p><a rel="nofollow" title="Download version 0.1 of TiledBackground.zip" href="http://klr20mg.com/downloads/TiledBackground.zip"><img src="http://klr20mg.com/wp-content/plugins/drain-hole/images/download.png" alt="download" width="128" height="128"/></a></p>

	<table class="download">
		<tr>
			<th>Download:</th>
			<td><a rel="nofollow" title="Download version 0.1 of TiledBackground.zip" href="http://klr20mg.com/downloads/TiledBackground.zip">TiledBackground.zip</a></td>
		</tr>
		<tr>
			<th>Version:</th>
			<td>0.1</td>
		</tr>
		<tr>
			<th>Updated:</th>
			<td>July 4, 2008</td>
		</tr>
		<tr>
			<th>Size:</th>
			<td>12.42 KB</td>
		</tr>
	</table>
</div>
</td>
</tr>
</table>
</div>
<p>Saludos!! </p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/07/04/clase-tiledbackground/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Obteniendo los hijos de un DisplayObject [AS3]</title>
		<link>http://klr20mg.com/2008/04/01/obteniendo-los-hijos-de-un-displayobject-as3/</link>
		<comments>http://klr20mg.com/2008/04/01/obteniendo-los-hijos-de-un-displayobject-as3/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 20:51:28 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Clases]]></category>
		<category><![CDATA[DisplayObject]]></category>
		<category><![CDATA[Utils]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=201</guid>
		<description><![CDATA[Está en una clase simple pero muy útil, al menos para mí, que recorre todos los hijos contenidos en un DisplayObject, la clase cuenta con 2 funciones: getAllChilds Regresa todos los hijos contenidos en el “target” getChildsByType Regresa solo los hijos que sean de un tipo específico, por ejemplo solo MovieClips, o solo Botones. DisplayObjectUtils [...]]]></description>
			<content:encoded><![CDATA[<p>Está en una clase simple pero muy útil, al menos para mí, que recorre todos los hijos contenidos en un DisplayObject, la clase cuenta con 2 funciones:</p>
<p><strong>getAllChilds</strong></p>
<p>Regresa todos los hijos contenidos en el “target”</p>
<p><strong>getChildsByType</strong></p>
<p>Regresa solo los hijos que sean de un tipo específico, por ejemplo solo MovieClips, o solo Botones.</p>
<h2>DisplayObjectUtils</h2>
<p>[as]<br />
package net.tmeister.utils<br />
{<br />
	/**<br />
	 * @author Enrique Chavez aka Tmeister<br />
	 */<br />
	import flash.display.DisplayObject;<br />
	public class DisplayObjectUtils<br />
	{<br />
		/**<br />
		 *<br />
		 * @param	target<br />
		 * @return Array<br />
		 */<br />
		public static function getAllChilds(target:*):Array<br />
		{<br />
			var listTmp:Array = []<br />
			for (var a = 0; a < target.numChildren; a++ )<br />
			{<br />
				listTmp.push (target.getChildAt(a) )<br />
			}<br />
			return listTmp<br />
		}<br />
		/**<br />
		 *<br />
		 * @param	target<br />
		 * @param	type<br />
		 * @return<br />
		 */<br />
		public static function getChildsByType(target:*, type:*):Array<br />
		{<br />
			var listTmp:Array = []<br />
			for (var a = 0; a < target.numChildren; a++ )<br />
			{<br />
				if (target.getChildAt(a) is type)<br />
				{<br />
					listTmp.push (target.getChildAt(a) )<br />
				}<br />
			}<br />
			return listTmp<br />
		}<br />
	}<br />
}<br />
[/as]</p>
<p>Su uso es el siguiente:</p>
<p>Primero creamos unos Movieclips y unos botones para tener algo que buscar.</p>
<p>[as]<br />
import net.tmeister.utils.DisplayObjectUtils;<br />
import fl.controls.Button</p>
<p>createMovieClips()<br />
createButtons()<br />
getChilds()</p>
<p>function createButtons()<br />
{<br />
	for(var a:Number = 0; a<2; a++)<br />
	{<br />
		var tmp:Button = new Button();<br />
		tmp.x = Math.random()*400<br />
		tmp.y = Math.random()*400<br />
		tmp.label = &#8220;buton&#8221;+a<br />
		addChild(tmp)<br />
	}<br />
}<br />
function createMovieClips()<br />
{<br />
	for(var a:Number = 0; a<5; a++)<br />
	{<br />
		var tmp:MovieClip = new MovieClip();<br />
		tmp.graphics.beginFill(0x2a2a2a, .5)<br />
		tmp.graphics.drawRect(Math.random()*500, Math.random()*300, Math.random()*100, Math.random()*100);<br />
		tmp.graphics.endFill();<br />
		tmp.name = &#8220;mc&#8221;+a;<br />
		addChild(tmp)<br />
	}<br />
}<br />
function getChilds()<br />
{<br />
	trace(&#8220;All Childs: &#8221; + DisplayObjectUtils.getAllChilds(this) )<br />
	trace(&#8220;=====================================================================================&#8221;)<br />
	trace(&#8220;Movieclips:  &#8221; + DisplayObjectUtils.getChildsByType(this, MovieClip))<br />
	trace(&#8220;=====================================================================================&#8221;)<br />
	trace(&#8220;Buttons:  &#8221; + DisplayObjectUtils.getChildsByType(this, Button))</p>
<p>}</p>
<p>[/as]</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/04/01/obteniendo-los-hijos-de-un-displayobject-as3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Advanced round class AS3</title>
		<link>http://klr20mg.com/2008/03/31/advanced-round-as3/</link>
		<comments>http://klr20mg.com/2008/03/31/advanced-round-as3/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 01:06:02 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Clases]]></category>
		<category><![CDATA[Math]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=200</guid>
		<description><![CDATA[Esta es una clase de mucha ayuda para cuando queramos redondear números de una forma más avanzada. AS3 cuenta con su Math.round pero esta función lo único que hace es redondear el numero al entero más cercano. Pero qué pasa si quiero redondear un número en múltiplos de 5 por ejemplo. Para ello escribí esta [...]]]></description>
			<content:encoded><![CDATA[<p>Esta es una clase de mucha ayuda para cuando queramos redondear números de una forma más avanzada.</p>
<p>AS3 cuenta con su Math.round pero esta función lo único que hace es redondear el numero al entero más cercano. Pero qué pasa si quiero redondear un número en múltiplos de 5 por ejemplo.</p>
<p>Para ello escribí esta sencilla clase que lo permite.</p>
<p>[as]<br />
package net.tmeister.utils<br />
{<br />
	/**<br />
	 *<br />
	 * Advanced Round Class<br />
	 * @version 0.1<br />
	 * @author Enrique Chavez aka Tmeister<br />
	 *<br />
	*/<br />
	public class MathUtils<br />
	{<br />
		/**<br />
		 *<br />
		 * Rounds a Number to the nearest multiple<br />
		 * @param	number Number to Round<br />
		 * @param	precision multiple to be rounded<br />
		 * @return 	A number round<br />
		 *<br />
		 */<br />
		public static function roundToNear(number:Number, precision:Number)<br />
		{<br />
			return Math.round( number / precision) * precision;<br />
		}<br />
		/**<br />
		 *<br />
		 * Rounds a Number up to the nearest multiple<br />
		 * @param	number Number to Round<br />
		 * @param	precision multiple to be rounded<br />
		 * @return 	A number Up round<br />
		 *<br />
		 */<br />
		public static function roundToUpNear(number:Number, precision:Number)<br />
		{<br />
			return Math.ceil( number / precision) * precision;<br />
		}<br />
		/**<br />
		 *<br />
		 * Rounds a Number down to the nearest multiple<br />
		 * @param	number number Number to Round<br />
		 * @param	precision multiple to be rounded<br />
		 * @return 	A number down round<br />
		 *<br />
		 */<br />
		public static function roundToDownNear(number:Number, precision:Number)<br />
		{<br />
			return Math.floor( number / precision) * precision;<br />
		}<br />
	}<br />
}<br />
[/as]</p>
<p>Modo de uso es tan simple como esto.</p>
<p>[as]<br />
import net.tmeister.utils.MathUtils;</p>
<p>const number:Number = 38<br />
const precision:Number = 5</p>
<p>trace(MathUtils.roundToNear(number, precision)) // 40<br />
trace(MathUtils.roundToUpNear(number, precision)) // 40<br />
trace(MathUtils.roundToDownNear(number, precision)) // 35<br />
[/as]</p>
<p>Enjoy <img src='http://klr20mg.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/03/31/advanced-round-as3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PureMVC :: ValueObjects</title>
		<link>http://klr20mg.com/2008/03/26/puremvc-valueobjects/</link>
		<comments>http://klr20mg.com/2008/03/26/puremvc-valueobjects/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 05:34:09 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[AMFPHP]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PureMVC]]></category>
		<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=199</guid>
		<description><![CDATA[Los ValueObjects son indispensables al momento de trabajar con MVC o sin el . Voy a tratar hacer una definición de los ValueObjects sin ser muy técnico. de ahora en adelante al usar VO me estaré refiriendo a los ValueObjects. Los puntos mas importantes de los VO son: Los VO son contenedores de información representada [...]]]></description>
			<content:encoded><![CDATA[<p>Los ValueObjects son indispensables al momento de trabajar con MVC o sin el <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Voy a tratar hacer una definición de los ValueObjects sin ser muy técnico. de ahora en adelante al usar VO me estaré refiriendo a los ValueObjects. Los puntos mas importantes de los VO son:</p>
<ol>
<li>Los VO son contenedores de información representada por una clase individual.</li>
<li>Los VO son serializables, es decir, pueden ser enviados entre un servidor y un cliente mantenido sus propiedades.</li>
</ol>
<p>Imaginemos que vamos a hacer un listado de mensajes para un guestbook, pero no sabemos quien, que o como nos van a proveer la información, lo único sabemos son los atributos que contendrá cada mensaje, estos son:</p>
<ul class="stars">
<li>idUnique</li>
<li>author</li>
<li>url</li>
<li>content</li>
</ul>
<p>Los mensajes siempre contendrán estas propiedades vengan de donde vengan.</p>
<p>Según el punto 1 esta información es representada por una clase individual entonces como nuestro cliente será hecho el FLEX creamos nuestro clase en AS3 la cual representara nuestros VO en el cliente.</p>
<p>[as]</p>
<p>package com.klr20mg.pureMVC.guestbook.model.vo<br />
{<br />
    [RemoteClass(alias="MessagesVO")]<br />
    [Bindable]<br />
    public class MessagesVO<br />
    {<br />
        public var idUnique:String;<br />
        public var author:String;<br />
        public var url:String;<br />
        public var content:String;<br />
        public function MessagesVO(author:String=null, url:String=null, content:String=null)<br />
        {<br />
            this.idUnique = &#8220;&#8221;<br />
            this.author = author;<br />
            this.url = url;<br />
            this.content = content;<br />
        }<br />
    }<br />
}</p>
<p>[/as]</p>
<p>Hay 2 formas comunes de &#8220;poblar&#8221; los VO mediante el constructor, como en este ejemplo o mediante getters y setters, yo prefiero la primera.</p>
<p>Ahora vamos crear un VO a partir de la clase anterior</p>
<p>[as]</p>
<p>package com.klr20mg.pureMVC.guestbook<br />
{<br />
    import com.klr20mg.pureMVC.guestbook.model.vo.MessagesVO<br />
    public class someClass<br />
    {<br />
        public function someClass()<br />
        {<br />
            var miVO:MessagesVO = new MessagesVO(&#8220;Tmeister&#8221;, &#8220;http://tmeister.net&#8221;, &#8220;Este es un mensaje de prueba&#8221;);<br />
            trace(miVO)<br />
        }<br />
    }<br />
}</p>
<p>[/as]</p>
<p>Con esto hemos creado un VO de acuerdo a la primera clase.</p>
<p>Los VO son &#8220;compatibles&#8221; entre el cliente y el servidor según el punto numero 2, y al usar AMFPHP, WebOrb entre otros podemos enviar arrays de VO&#8217;s entre el server y el cliente sin ningún problema, pero entonces debemos de crear nuestros VO&#8217;s en el servidor en este caso usando PHP para poder &#8220;mapear&#8221; esta información.</p>
<pre class="brush: php;">

&lt;?php
class MessagesVO
{
    public $idUnique;
    public $author;
    public $url;
    public $content; 

    public function MessagesVO()
    {
    }
    public function mapObject($data)
    {
        $this-&gt;idUnique = $data[&quot;idUnique&quot;];
        $this-&gt;author = $data[&quot;author&quot;];
        $this-&gt;url = $data[&quot;url&quot;];
        $this-&gt;content = $data[&quot;content&quot;];
    }
}
?&gt;
</pre>
<p>Como pueden ver es el mismo concepto encapsular la información en una clase.</p>
<p>Con esto, repito, no importa si la información viene de archivos de texto, de un webservice, de una base de datos, siempre podremos almacenar, consultar y modificar la información mediante nuestros VO&#8217;s.</p>
<p>Espero que con esto quede claro que son y para que usan los ValueObjects</p>
<p>Saludos <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/03/26/puremvc-valueobjects/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Introducción a PureMVC</title>
		<link>http://klr20mg.com/2008/03/19/introduccion-a-puremvc/</link>
		<comments>http://klr20mg.com/2008/03/19/introduccion-a-puremvc/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 22:15:53 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PureMVC]]></category>
		<category><![CDATA[Tutoriales]]></category>

		<guid isPermaLink="false">http://klr20mg.com/2008/03/19/introduccion-a-puremvc/</guid>
		<description><![CDATA[La Teoría PureMVC es un framework open source que implementa el modelo MVC para crear aplicaciones usando ActionScript 3 bajo Flash CS3 y Flex, creado originalmente por Cliff Hall . Dentro de los planes de desarrollo podemos encontrar que se intenta implementar este framework en diversos lenguajes de programación, tales como: ActionScript 2 ColdFusion CSharp [...]]]></description>
			<content:encoded><![CDATA[<h1>La Teoría</h1>
<p>PureMVC es un framework open source que implementa el modelo MVC para crear aplicaciones usando ActionScript 3 bajo Flash CS3 y Flex, creado originalmente por <a href="http://puremvc.org/component/option,com_contact/Itemid,3/">Cliff Hall</a> .</p>
<p>Dentro de los planes de desarrollo podemos encontrar que se intenta implementar este framework en diversos lenguajes de programación, tales como:</p>
<ul class="stars">
<li>ActionScript 2</li>
<li>ColdFusion</li>
<li>CSharp</li>
<li>Java</li>
<li>Perl</li>
<li>PHP</li>
<li>Python</li>
<li>Ruby</li>
</ul>
<p>Al implementar el patrón MVC (Modelo-Control-Vista) podemos separar los datos de la aplicación, las vistas (Interfaz de usuario) y la lógica de control en tres &#8220;componentes&#8221;, para poder reutilizar código y sobre todo hacer nuestras aplicaciones escalabres y mantenibles.</p>
<p>PureMVC separa estos 3 componentes en 3 &#8220;actores&#8221; dentro del framework:</p>
<ul class="stars">
<li>Proxies</li>
<li>Mediators</li>
<li>Commands</li>
</ul>
<p>En donde:</p>
<p>Los datos, remotos o locales son manejados por los Proxies.<br />
Las vistas o interfaz de usuario, son manejados por los Mediators.<br />
La lógica de la aplicación es manejada por los Commands los cuales pueden interactuar con los Proxies, los Mediators y pueden activar o ejecutar otros Commands.</p>
<p>Existe un cuarto elemento en PureMVC llamado Facade el cual provee una interfaz simple de comunicación para que los 3 actores principales puedan comunicarse entre sí. Además de que PureMVC implementa un esquema de notificaciones (Eventos) mediante los cuales se puede activar/ejecutar una o varias acciones.</p>
<p><span id="more-190"></span></p>
<h1>La Práctica Hello PureMVC</h1>
<div align="center">

<object width="640" height="546">
<param name="movie" value="http://www.klr20mg.com/video/introPureMvc/introPureMvc.swf"></param>
<param name="quality" value="high"></param>
<param name="wmode" value="window"></param>
<param name="menu" value="false"></param>
<param name="bgcolor" value="#2a2a2a"></param>
<param name="allowFullScreen" value="true"></param>
<embed type="application/x-shockwave-flash" width="640" height="546" src="http://www.klr20mg.com/video/introPureMvc/introPureMvc.swf" quality="high" bgcolor="#2a2a2a" wmode="window" menu="false" allowFullScreen="true" ></embed>
</object>

</div>
<p>Wow. Tanto para solo un Hello World? No siempre trabajar con frameworks significa menos código, además la potencia de estos frameworks se nota al trabajar en aplicaciones medianas-grandes, yo recomiendo usarlo y ustedes mismos verán las ventajas.</p>
<p>En fin espero les sea útil, además de decir que este es el primer video-tutorial de Klr20mg, que piensan al respecto, seguimos con los tutos escritos o seguimos con video?</p>
<p>Enjoy <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Enlaces:</h2>
<p> <a href="http://puremvc.org/">PureMVC Home</a>, <a href="http://puremvc.org/content/view/50/1/">Download PureMVC</a></p>
<h4>Download Sources</h4>
<div class="legend">
<h3 class="legend-title">Files</h3>
<div style="width: 200px; margin: 10px; text-align: center">
	<p><a rel="nofollow" title="Download version 0.1 of HelloPureMVC.zip" href="http://klr20mg.com/downloads/HelloPureMVC.zip"><img src="http://klr20mg.com/wp-content/plugins/drain-hole/images/download.png" alt="download" width="128" height="128"/></a></p>

	<table class="download">
		<tr>
			<th>Download:</th>
			<td><a rel="nofollow" title="Download version 0.1 of HelloPureMVC.zip" href="http://klr20mg.com/downloads/HelloPureMVC.zip">HelloPureMVC.zip</a></td>
		</tr>
		<tr>
			<th>Version:</th>
			<td>0.1</td>
		</tr>
		<tr>
			<th>Updated:</th>
			<td>March 21, 2008</td>
		</tr>
		<tr>
			<th>Size:</th>
			<td>285.13 KB</td>
		</tr>
	</table>
</div>

</div>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2008/03/19/introduccion-a-puremvc/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Nuevo Hosting</title>
		<link>http://klr20mg.com/2006/11/21/nuevo-hosting/</link>
		<comments>http://klr20mg.com/2006/11/21/nuevo-hosting/#comments</comments>
		<pubDate>Wed, 22 Nov 2006 04:53:26 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>

		<guid isPermaLink="false">http://s6002.gridserver.com/?p=137</guid>
		<description><![CDATA[Si estas leyendo este post es porque los DNS de nuestro nuevo hosting ya están esparcidos por la red =). El cambio fue debido en mucha medida para poder contar de las bondades de php5, Ruby on Rails, entre otras cosas. Con PHP5 ahora podre probar finalmente weborb junto con Flex o con el alpha [...]]]></description>
			<content:encoded><![CDATA[<p>Si estas leyendo este post es porque los DNS de nuestro nuevo hosting ya están esparcidos por la red =).</p>
<p style="margin-bottom: 0cm">El cambio fue debido en mucha medida para poder contar de las bondades de php5, Ruby on Rails, entre otras cosas. Con PHP5 ahora podre probar finalmente weborb junto con Flex o con el alpha de Flash 9.</p>
<p style="margin-bottom: 0cm">Ahora los dominios de <a target="_blank" href="http://www.tmeister.net">tmeister.net</a> y de klr20mg.com están hospedados en <a target="_blank" href="http://www.mediatemple.net">mediatemple</a>.</p>
<p style="margin-bottom: 0cm">PD. Todos los archivos de ejemplo, flas y zips fueron migrados (según yo) bien. <img src='http://klr20mg.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  pero si encuentran algún problema con los links por favor no duden en avisarme.</p>
<p style="margin-bottom: 0cm">Nos estamos viendo.. <img src='http://klr20mg.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2006/11/21/nuevo-hosting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Clase Config (Parsear archivos de configuración)</title>
		<link>http://klr20mg.com/2006/10/14/clase-config-parsear-archivos-de-configuracion/</link>
		<comments>http://klr20mg.com/2006/10/14/clase-config-parsear-archivos-de-configuracion/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 02:43:02 +0000</pubDate>
		<dc:creator>Tmeister</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Clases AS2]]></category>

		<guid isPermaLink="false">http://klr20mg.com/?p=129</guid>
		<description><![CDATA[En muchas ocasiones cuando se nos encarga una aplicación dinámica en flash siempre hay un problema al momento de que el cliente cambie los valores de configuración de dicha aplicación mucho mas cuando este ultimo no quiere pagar por una interfaz de configuración =). Para nosotros como desarrolladores no es nada del otro mundo poder [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm">En muchas ocasiones cuando se nos encarga una aplicación dinámica en flash siempre hay un problema al momento de que el cliente cambie los valores de configuración de dicha aplicación mucho mas cuando este ultimo no quiere pagar por una interfaz de configuración =).</p>
<p style="margin-bottom: 0cm">Para nosotros como desarrolladores no es nada del otro mundo poder cambiar los valores de un XML pero esto cambia cuando el cliente final sera el encargado de modificar dicho archivo. Cuando decimos XML se quedan con cara de &#8216;ehhh? Y eso con que se come&#8217;, repito si el cliente no quiere pagar por una interfaz de administración y quiere poder cambiar algunos valores de la aplicación lo mejor es que se le de un archivo de configuración en texto plano.</p>
<p style="margin-bottom: 0cm">Ustedes pensaran que para ello podemos usar loadVars con las variables declaradas, el problema, de nuevo desde el punto de vista del cliente final es complicado ya que este debe tener un formato y ademas de que no podemos poner comentarios en el.</p>
<p style="margin-bottom: 0cm">Jugando por ahí con Python me encontré con el modulo Config que carga y parsea un archivo de configuración estándar. A que me refiero con archivo de configuración estándar?</p>
<p style="margin-bottom: 0cm">El típico archivo que utilizan los programas en linux, por ejemplo apache. Si nunca han visto este tipo de archivos así es como se ve.</p>
<p>###########################################<br />
### This is a sample of a Config file config.txt<br />
### Author: Enrique Chavez aka Tmeister<br />
### Site: http:www.klr20mg.com<br />
### Date: Oct, 14 2006<br />
###########################################</p>
<p>###########################################<br />
### The images path<br />
###########################################</p>
<p>pathImages path/to/folder/</p>
<p>###########################################<br />
### The gallery&#8217;s name<br />
###########################################</p>
<p>GalleryName this is my test gallery</p>
<p>###########################################<br />
### Your Firstname<br />
###########################################</p>
<p>firstname = Enrique</p>
<p>###########################################<br />
###Your Lastname<br />
###########################################</p>
<p>lastname Chavez</p>
<p>###########################################<br />
###Your Nick =)<br />
###########################################</p>
<p>nick Tmeister</p>
<p># End File</p>
<p style="margin-bottom: 0cm">Bueno, He creado una sencilla clase que se encarga de parsear este tipo de archivos pudiendo acceder a los valores de las variables de una forma simple.</p>
<p style="margin-bottom: 0cm">Tomando como ejemplo el archivo de configuración anterior, lo único que tenemos que hacer en nuestra clase o Fla es algo así..</p>
<p>[as]<br />
import org.utils.Config<br />
import mx.utils.Delegate<br />
class myApp extends MovieClip<br />
{<br />
	private var config : Config;<br />
	function myApp ()<br />
	{<br />
	}<br />
	function onLoad ()<br />
	{<br />
		config = new Config (&#8220;config.txt&#8221;);<br />
		config.addEventListener (&#8220;fault&#8221;, Delegate.create (this, onFault));<br />
		config.addEventListener (&#8220;complete&#8221;, Delegate.create (this, onComplete));<br />
	}<br />
	private function onComplete (obj : Object)<br />
	{<br />
		trace (config.read (&#8220;pathImages&#8221;))<br />
		for (var i in config.list)<br />
		{<br />
			trace (&#8216;key: &#8216; + i + &#8216;, value: &#8216; + config.list [i]);<br />
		}<br />
	}<br />
	private function onFault (obj : Object)<br />
	{<br />
		for (var i in obj) trace (&#8216;key: &#8216; + i + &#8216;, value: &#8216; + obj [i]);<br />
	}<br />
}<br />
[/as]</p>
<p style="margin-bottom: 0cm">Con esto obtenemos algo así:</p>
<p>path/to/folder/<br />
key: nick, value: Tmeister<br />
key: lastname, value: Chavez<br />
key: firstname, value: Enrique<br />
key: GalleryName, value: this is my test gallery<br />
key: pathImages, value: path/to/folder/</p>
<p>Como pueden ver al instaciar la clase se le pasa como parámetro el path del archivo de configuración. Esta clase cuenta con 2 dispatchs, fault y complete los nombres son mas que descriptivos cierto? <img src='http://klr20mg.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Por ultimo hay 2 métodos </p>
<p><strong>read</strong> que regresa el valor de la variable que se pasa como parámetro y<br />
<strong>list </strong>que regresa un objeto con todas las variables del archivo de configuración</p>
<p>Por ultimo la clase Config</p>
<p>[as]<br />
import mx.events.EventDispatcher;<br />
import mx.utils.Delegate<br />
 [Event("complete")]<br />
 [Event("fault")]<br />
class org.utils.Config<br />
{<br />
	private var cfgFile : String<br />
	private var cfg_lv : LoadVars<br />
	public var addEventListener : Function<br />
	private var dispatchEvent : Function;<br />
	private var token : Object<br />
	public var configList : Object<br />
	public function Config (getFile : String)<br />
	{<br />
		EventDispatcher.initialize (this);<br />
		cfgFile = getFile;<br />
		loadConfig ();<br />
	}<br />
	private function loadConfig ()<br />
	{<br />
		cfg_lv = new LoadVars ();<br />
		cfg_lv.load (cfgFile);<br />
		cfg_lv.onLoad = Delegate.create (this, parseCfg);<br />
	}<br />
	private function parseCfg (ok)<br />
	{<br />
		if ( ! ok)<br />
		{<br />
			dispatchEvent (<br />
			{<br />
				type : &#8220;fault&#8221;, msg : &#8220;Cant load file &#8221; + cfgFile<br />
			});<br />
			return<br />
		}<br />
		var data : String = unescape (cfg_lv.toString ())<br />
		data = data.split (&#8220;=&#038;onLoad=[type Function]&#8220;).join (&#8220;&#8221;)<br />
		data = data.split (&#8220;&#038;onLoad=[type Function]&#8220;).join (&#8220;&#8221;)<br />
		var lines : Array = data.split (&#8220;\n&#8221;)<br />
		var count : Number = 0;<br />
		token = {<br />
		};<br />
		configList = {<br />
		}<br />
		while (lines [count])<br />
		{<br />
			var actualLine = lines [count ++]<br />
			var firstCharacter : String = escape (actualLine.substr (0, 1));<br />
			if (firstCharacter != &#8220;%23&#8243; &#038;&#038; firstCharacter != &#8220;%0D&#8221; &#038;&#038; firstCharacter != &#8221; &#8220;)<br />
			{<br />
				var finalLine = actualLine.split (&#8220;\r&#8221;).join (&#8220;&#8221;)<br />
				var values : Array = finalLine.split (&#8221; &#8220;);<br />
				var finalValue : String = &#8220;&#8221;;<br />
				for (var i : Number = 1; i < values.length; i ++)<br />
				{<br />
					finalValue += values [i] + " ";<br />
				}<br />
				finalValue = finalValue.substr (0, - 1)<br />
				token [values [0]] = finalValue<br />
				configList [values [0]] = finalValue<br />
			}<br />
		}<br />
		dispatchEvent (<br />
		{<br />
			type : "complete"<br />
		});<br />
	}<br />
	public function read (variable : String) : String<br />
	{<br />
		return token [variable]<br />
	}<br />
	public function get list () : Object<br />
	{<br />
		return configList;<br />
	}<br />
}<br />
[/as]</p>
<p>Los archivos Fuente. <a href="http://klr20mg.com/archivos/config.zip">http://klr20mg.com/archivos/config.zip</a></p>
<p style="margin-bottom: 0cm">Estoy totalmente convencido que la mejor manera para manejar nuestras configuraciones en Flash sigue y seguirá siendo un archivo XML, pero para aquellos necesiten un archivo de texto plano que sirva como archivo de configuración simple con comentarios para los clientes necios jeje esta clase puede ser de utilidad.</p>
<p style="margin-bottom: 0cm">Saludos!!</p>
]]></content:encoded>
			<wfw:commentRss>http://klr20mg.com/2006/10/14/clase-config-parsear-archivos-de-configuracion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
