« Codebeach | Inicio | Aptana »

VoodooFlash

El ActionScript sigue siendo, por desgracia, y salvo que el rodaje de AS3 demuestre lo contrario, un 80% de programación y un 20% de vudú. Y eso con suerte.

Véase el siguiente ejemplo (reducido hasta la mayor simplicidad a efectos prácticos). Lo que se pretende es escribir un cliente de IRC en AS2. Tras un par de días de pruebas desesperantes, no se consigue abrir un socket con el servidor: medio día de eliminación de código, hasta dejarlo en el puro varillaje, lleva a esta conclusión:

import mx.utils.Delegate
class IRCFacade
{
   function IRCFacade( )
   {
   }

   public function connect( server: String , port: Number )
   {
      var socket: XMLSocket = new XMLSocket( );
      socket.onConnect = Delegate.create( this, onConnect);
      socket.connect( server, port );
   }

   private function onConnect( )
   {
      trace( "socket abierto" );
   }
}

Si desde la línea de tiempo principal de un fla vacío se hace:

var facade: IRCFacade = new IRCFacade( );
facade.connect( "server.server.server", 7000 );

No salta el evento onConnect.

Sin embargo, si se modifica la clase IRCFacade de la siguiente forma:

import mx.utils.Delegate
class IRCFacade
{
   private var socket: XMLSocket;

   function IRCFacade( )
   {
      socket= new XMLSocket( );
   }

   public function connect( server: String , port: Number )
   {
      socket.onConnect = Delegate.create( this, onConnect);
      socket.connect( server, port );
   }

   private function onConnect( )
   {
      trace( "socket abierto" );
   }
}

Oh, sorpresa, todo funciona como se espera. Estupendo. Me lo expliquen.

Comentarios

Hola Cesar,

Yo ya he visto cosas de estas raras y al final lo que hago es que todos los objetos que tienen eventos los declaro globalmente.

No se si sirve de algo, pero me hace sentir mejor....

Hola Cesar, el problema esta en que la variable socket es local a la funcion y no a la clase, por lo que luego de la llamada la variable se borra y la referencia al objeto de la variable tambien, por lo que nunca se va a conectar y es por ese motivo que hace falta declararlo como variable de instancia... fijate q si usas XML, tambien sucede lo mismo.

Una forma de solucionarlo sin tener q declarar la variable como variable de instancia, es devolviendo el valor desde la funcion y guardando su referencia fuera da la clase, o sea, por algun lado de la linea de tiempo...

Saludos!

Hola Andrés,

No creo que ése sea el problema. La variable es local al método connect, efectivamente, pero en el contexto de ese método se le debería poder registrar cualquier listener.

De hecho con otros objetos como XML o XMLLoader sí funciona...

Voodoo.
Mi parte favorita es cuando algo te da error al compilar, lo cortas, lo vuelves a pegar en el mismo sitio y deja de dar error.
Voodoo!!!!!!!!!!!

Dios mío. DN is back... (Disculpen el comentario intrascendente)

Cielos, nunca pida Vd disculpas por un comentario intrascendente...

Buenas!

Yo he visto algo parecido con el objeto LocalConnection mientras picaba mi ZLog.

Lo que yo creo que pasa es que al declarar el objeto XML como local a la funcion, el GC lo elimina cuando la funcion ha terminado. No soy ningun crack de GC, pero diria que NO hay nada apuntando a ese objeto, por lo que esta bien borrado. Y como el onConnect es asincrono... pues no llega nada.

Ya digo que pasa lo mismo con el onStatus de LocalConnection.

Estas cositas que te hacen perder

Imagino que sí, que se debe ser algo así, pero la verdad es que al registrarse al onConnect. sí que debería quedar una referencia a ese objeto, y no debería eliminarse, creo


I think that you are missing the "addEventListener" and on the first example your socket var gets killed before the connection could be stablished since the function ends it´s run.


http://www.actionscript.org/resources/articles/205/1/The-Delegate-Class/Page1.html

just a thought
greetings

Publicar un comentario

(Si no dejó aquí ningún comentario anteriormente, quizás necesite aprobación por parte del dueño del sitio, antes de que el comentario aparezca. Hasta entonces, no se mostrará en la entrada. Gracias por su paciencia).