Foro especializado en Warcraft III y su editor
 
BuscarEntrar al ChatboxPortal del foroÍndiceSpellsRegistrarseConectarseGrupos de Usuarios
Eventos Actuales
¡ Bienvenido Invitado !

Editar Perfil

Tus temas
Tus Mensajes ()

Enlaces rápidos








Comparte | .
 

 [Tutorial] Resumen algo básico sobre el manejo de sintaxis de las Bibliotecas - Vjass

Ver el tema anterior Ver el tema siguiente Ir abajo 
AutorMensaje
angelcraft
Soldado
avatar


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

Mensajes Mensajes : 114
Reputación Reputación : 29
Monedas de oro : 441


Inventario :



Mensaje(#) Tema: [Tutorial] Resumen algo básico sobre el manejo de sintaxis de las Bibliotecas - Vjass Lun Feb 26, 2018 11:13 pm

Para iniciar en los cambios de nuevos parches de warcraft 3, es de seguro que muchos usuarios necesitarian saber el funcionamiento de ciertos codigos dentro de un mapa, para poder entender una de mejor manera utilidades que ayudaran mucho dentro del We. Este guia, o resumen va dirigido a usuarios que van entrando en tema de programacion basica usando Vjass.

Hablaremos en este caso de las Bibliotecas -- > Más conocido por muchos como librerías por una forma de traducción incorrecta XD (más cómodo y claro llamarlos a si en mi caso XD).

Bibliotecas:

1) Primer Plano: Concepto.
Es un conjunto de programas (en este caso código) estándares y subrutinas que se almacenan. Tomando un orden superior dentro del guion del código del mapa. (A esto me refiero que, al momento de la compilación de su código, este estará por el nivel de la cabecera del guion del mapa, si se llama una función alguna que está dentro de una biblioteca mediante un código dentro de un scope, esa función siempre será utilizable) En muchos casos se debe tomar en cuenta también la jerarquía de compilación donde esta se encuentra, para que el compilador no tenga problemas en hallar la función.

1.1) El orden de compilación seria el siguiente:

Fase 1: import / novjass / comentarios delimitados
Fase 2: textmacros
Fase 3: Zinc
Fase 4: Bibliotecas
Fase 5: Static Ifs
Fase 6: Módulos
Fase 7: Structs, etc.
Fase 8: Scope
Fase 9: Shadowhelper
Fase 10: PJass
Fase 11: Optimización (en línea)


Sabiendo esto, uno puede estar seguros que las bibliotecas y su codificación interior siempre serán revisadas antes que estructuras, scopes y paquete de códigos.

1.2) En segundo Plano: Sintaxis para la Declaración y Orden.

a) Declaración de Bibliotecas:

- Forma 1.-
[jass]library namespace
endlibrary
[/jass]
- Forma 2.-
[jass]library namespace initializer Init
   private function Init takes nothing returns nothing
   endfunction
endlibrary[/jass]
* Nota 1: El nombre de las Biblioteca, no pueden llevar caracteres de tipo No Alfanuméricos como. *, @, %, $, _, #, etc.
* Nota 2: Las Bibliotecas no podrán tener en su primera palabra de su nombre un número, Digamos library 13namespace.
· Dentro de las Bibliotecas se pueden declarar Structs, textmacros, functions, globals, etc. Mas no Scopes (A excepción de que no posea un initializer) u otras Bibliotecas.

[jass]library L1 initializer Init
   globals
       public constant integer dummyId = 'e000'
   endglobals
   
   private struct Circulo
       real x = 0
       real y = 0
       real r = 0
       
       static method create takes real x, real y, real r returns thistype
           local thistype d = thistype.allocate()
           set d.x = x
           set d.y = y
           set d.r = r
           return d
       endmethod
   endstruct
   
   globals
       public Circulo Circle
   endglobals
   
   public function PrecargarUnidad takes integer unitID returns nothing
       call RemoveUnit(CreateUnit(Player(15), unitID, 0, 0, 0))
   endfunction
   
   private function Init takes nothing returns nothing
       call PrecargarUnidad(dummyId)
       set Circle = Circulo.create(0,0,50)
       call Circle.destroy()
   endfunction
endlibrary
[/jass]
- Si una Biblioteca tiene una función sin ningún tipo de encapsulamiento (public, private), otra Biblioteca no podrá crear o definir una función con el mismo nombre. Ejemplo:
[jass]library l1
   function PrecargarUnidad takes integer unitID returns nothing
       call RemoveUnit(CreateUnit(Player(15), unitID, 0, 0, 0))
   endfunction
endlibrary

library l2
   //(XXX) l2 no puede usar una funcion con el nombre PrecargarUnidad por que
   //la Biblioteca l1 ya tiene una con el mismo nombre.
   function PrecargarUnidad takes integer unitID returns nothing
       call RemoveUnit(CreateUnit(Player(15), unitID, 0, 0, 0))
   endfunction
endlibrary[/jass]
b) Orden:
- Otra cosa que se debe tomar en cuenta, es el orden donde se sitúan las Bibliotecas por sus nombres que poseen.
Naturalmente el jass (de jasshelper) lee el código de abajo hacia arriba, y en varios casos Nosotros usualmente ponemos el orden de nuestras funciones dependiendo de esta regla. Pero en este caso, lo que influye el orden de las liberáis son sus nombres, en si ya nosotros no podemos situar conveniente la posición de nuestras Bibliotecas como hacíamos con las estructuras y las funciones que generábamos.
Ahora se preguntarán ¿cómo es basado en sus nombres? Esta situación se entiende fácilmente usando la lógica del alfabeto, podemos decir que A esta antes que B y B antes que C, pero tomando en cuenta que se incluye también los números (Cambiando el conjunto alfabético, a los alfanuméricos). Un ejemplo practico seria:


- library a2, library a1, library a y library a12
Usando la anterior lógica, sus nombres en si tendría que estar ordenados de forma alfanumérica, de la siguiente forma.

- library a, library a1, library a12 y library a2
Ahora este orden se aplica dentro del código del mapa que es diferente al código dentro de los detonadores, mostrando lo siguiente.

- Vista del código dentro de un detonador.
[jass]library a2
endlibrary
library a1
endlibrary
library a
endlibrary
library a12
endlibrary[/jass]
* Nota: En realidad cada nombre de cada Biblioteca tiene un valor en código "Asscii", lo que permite al jasshelper ordenarlos de forma numérica y mas fácil de compilar.
- Dentro del código del mapa, las Bibliotecas se situan dentro del guion del mapa por el orden de sus nombres mediante jasshelper.

[jass]//---------------------------------------------------
library a
endlibrary
library a1
endlibrary
library a12
endlibrary
library a2
endlibrary
//La Biblioteca de menor valor se situará siempre al principio de la sección del guion
//(codigo) del mapa.
//library.
//---------------------------------------------------[/jass]
- Esto es importante saber ya que, a la hora de jugar con funciones de distintas Bibliotecas, pueden generarse un error de función no declarada, esto sucede por no saber en qué orden el jasshelper situó mis Bibliotecas. Tomando en cuenta que el jasshelper lee el código de abajo hacia arriba, y que sitúa las Bibliotecas dependiendo de su nombre. Podemos realizar el siguiente ejemplo:(Todo este código esta dentro de un detonador).

- Generación de error por función no declarada, por orden del valor del nombre de las Bibliotecas:

[jass]library l2// Es mayor en asscii que l1
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

library l1// Es menor en asscii que l2
   function Funcion_l1 takes nothing returns nothing
        call Funcion_l2() //A la hora de llamar a mi funcion que esta dentro de l2
                          //me saldra el error de funcion no declarada.
   endfunction
endlibrary[/jass]
-|- Así es como se ve el Error en jasshelper.
(V) Generación de error por orden del nombre de la Biblioteca (JassHelper):

[jass]//---------------------------------------------------
library l1 //l1 se encuentra en el top del codigo
   function Funcion_l1 takes nothing returns nothing
        call Funcion_l2()
   endfunction
endlibrary

library l2
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

//Como ven la Biblioteca l1 esta arriba de l2, y sabiendo la regla de leer de abajo hacia
//arriba del jasshelper. A la hora de que llegue el compilador a la línea de código
//"call Funcion_l2()", quedra buscar la funcion "Funcion_l2()", pero esta estara por debajo
//de la linea de compilacion, tomando como no declarada la parte del codigo "Funcion_l2()".
//---------------------------------------------------[/jass]
Hay varias soluciones para esto, pero una sencilla seria cambiando el nombre de la Biblioteca l1, dándole mas peso para enviarle por debajo de la Biblioteca l2.
- Solución del problema:

[jass]library l2
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

library l3//Nombre cambiado de l1 a l3, ahora l3 en valor assci es mayor que l2
   function Funcion_l1 takes nothing returns nothing
        call Funcion_l2()
   endfunction
endlibrary[/jass]
* Solución del problema (JassHelper):
[jass]//---------------------------------------------------
library l2
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

library l3//Nombre cambiado de l1 a l3
   function Funcion_l1 takes nothing returns nothing
        call Funcion_l2()
   endfunction
endlibrary
//Ahora l3 puede leer la función de l2, por que esta arriba de la línea de compilación
//logrando seguir la regla de jasshelper (leer el código de abajo hacia arriba).
//---------------------------------------------------[/jass]
- Algo en tener en cuenta es que las Bibliotecas se sitúan dentro del código del mapa en la sección library (esta es una seccion exclusiva donde se ubica el codigo de las librerias y lo que contengan dentro de estas como funciones, estructuras , etc, que esta situada de acuerdo al orden especificado de las jerarquias por jasshelper y vjass, todo esto dentro del guion del mapa), siguiendo un orden de acuerdo al valor de sus nombres en Asscii, siempre el de menor valor ira en al principio del código, y detrás de esta las subsiguientes Bibliotecas siguiendo la secuencia (Aunque ya lo mencione repetidas veces esto se debe tener claro o al menos la logica que se sigue).

* Nota: También el orden por el nombre de las Bibliotecas esta vigente, cuando se sitúan en hojas de detonadores diferentes. El nombre con menor peso será el primero (como siempre):

- Generación de Error:

[jass]//Detonador Libreria1:
library Admin2
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

//Detonador Libreria2:
library Admin1
   function Funcion_l1 takes nothing returns nothing
       call Funcion_l2()
   endfunction
endlibrary[/jass]
Solucion del problema:
[jass]//Detonador Libreria1:
library Admin2//Generador del error.
   function Funcion_l2 takes nothing returns nothing
   endfunction
endlibrary

//Detonador Libreria2:
library Admin3//Cambiar su nombre para que tenga mas peso. Para que se situe
             //debajo de Admin2 en el codigo del mapa.
   function Funcion_l1 takes nothing returns nothing
       call Funcion_l2()
   endfunction
endlibrary[/jass]
* Nota Adicional: El orden es afectado cuando se usa los operadores uses, needs, requires. Ya que si uso uno de estos operadores mandaran a mi Biblioteca, hasta la parte final de mi código que ocupa las Bibliotecas. Esto solo lo menciono para aquellos que desean codear con Bibliotecas y hacer varios sistemas con estas, tomando en cuenta estas circunstancias.

1.3) En Tercer Plano: Usos de Bibliotecas.

- Las bibliotecas se usan como una abstracción de todo lo básico que podamos tener en nuestro código. Puede ser por ejemplo tener formulas matemáticas, que la mayoría sabe que siempre nos darán un valor especifico y exacto.
Tomando en cuenta que estas no se modifican.

[jass]library l1
//Funcion que halla la distancia entre dos puntos.
function DBPXY takes real x1, real y1, real x2, real y2 returns real
    return SquareRoot((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
endfunction
endlibrary[/jass]
- Las Bibliotecas pueden ser usadas para la creación de sistemas, tales como sistemas de inventarios, sistemas de selección de héroes. Esto depende de cada uno y como quiera usarlo. Un ejemplo podría ser:
[jass]library EfectoTemblor
//Un sistema que genere movimiento en la cámara, haciendo un efecto parecido a la
//de un temblor.
// |-------------|
// | Constants:  |
// |-------------|

globals
   private constant real Periodic = 0.04
   private integer array Datas
   private integer N  = 0
   private timer T    = CreateTimer()
endglobals

// |------------------|
// | End of Constants |
// |------------------|

//! textmacro L_ET_AllPlayer takes finalizar
   set n = 0
   loop
       exitwhen n > 15
           if $finalizar$ then
               call CameraClearNoiseForPlayer(Player(n))
           else
               call CameraSetEQNoiseForPlayer( Player(n),  d.frecuency )
               call CameraSetTargetNoiseForPlayer( Player(n),  d.frecuency, d.velocity )
           endif
       set n = n + 1
   endloop
//! endtextmacro

// |-------------------|
// | Private Structura |
// |-------------------|

private struct data
   player p
//---------------------
   real periodic
   real frecuency
   real velocity
   real mtime
   real ctime = 0
   boolean allplayer
//---------------------
   static method CallbackPlayer takes nothing returns nothing
       local data d
       local integer i = N
       local integer n
       
       loop
           exitwhen i == 0
           set d = Datas[i]
           
           set d.ctime=d.ctime+d.periodic
           if d.ctime > d.mtime then
               if d.allplayer then
                   //! runtextmacro L_ET_AllPlayer("true")
               else
                   call CameraClearNoiseForPlayer(d.p)
               endif
               set Datas[i] = Datas[N]
               set N = N - 1
               if N == 0 then
                   call PauseTimer(T)
               endif
           else
               if d.allplayer then
                   //! runtextmacro L_ET_AllPlayer("false")
               else
                   call CameraSetEQNoiseForPlayer( d.p, d.frecuency )
                   call CameraSetTargetNoiseForPlayer( d.p, d.frecuency , d.velocity )
               endif
           endif
           set i = i-1
       endloop
   endmethod
   static method Start takes player p, real frecuency, real velocity, real duration, boolean allplayer returns data
      local data d = .allocate()
      set d.p = p
      set d.frecuency = frecuency
      set d.velocity = velocity
     
      set d.allplayer = allplayer
      set d.periodic = Periodic
      set d.mtime = duration
      return d
   endmethod
   
endstruct
 
// |---------------|
// | End Structura |
// |---------------|
 
 //ACTIONS//
function Efecto_Temblor_Player takes player p, real frecuency, real velocity, real duration, boolean allplayer returns nothing
   if p == null and allplayer == false then
       return
   endif
   if N == 0 then
       call TimerStart (T, Periodic, true, function data.CallbackPlayer)
   endif
   set N = N + 1
   set Datas[N] = data.Start(p,frecuency,velocity,duration,allplayer)
endfunction
//END ACTIONS//
endlibrary[/jass]

1.4) En Cuarto Plano: needs, uses, requires, optional

Son opciones que permiten que se especifique a una Biblioteca, que necesita de otra para trabajar. Estas opciones van después del nombre de su bibliotecas o si posee un initializer obligadamente despues de este. Solo puede usarse una de ellas a  la vez, exepto optional.
- Tanto como needs, uses, requires, trabajan de igual forma.

[jass]library D initializer InitD
   function InitD takes nothing returns nothing
   endfunction
endlibrary

library C initializer InitC requires D //Si ya use requires no puedo agregar poner uses o needs
   function InitC takes nothing returns nothing
   endfunction
endlibrary

library B initializer InitB uses C //Si ya use uses no puedo poner agregar requires o needs
   function InitB takes nothing returns nothing
   endfunction
endlibrary

library A initializer InitA needs B //Si ya use needs no puedo poner agregar uses o requires
   function InitA takes nothing returns nothing
   endfunction
endlibrary[/jass]
- Una Biblioteca puede necesitar de varias Bibliotecas. Esto se expresa con poner comas "," cuando se declara las opciones needs, uses, requires y optional, por ejemplo:

- library A initializer InitA needs B , C , E

* Nota: Cuando se usa estas opciones en una bilbioteca, el error que se ocasionaba por el orden de sus nombres se elimina. Ya que se crean un orden jerárquico entre las Bibliotecas que la usen.
[jass]library A initializer InitA uses B, C//Esta Biblioteca obvia el orden de su nombre
                                    //permitiendo situarse debajo de las Bibliotecas
                                    //B y C en el codigo del Mapa.
   function InitA takes nothing returns nothing
       call Funcion_C()
   endfunction
endlibrary

library B initializer InitB
   function InitB takes nothing returns nothing
   endfunction
endlibrary

library C
   function Funcion_C takes nothing returns nothing
   endfunction
endlibrary[/jass]
*Una forma segura de poder ordenar tus Biblioteca en distintas hojas de códigos (Detonadores), sin el uso de utilizar sus propios nombres, es la siguiente: (Esta solución va dirigido a usuarios medios/avanzados en vjass.)
-Optional, esta opción es muy diferente a las otras opciones, esta permite que una Biblioteca que se necesite se vuelva opcional, porque capaz esa Biblioteca no exista, entonces se obvia ese argumento. Su declaración debe estar acompañada de un uses o requires o needs.

[jass]//Esta Biblioteca requiere opcionalmente de una Biblioteca Z pero no existe,
//asi que se obvia ese argumento.
library B requires optional Z
   function Funcion_B takes nothing returns nothing
   endfunction
endlibrary

//Esta Biblioteca necesita de una Biblioteca B y una opcional C.
library A initializer InitA needs B, optional C
   function InitA takes nothing returns nothing
   endfunction
endlibrary[/jass]
* Nota: En este caso se aplica los Static Ifs, para verficar mediante una variable si existe esa Biblioteca.
[jass]library C
   globals
       //Public (encapsulamiento):
       //El encapsulamiento public hace que una variable, struct y funcion
       //tenga que poner el nombre asignado al scope o Biblioteca o struct, ejemplo
       //BibliotecaC_Existe, si otra entidad quiere usar esta varaible global publica,
       //tendra que poner "NombreBiblioteca"+"_"+"BibliotecaC_Existe", como resultado
       //C_BibliotecaC_Existe
       public constant boolean BibliotecaC_Existe = true
   endglobals
endlibrary

//Static Ifs:
//Mayormente usadas, para el caso de Bibliotecas opcionales,
//en este caso usandose para verificar si una Biblioteca existe o no.
//Si no existe la variable que se pide en este caso BibliotecaC_Existe,
//se tomara como un valor negativo. (false)
//Los static ifs, se toman como una forma de condicion mas elevada, porque puede cortar
//el codigo en la que se utiliza, por ejemplo encerrando una funcion, si no se cumple la
//condicion, el static if no permitira que el jasshelper compile la funcion que esta dentro
//del static if. Y genere una advertencia de compilacion "Undeclared function".
library B initializer InitB requires optional C, optional Z
   static if C_BibliotecaC_Existe then
       function Funcion_C takes nothing returns nothing
           call BJDebugMsg("Existe la Biblioteca C")
       endfunction
   endif
   static if Z_BibliotecaZ_Existe then
       function Funcion_Z takes nothing returns nothing
           call BJDebugMsg("Existe la Biblioteca Z")
       endfunction
   endif
   function InitB takes nothing returns nothing
       static if C_BibliotecaC_Existe then
           call Funcion_C()
       else
           call BJDebugMsg("No existe la Biblioteca C")
       endif
       static if Z_BibliotecaZ_Existe then
           call Funcion_Z()
       else
           call BJDebugMsg("No existe la Biblioteca Z")
       endif
   endfunction
endlibrary[/jass]
2) Como Testear y usar Static Ifs:
Esta sentencia a diferencia de if else normal, no requiere que el valor o variable exista dentro del codigo de nuestro mapa, dando la oportunidad de que el compilador no genere un error al no existir la variable puesta dentro de esta sentencia. El Static If es muy usado dentro de las bibliotecas para saber si existe un valor que requiera de forma opcional, de otras codigos, librerias, etc, que aun no se han puesto o codificado dentro del mapa. Los operadores que nos deja usar jasshelper son: and y not dentro de los Static Ifs
[jass]//Si quitamos /**/ de MiBibliotecaL1, podra funcionar las funciones de
//MiBibliotecaL2.
/*library MiBibliotecaL1
   globals
       //Cambie el valor de la VariableA y VariableB para comprobar.
       private constant boolean VariableA = true//false
       private constant boolean VariableB = false//true
   endglobals

  public function Funcion2_test takes nothing returns nothing
      call BJDebugMsg("Funciona MiBibliotecaL1")
  endfunction
endlibrary*/

library MiBibliotecaL2 initializer Init

 static if VariableA then
     function Funcion_MiBiblioteca takes nothing returns nothing
         call BJDebugMsg("Existe la Funcion_MiBiblioteca")
     endfunction
 endif
 static if  VariableA and not(VariableB) then
     function Funcion_MiBibliotecaEx takes nothing returns nothing
         call BJDebugMsg("Existe la Funcion_MiBibliotecaExtra")
     endfunction
 endif

  private function Init takes nothing returns nothing
     call Funcion_MiBiblioteca() y
     call Funcion_MiBibliotecaEx()
      //Si no se encuentra la VariableA, jasshelper lo tomara como falso
      //y no existira la function Funcion_MiBiblioteca, y no dara advertencia a
      //la hora de compilar. Asi que para una biblioteca que necesite de un
      //codigo especifico este podra seguir funcionando, a pesar que no exista
      //gracias a static if, separando codigo existente de codigo no encontrado

      //static if tambien se puede usar dentro de funciones como ejemplo:
      static if VariableA then
          call MiBibliotecaL1_Funcion2_test()
      endif
      //De esta manera, una biblioteca que requiera una funcion de otra biblioteca,
      //el creador podra diseñar un codigo opcional de la libreria faltante. Sin
      //generar advertencias de compilador. Para la comodidad de usuarios que usen
      //su codigo.
  endfunction
endlibrary[/jass]

3) Recomendaciones:

* Como consejo, no es bueno trabajar con muchas Bibliotecas que se combinan entre si. (Ya por lo previsto por el orden de los nombres, si se quiere manejar varias puede usarse los operadores para tal acción, generando una jerarquía de Bibliotecas)
* Si se desea tener una Biblioteca básica principal, es bueno poner todas sus funciones básicas dentro de esta, el nombre de esta librería debe ser con pocas letras digamos "AB”, y como es básica no debe usar funciones de otras Bibliotecas.
* En las implementaciones de Bibliotecas por terceros no dudar en usarlos, porque ellos ya han previsto los problemas suscitados en sus Bibliotecas.
Esto es un pequeño resumen de lo que se puede hacer con Bibliotecas. Cualquier cosa correspondiente a un error dentro de este documento, pueden comentar para mejorar este tutorial.


Saludos... Cool


Última edición por angelcraft el Mar Feb 27, 2018 3:58 pm, editado 4 veces (Razón : Tipeos y Ortografía)
Volver arriba Ir abajo
PENSATIVO197
Aprendiz
avatar


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

Mensajes Mensajes : 25
Reputación Reputación : 3
Monedas de oro : 68
Monedas de Platino : 0

Inventario :



Mensaje(#) Tema: Re: [Tutorial] Resumen algo básico sobre el manejo de sintaxis de las Bibliotecas - Vjass Jue Mayo 17, 2018 7:47 pm

para reventarse la cabeza O_o! alas justas puedo entender GUI XD!
Volver arriba Ir abajo
 

[Tutorial] Resumen algo básico sobre el manejo de sintaxis de las Bibliotecas - Vjass

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

 Temas similares

-
» Debate sobre Proxies y Préstamos de cartas
» Breve resumen del Mundial
» Duda sobre commander
» El puente sobre el río Kwai [DVDRip]
» Multimedia-Video - DVD Styler

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