Cargar clases dinámicamente
Introducción
En el capítulo anterior nos quedamos un poco con las ganas de no tener que forzar al compilador a incluir las clases de las que creábamos las instancias dinámicamente. Esto es especialmente un problema cuando no se sabe de antemano cuántas clases distintas se van a tener que instanciar. ¿La forma de solucionarlo? Muy sencillo. Con loadMovie :)
Solución
La idea es muy sencilla, “meter” la(s) clase(s) que queramos en un swf, cargarlo con loadMovie y listo. Es casi tan fácil como suena. Vamos a hacerlo por pasos.
** Paso 1. Meter las clases en un swf independiente
Si utilizas el IDE
La idea es la misma que contaba en el artículo anterior, forzar al compilador a meter la clase en el swf. Para ello símplemente impórtala y haz referencia a ella, nada más. Algo como esto en la línea de tiempo principal:
-
import tv.zarate.test.DynamicOne;
-
var force:DynamicOne;
Y listo. No hay que crear una instancia ni nada. Con eso es suficiente.
Si utilizas MTASC
Más sencillo aún. Con algo como:
-
mtasc -swf "dynamicone.swf" -header 1:1:24 -version 7 -strict DynamicOne.as
Que se note que *no* utilizamos -main para iniciar la película, simplemente creamos un swf y metemos la clase dentro.
** Paso 2. Cargas el swf con la clase.
Una vez que tienes creado el swf, lo cargas con loadMovie o MovieClip loader y, cuando haya terminado de cargar, ya tienes “disponible” la clase que estaba en ese swf. Puedes utilizar el método del anterior artículo para crear dinámicamente la instancia sin necesidad de forzar la inclusión de las clases en la clase principal. ¡YEAH!
Puedes bajarte el mismo ejemplo del artículo anterior de aquí.
La vida es bella, pero no tanto
Lo normal. Todas las cosas molonas tienen un pero y esta no iba a ser la excepción:
Los excludes. Este ejercicio es tan fácil porque las clases son triviales, pero en la vida real son más complicadas y normalmente hay mucha relación entre ellas. Si utilizas esta técnica, lo más normal es que tengas un puñado de clases comunes que están en el swf principal y que quieras que en el swf cargado sólo esté la clase que quieres cargar dinámicamente. Para forzar al compilador a NO incluir ciertas clases, necesitas utilizar los apestodos excludes. Que, como comentábamos en este post de Domestika, no funcionan muy bien que digamos. Al final dejo un par de enlaces para utilizarlos, tanto desde el IDE como desde MTASC.
Las variables globales. Yo y mi cruzada contra las variables globales. A lo mejor tienes suerte y no es tu caso, pero las variables globales de una película publicada para player 6 NO se ven en una película publicada para player 7. Eso quiere decir que si uno de los swfs es 7 y el otro 6, esto deja de funcionar. *Creo* que esto ya no es así para player superior a 7, pero no estoy seguro. Esta técnica funciona sin problemas con el player 9, pero estoy casi seguro de que no se puede mezclar clases AS1/AS2 con AS3. Quien haga la prueba que me mande un mail, please.
Notas finales
Esta técnica tiene bastantes aplicaciones y funciona bastante bien. Sé de buena tinta que por ejemplo El Pais 3 la utiliza intensivamente para ahorrar tiempo de descarga. La mayoría de los objetos (tipos de noticia) utilizan clases que son comunes a todo el sitio web, con lo que son excluidas a la hora de crearlos. Las clases comunes simplemente están ahí cuando la película las necesita. Es decir, la parte principal de la aplicación carga unas clases comunes que son excluídas de los objetos secundarios. Un efecto lateral de esto es que, al no estar las clases comunes compiladas en los objetos secundarios, no hace falta recompilar esos objetos para las nuevas versiones de las clases comunes. Esto es al mismo tiempo una ventaja y un inconveniente. Si actualizas una clase y la cagas, cosas que funcionaban dejarán de funcionar aunque no las hayas recompilado. Por la misa regla de 3, solucionar un bug común es más sencillo, ya que, una vez solucionado, todos los objetos secundarios utilizarán la nueva versión instantáneamente. Yo en su d&iaacute;a encontré partidarios y detractores por igual utilizar esto.
Otro uso bastante molón es por ejemplo para hacer skins. La idea es: tienes una clase que hace de modelo y quieres tener muchas vistas distintas. No sólo colores, sino una disposición de los elementos completamente variable. En ese caso lo que puedes hacer es crear un swf principal con el modelo y clases comunes y un swf con elementos de biblioteca y la clase específica de esa vista. Luego defines en un xml qué swf quieres que haga de skin. Funciona de maravilla siempre y cuando todas las vistas tengan algo en común, una interfaces.
Pues esto es más o menos todo. Espero que ayude. ¡Salud!
Enlaces
- Using a SWF as a DLL. Artículo de Aral Balkan en OSFlash sobre el mismo tema: cómo cargar clase dinámicamente.
- Using _exclude.xml, the Good, the Bad, and the Wishlist. Darron Schall hablando de los excludes.
- Cómo usar -exclude en MTASC. MTASC no aporta mucho más a la utilización de excludes, aunque sí alguna mejora como poder utilizar varios archivos.
- Post en Domestika donde se comenta sobre los excludes.