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

Editar Perfil

Tus temas
Tus Mensajes ()

Enlaces rápidos








Comparte
 

 [SNIPPET] NewGroup

Ver el tema anterior Ver el tema siguiente Ir abajo 
AutorMensaje
muzk
Peón
muzk


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

Mensajes Mensajes : 40
Reputación Reputación : 4
Monedas de oro : 188
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 5:42 pm

NewGroup v2.0

GITHUB: https://github.com/muZk/warcraft3/tree/master/NewGroup

Actualización de vieja librería para reciclar grupos.

Usa 2 funciones que pueden encontrarse en la famosa librería GroupUtils

Mi opinión personal sobre GroupUtils:

  • Muchas líneas de código si solo vas a reciclar grupos.
  • Ni siquiera la versión segura es 100%, hay formas de romper toda su seguridad, lo que puede provocar bugs tremendos en mapas si no se es cuidadoso.


¿Cómo romper group utils?
[jass]
local group g = NewGroup()
local unit u = CreateUnit(Player(15), 'Hpal',0,0,0)
call DestroyGroup(g)
call ReleaseGroup(g) // true
set g = NewGroup() // el mismo que eliminamos
call GroupAddUnit(g,u)
call IsUnitInGroup(u, g) // false
[/jass]

Semejanzas GroupUtils y NewGroup

  • Ambos implementan NewGroup y ReleaseGroup.
  • Ambos proveen de grupo global ENUM_GROUP.
  • Ambos se preocupan de no guardar más grupos de lo que pueden (limitación del largo de arrays).
  • Ambos se preocupan de no reciclar grupos que ya han sido reciclados.


Diferencias entre GroupUtils y NewGroup

  • GroupUtils tiene más funcionalidades que solo reciclar.
  • GroupUtils tiene bugs en relación a guardar y obtener grupos destruidos, los cuales son inutilizables. NewGroup es cuidadoso en relación a los grupos destruidos.


Código

Utiliza http://www.worldofeditors.net/t2058-snippet-isgroupdestroyed

[jass]
library NewGroup requires IsGroupDestroyed

 /*
  * Version 2.0
  * Usage:
  *  - Use NewGroup() instead of CreateGroup()
  *  - Use ReleaseGroup(g) instead of DestroyGroup(g)
  *  - When you use groups only for enumeration, use the ENUM_GROUP global instead
  * Changelogs:
  *  2.0:
  *    - Rewritten in vjass
  *    - Added validations to:
  *        - Avoid releasing a group multiple times
  *        - Avoid releasing a null group
  *        - Avoid releasing a destroyed group
  *        - NewGroup now always returns a non-destroyed & empty group
  *  Release (1.0):
  */

 globals
   private integer count = 0
   private group array groups
   private hashtable ht = InitHashtable()
   group ENUM_GROUP = CreateGroup()
 endglobals

 function NewGroup takes nothing returns group
   if count == 0 then
     return CreateGroup()
   endif

   loop
       set count = count - 1
   
       if !IsGroupDestroyed(groups[count]) then
           call GroupClear(groups[count]) // Always return an empty group
           call RemoveSavedBoolean(ht, GetHandleId(groups[count]), 0)
           return groups[count]
       endif
       
       debug call BJDebugMsg(SCOPE_PREFIX+"Warning: A null group was found in groups array, at: " + I2S(count))
       
       exitwhen count == 0
   endloop
   
   return CreateGroup()
 endfunction

 function ReleaseGroup takes group g returns boolean
   if IsGroupDestroyed(g) then
       debug call BJDebugMsg(SCOPE_PREFIX+"Error: Destroyed groups cannot be released")
       return false
   elseif HaveSavedBoolean(ht, GetHandleId(g), 0) then
       debug call BJDebugMsg(SCOPE_PREFIX+"Error: Groups cannot be multiply released")
       return false
   elseif count == 8191 then
       debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max recycled groups achieved, destroying group")
       call DestroyGroup(g)
       return false
   endif
   call GroupClear(g)
   set groups[count] = g
   set count = count + 1
   call SaveBoolean(ht, GetHandleId(g), 0, true)
   return true
 endfunction

endlibrary
[/jass]

Test

Adjunto el código usado para testear.

[jass]
scope Test

   function AssertEqual takes boolean b1, boolean b2, string msg returns nothing
       local string red = "|cffff0000"
       local string green = "|cff008000"
       local string end = "|r"
       if b1 == b2 then
           call BJDebugMsg(green + msg + end)
       else
           call BJDebugMsg(red + msg + end)
       endif
   endfunction

   globals
       private group g
       private boolean b
   endglobals
   
   function Test1 takes nothing returns nothing
       set g = NewGroup()
       call AssertEqual(g == null, false, "Test 1: NewGroup() isn't null.")
       call ReleaseGroup(g)
   endfunction
   
   function Test2 takes nothing returns nothing
       set g = NewGroup()
       call DestroyGroup(g)
       call AssertEqual(ReleaseGroup(g), false, "Test 2: ReleaseGroup() on destroyed group shouldn't work.")
   endfunction
   
   function Test3 takes nothing returns nothing
       call AssertEqual(ReleaseGroup(null), false, "Test 3: ReleaseGroup() on null group shouldn't work.")
   endfunction
   
   function Test4 takes nothing returns nothing
       call NewGroup() // in case Test3, just "pops" the queue
       set g = NewGroup()
       set b = ReleaseGroup(g)
       call AssertEqual(b, true, "Test 4.1: Correctly released")
       call DestroyGroup(g)
       call AssertEqual(IsGroupDestroyed(g), true, "Test 4.2: Correctly destroyed")
       set g = NewGroup()
       call AssertEqual(IsGroupDestroyed(g), false, "Test 4: NewGroup shouldn't return a destroyed group")
   endfunction
   
   function Test5 takes nothing returns nothing
       set g = NewGroup()
       call ReleaseGroup(g)
       call AssertEqual(ReleaseGroup(g), false, "Test 5: Releasing a group twice shouldn't work")
   endfunction

   function InitTrig_Test takes nothing returns nothing
       call Test1()
       call Test2()
       call Test3()
       call Test4()
       call Test5()
   endfunction
endscope
[/jass]

Si se prueba con GroupUtils, falla el 2 y el 5.
Volver arriba Ir abajo
Marcos_M

Marcos_M


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

Mensajes Mensajes : 3307
Reputación Reputación : 588
Monedas de oro : 10302
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 6:41 pm

Linda librería .3

+rep to the muzk
Volver arriba Ir abajo
Ruke

Ruke


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

Mensajes Mensajes : 298
Reputación Reputación : 64
Monedas de oro : 1678
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 8:51 pm

[jass]struct NewGroup
readonly group group

public static method create takes nothing returns thistype
   local thistype this = thistype.allocate()

   if (IsGroupDestroyed(this.group)) then
       set this.group = CreateGroup()
   else
       call GroupClear(this.group)
   endif

   return this
endmethod
endstruct[/jass]

si no recuerdo mal allocate devolvia 0 si tenias mas de 8190 (para hacer el chequeo de grupos maximos reciclados que estas haciendo).
Volver arriba Ir abajo
muzk
Peón
muzk


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

Mensajes Mensajes : 40
Reputación Reputación : 4
Monedas de oro : 188
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 9:10 pm

No usaría struct solo por el checkeo, sabiendo que agrega mucho código innecesario Surprised
Volver arriba Ir abajo
Ruke

Ruke


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

Mensajes Mensajes : 298
Reputación Reputación : 64
Monedas de oro : 1678
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 9:17 pm

es que no es por el chequeo, es que escribis menos, por lo tanto menos codigo para test.
ademas me he fijado el codigo innecesario que pone, son dos o tres lineas locas muzk, no seas rata =.= (aunque tambien podes usar custom alloc)
Volver arriba Ir abajo
muzk
Peón
muzk


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

Mensajes Mensajes : 40
Reputación Reputación : 4
Monedas de oro : 188
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 9:23 pm

El coverage del test no tiene directa relación con la cantidad de líneas de código, por lo que decir que tengo menos que testear por la cantidad de código escrito es una falacia.

Además el diseño de la librería en base a structs creo que no le va

EDIT:
nah, en verdad si le va, ahí veo si la toco, pero no le veo beneficios de hacerlo, son 2 putos métodos xD.
Volver arriba Ir abajo
Ruke

Ruke


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

Mensajes Mensajes : 298
Reputación Reputación : 64
Monedas de oro : 1678
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 9:41 pm

@muzk #muzk (a ver si andan las notificaciones xD) de que me hablas?, por supuesto que cuanto menos código tengas menos tenes para testear, porque justamente lo que estas validando es el codigo que escribiste, directa relacion.


Última edición por Ruke el Dom Abr 12, 2015 8:42 am, editado 4 veces
Volver arriba Ir abajo
muzk
Peón
muzk


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

Mensajes Mensajes : 40
Reputación Reputación : 4
Monedas de oro : 188
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 10:01 pm

Dude, en la vida real se usan métricas para saber qué tan testeado tu código, y me parece que no hay muchas que sean en base a la cantidad de líneas de código (o al menos de las famosas).

Look: http://en.wikipedia.org/wiki/Code_coverage

Piénsalo así, la librería tiene que cumplir estos tests:
- Que entregue siempre un grupo válido
- Que no se pueda guardar un grupo inválido
- Que si la pila ya está llena, los grupos a guardarse se destruyan
- Que no se pueda guardar 1 grupo más de 1 vez

En este caso, usar structs no reduce la cantidad de tests, ya que tengo que cumplirlos igual
Volver arriba Ir abajo
Ruke

Ruke


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

Mensajes Mensajes : 298
Reputación Reputación : 64
Monedas de oro : 1678
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Sáb Abr 11, 2015 10:11 pm

tenes razon, no lineas de codigo si no funcionalidad.
Volver arriba Ir abajo
Trigger.edge

Trigger.edge


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

Mensajes Mensajes : 978
Reputación Reputación : 111
Monedas de oro : 1245
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
Cetro del Rey Armadura Mágica Daga Mística
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Dom Abr 12, 2015 4:00 pm

Ahh al fin, nuevas librerías? xd

Supongo que usando structs quedaría algo así: Group.new() y myGroup.release()

[jass]
struct Group extends array

static method new takes nothing returns Group

method release takes nothing returns nothin

endstruct
[/jass]


[SNIPPET] NewGroup Wc3scr10
Volver arriba Ir abajo
muzk
Peón
muzk


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

Mensajes Mensajes : 40
Reputación Reputación : 4
Monedas de oro : 188
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Dom Abr 12, 2015 4:13 pm

^algo así. La idea es que tiene que simular un stack, así que tendría algún método estático push/pop.

Pero como digo, no vale la pena, son 2 métodos, y además si o sí tengo que meter las funciones NewGroup/Release por retrocompatibilidad, y ahí si te agregas 2 tests adicionales Ruke, haha.
Volver arriba Ir abajo
Ruke

Ruke


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

Mensajes Mensajes : 298
Reputación Reputación : 64
Monedas de oro : 1678
Monedas de Platino : 0 [SNIPPET] NewGroup Empty

Inventario :
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10
[SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10 [SNIPPET] NewGroup Empysl10

[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10Dom Abr 12, 2015 10:23 pm

@muzk escribió:
^algo así. La idea es que tiene que simular un stack, así que tendría algún método estático push/pop.

Pero como digo, no vale la pena, son 2 métodos, y además si o sí tengo que meter las funciones NewGroup/Release por retrocompatibilidad, y ahí si te agregas 2 tests adicionales Ruke, haha.

eso por pt y no usar structs de comienzo xD
Volver arriba Ir abajo
Contenido patrocinado




[SNIPPET] NewGroup Empty
Mensaje(#) Tema: Re: [SNIPPET] NewGroup [SNIPPET] NewGroup Clock10

Volver arriba Ir abajo
 

[SNIPPET] NewGroup

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 :: Aportes :: Librerías-