BuscarEntrar al ChatboxPortal del foroÍndiceSpellsRegistrarseConectarseGrupos de Usuarios
Eventos Actuales
¡ Bienvenido Invitado!

Editar Perfil

Tus temas
Tus Mensajes ()

Enlaces rápidos








Comparte | .
 

 Funciones delegadas en Zinc

Ver el tema anterior Ver el tema siguiente Ir abajo 
AutorMensaje
SpamBot
Aprendiz
avatar


Barra de Salud : Su salud está al 100% - Este usuario no ha recibido infracciones

Mensajes Mensajes : 21
Reputación Reputación : 3
Monedas de oro : 84
Monedas de Platino : 0

Inventario :



Mensaje(#) Tema: Funciones delegadas en Zinc Sáb Jun 06, 2015 2:43 pm

Funciones Delegadas en Zinc

Nota : para seguir este tutorial necesitas tener el pre compilador para Zinc en el newgen.
Este Tema en la documentación de Zinc se encuentra en el apartado Function pointers (interfaces)
pero está en ingles asi que aqui va algo de informacion en pastruñol XD

¿Que son las funciones delegadas?  Las funciones delegadas son como su nombre lo dice funciones que implementas luego que pueden hacer algo distinto que en el momento que estas escribiendo un objeto el cliente que utilice tu librería querrá implementar poniendo su propia funcionalidad.

Las funciones delegadas permiten la implementación de componentes de manera mas limpia y permite que los componentes creados puedan llamar funciones que no se conocen de antemano,  en otros lenguajes como C# se permite la implementación de métodos delegados que son extremadamente útiles a la hora de implementar un evento al desarrollar algún tipo de control ,en este tutorial vamos a explicar un poco la forma en la que se puede hacer algo similar para el warcraft III y que a mi parecer resulta bastante cómodo.

*En los códigos se omitirán las instrucciones al precompilador //! zinc y //! endzinc

Resulta que en zinc no existen los metodos delegados, en su lugar existen los punteros a funciones y se declaran de la siguiente manera
[jass]
library FuncionesDelegadas
{
   type MiFuncionDelegadaA extends function(unit);
   type MiFuncionDelegadaB extends function(unit , integer);
   type MiFuncionDelegadaC extends function(unit ,string) -> boolean;
}
[/jass]
Como vemos arriba las funciones delegadas declaradas son como esquemas o la forma que tendrá una función al ser implementada ,luego podemos utilizar estas funciones declaradas como tipos.

En esta forma ya podrian ser utilizadas desde otras funciones :
[jass]
library FuncionesDelegadas
{
   type MiFuncionDelegadaA extends function(unit);
   type MiFuncionDelegadaB extends function(unit , integer);
   type MiFuncionDelegadaC extends function(unit ,string) -> boolean;
   
   private function QuienEresTu(unit u)
   {
       BJDebugMsg( "Yo soy "+GetUnitName(u));
   }
   
   private function Muere(unit u)
   {
       BJDebugMsg( "Muere !!!!");
       KillUnit(u);
   }
   
   private function Prueba( unit u , MiFuncionDelegadaA func)
   {
       func.evaluate(u);
   }
   
   private function onInit()
   {
       unit u = CreateUnit(Player(0) , 'Hpal',0,0,0);
       Prueba(u,QuienEresTu);
       Prueba(u,Muere);
   }
}
[/jass]

Como vemos en el ejemplo anterior podemos llamar a las funciones como parámetros y aunque el ejemplo no tiene mucho sentido , podemos utilizarlas de una forma un poco mas interesante, como por ejemplo una implementación de un evento realizado desde un objeto.

Una implementación mas interesante es ver los delegados de funciones como una forma de disparar nuestros propios eventos directamente desde los objetos que se han creado, esta implementación es similar a la que se utiliza en C# en la que las acciones de los eventos corren en manos de la persona que está utilizando el objeto.

en este ejemplo estamos definiendo un objeto que levantara un evento que correrá la función que necesitemos, lo único malo de esto es que necesitamos una hashtable para recuperar la instancia que ha detonado el evento
[jass]
library LibPrueba2
{
   private hashtable HASHTABLE;
   private constant key TESTEVENT_KEY; // key nos da un valor unico
   
   type EventHandlerOnAttack extends function(TestEvent , unit); //Manejador del evento delegado
   
   public struct TestEvent
   {
       EventHandlerOnAttack OnAttackEvent; //el evento que será lanzado desde otra parte del programa
       unit u ; //la unidad que tiene el evento
       trigger attackTrigger; //detonador que desencadena el evento
       
       private method OnAttackCallback(unit attacker) //este metodo llamara a la funcion delegada que implementemos si es que existe
       {
           if(this.OnAttackEvent!= 0)
               this.OnAttackEvent.evaluate(this , attacker); //llamara la funcion que necesitamos desde fuera del objeto y sin saber nosotro lo que hará
           else
               BJDebugMsg("Unimplemented Exception"); //mensaje de error en caso de que la funcion no esté implementada
       }
       
       public static method create(unit u)-> thistype
       {
           thistype this = thistype.allocate();
           this.u = u;
           this.attackTrigger = CreateTrigger();
           
           SaveInteger(HASHTABLE , TESTEVENT_KEY , GetHandleId(this.attackTrigger),this); //guardamos la instancia en la hashtable
           
           TriggerRegisterUnitEvent(this.attackTrigger , this.u , EVENT_UNIT_ATTACKED);
           TriggerAddAction(this.attackTrigger, function() //dejamos la ejecucion del detonador en manos de una funcion anonima
           {
               thistype this = thistype(LoadInteger(HASHTABLE , TESTEVENT_KEY , GetHandleId(GetTriggeringTrigger())));//recuperamos la instancia , recordar que esta es una funcion por lo tanto es estatica si tal cosa existe
               unit attacker = GetAttacker();
               //ejecuta el callback
               this.OnAttackCallback(attacker);

           });
           
           return this;
       }
   }
   
   private function onInit()
   {
       HASHTABLE = InitHashtable();
   }
}
[/jass]
Aquí podemos ver un struct que implementa un delegado para hacer algo fuera del objeto , en este caso el evento avisa que la unidad esta siendo atacada, las acciones a realizar para el evento estan siendo declaradas mas abajo Very Happy

Aqui estamos utilizando el objeto que hemos creado mas arriba y estamos utilizando un funcion que es ejecutada cuando corre el evento , para este caso simplemente avisa en pantalla quien esta atacando a la unidad que tiene el struct
[jass]
library LibTest2
requires LibPrueba2
{
   //funcion que es ejecutada cuando el evento es disparado
   private function OnAttackActions(TestEvent obj , unit attacker)
   {
       BJDebugMsg("La unidad "+GetUnitName(obj.u)+" esta siendo atacada por "+GetUnitName(attacker));
   }
   
   private function onInit()
   {
       unit u = CreateUnit(Player(0) , 'Hpal' , 0 ,0 ,0);
       TestEvent testObj = TestEvent.create(u);
       
       testObj.OnAttackEvent = OnAttackActions; //enlazamos nuestra funcion que ejecutara las acciones que estamos implementado
                                                //a nuestra funcion delegada
       
   }
}
[/jass]

descargar



FN escribió:
Si miras durante mucho tiempo un abismo ,el abismo puede asomarse en tu interior
Volver arriba Ir abajo
Trigger.edge

avatar


Barra de Salud : Este usuario es invulnerable ¿Será que es fiel a las normas?

Mensajes Mensajes : 977
Reputación Reputación : 106
Monedas de oro : 1239
Monedas de Platino : 0

Inventario :
Cetro del Rey Armadura Mágica Daga Mística


Mensaje(#) Tema: Re: Funciones delegadas en Zinc Miér Abr 13, 2016 12:25 pm

Interesante... que nadie había leído esto o que? apruebo.


Volver arriba Ir abajo
 

Funciones delegadas en Zinc

Ver el tema anterior Ver el tema siguiente Volver arriba 
Página 1 de 1.

Permisos de este foro:No puedes responder a temas en este foro.
Warcraft III - WorldEditor :: Academia :: Area JASS :: Tutoriales Varios-