OOP: Mejorando el rendimiento.

Autor: Buty
Cuando uno trabaja en proyectos de mediana-gran envergadura, hay que prestar especial cuidado en el rendimiento final de nuestra aplicación o sitio hecho en Flash. Sobre todo con los onEnterFrames o setInterval.

En esta ocasión, vamos a dejar un poco de lado a los intervalos, y nos vamos a ocupar de los onEnterFrame. Vamos a implementar una clase siguiendo el patrón Singleton y el patrón Observer, de forma que haya un único onEnterFrame en la película, pudiéndose suscribir y borrar de la suscripción los movieclips que deseemos/necesitemos. De esta forma no se nos queda ningún onEnterFrame suelto por hay, vamos allá.


La idea la ví­ a raiz de un post de Carlos Rovira. Este chico había portado las librería famosa de tween de Laco a as2. Pero había más. Había desarrollado una clase que implementaba un único onEnterFrame para mejorar el rendimiento. Pero cuando me decidí­ a probarlo, me resultó muy incómodo el método que utilizaba para suscribirse/borrarse al/del onEnterFrame. Así­ que decidí­ aparcarlo. Pero últimamente he trabajado en un proyecto, donde el motor de renderización requiere bastante optimización para que la cosa quede bonita. Así­ que me dicidí­ a desarrollar mi propia clase EnterFrameSingleton, siguiendo el mismo patrón Singleton, pero además implementando un patrón Observer, de forma que suscribirse o borrarse resultara más cómodo. El resultado de la clase es este:

Actionscript:
  1. import mx.utils.Delegate;
  2.  
  3. class util.EnterFrameSingleton{
  4. private static var _s:EnterFrameSingleton = null;
  5. // Referencia a los _listeners.
  6. private var _listeners : Array;
  7. // onEnterFrame wrapper
  8. private var tweenHolder:MovieClip;

Definimos las variables de la clase. Como en todo patrón Singleton, una variable que nos indica si ya existe una instancia de la clase definida, de forma que tan solo exista una única instancia de las misma. De la misma forma, para implementar el patrón Observer, definimos un array de listeners donde almacenaremos referencias a los movieclips suscritos. Y por último un movieclip sobre el que ejecutar un onEnterFrame.

Actionscript:
  1. private function EnterFrameSingleton (){
  2. trace("constructor Observable");
  3. _listeners = new Array ();
  4. tweenHolder=_root.createEmptyMovieClip ("_$ingletonObservable", 8020);
  5. tweenHolder.onEnterFrame = Delegate.create (this, update);
  6. }
  7. public static function getSingleton():EnterFrameSingleton {
  8. if (_s == null) {
  9. trace("creando Singleton");
  10. _s = new EnterFrameSingleton();
  11. } else {
  12. trace("Singleton ya creado");
  13. }
  14. return _s;
  15. }

El constructor crea el movieclip, inicializa el array de listeners y asigna una función al onEnterFrame del clip creado: update. esta función es una de las principales, ya que se encarga de transmitir el "evento" a todos los movieclips suscritos. El constuctor en el patrón Singletón es privado y se accede por el método estático getSingleton, que nos devuelve una referencia de la clase misma. Podéis encontrar mucha más referencia sobre el patrón Singleton en internet, y en el libro de Moock "Essential ActionScript 2.0".

Actionscript:
  1. public function addListener (o : MovieClip) : Boolean {
  2. if (o == null){
  3. return false;
  4. }
  5. if (isListener(o)){
  6. trace("este listener ya está escuchando")
  7. return false;
  8. }
  9. _listeners.push (o);
  10. return true;
  11. }
  12. public function removeListener (o : MovieClip) : Boolean {
  13. var len : Number = _listeners.length;
  14. for (var i : Number = 0; i <len; i ++) {
  15. if (_listeners [i] == o){
  16. _listeners.splice (i, 1);
  17. return true;
  18. }
  19. }
  20. return false;
  21. }
  22. public function removeAllListeners () : Void {
  23. _listeners = new Array ();
  24. }
  25. public function isListener (o : MovieClip) : Boolean {
  26. var len : Number = _listeners.length;
  27. for (var i : Number = 0; i <len; i ++) {
  28. if (_listeners [i] == o){
  29. return true;
  30. }
  31. }
  32. return false;
  33. }

La suscripción a la clase se hace por medio del método addListener, pasándole una referencia del movieclip que se suscribe. Hace uso del método isListener, que nos dice si un movieclip ya está suscrito, en cuyo caso no se añade de nuevo, y evitamos redundancia. El método removeListener, nos sirve para borrar una sucripción del movieclip pasado como argumento. Decir que los tres métodos nos devuelven el resultado de la ejecución del mismo. El método removeAllListener nos sirve para borrar todos los listeners suscritos.

Actionscript:
  1. function update () : Void{
  2. var _listenersSnapshot : Array = _listeners.slice (0);
  3. // Invocamos onEnter() sobre todos los _listeners.
  4. for (var i : Number = _listenersSnapshot.length - 1; i>= 0; i --)    {
  5. _listenersSnapshot [i].onEnter();
  6. }
  7. }

El método update es la que se encarga de trasnmitir el "evento" a todos los movieclips suscritos, ejecutando la función onEnter de los mismos. Tan solo reseñar que primeramente hacemos una copia de los listener, de forma que no interfiera con los métodos addListener y removeListener mientras ejecutamos el método update.
En un sentido estricto, deberí­amos haber definido un interfaz Enterable, donde se definiera el método onEnter, y todos los objetos que quisieran suscribirse a la clase EnterFrameSingleton debieran de implementarlo. Pero me ha parecido más "usable" y cotidiano esta forma de desarrollar la clase. Si hay algún purista entre la audiencia, que me perdone.

Actionscript:
  1. public function countListeners () : Number {
  2. return _listeners.length;
  3. }
  4. public function test(frase:String):Void{
  5. trace(frase);
  6. }
  7. }

Por último, un método que nos devuelve cuantos listener tenemos en un momento dado, y un método para testear la clase.

Descarga de archivos

Descarga Enterframesingleton

Enterframesingleton se ha descargado 430 veces.

6 Votes | Average: 4.67 out of 56 Votes | Average: 4.67 out of 56 Votes | Average: 4.67 out of 56 Votes | Average: 4.67 out of 56 Votes | Average: 4.67 out of 5 (6 votos, promedio: 4.67 sobre 5)
Loading ... Loading ...

0 Responses to “OOP: Mejorando el rendimiento.”


  1. No Comments

Leave a Reply




Subscribe

Subscribe to my RSS Feeds