2019-04-19, 12:31 AM
Esta es una traduccion de esta guía para VisualTexture
Introduccion
Hay una gran cantidad de temas que hablan sobre gran parte de YSI, pero generalmente se ignoran pequeños detalles de YSI. El punto de este tema es mostrar la mayoría de estos detalles para facilitar el desarrollo a la hora de trabajar con YSI.
GLOBAL_TAG_TYPES
Esto es usado en el lugar de los argumentos de una función, por ejemplo, "printf" esta definido así:
Usando "{Float,_}" significa que la funcion acepta un rango desde variables "Float" hasta "_" (Integers). Pero que hay de otras como "Text:", "Group:" o "Menu:". Podrias escribir así:
Pero YSI incluye GLOBAL_TAG_TYPES, una definicion que permite ahorrarnos esa tarea al agregar la mayoria de tags de variables.
Que se transformaria en esto en el preprocessor:
PP_LOOP
"PP_LOOP" es un loop preprocessor, lo que significa que genera multiples bloques de codigo, por ejemplo:
Compilara como
La definicion de este macro es esta:
Otro ejemplo de PP_LOOP:
Compilaria como:
Notese la falta de ',' al final ya que no esta separando nada.
__COMPILER_PASS
El compilador PAWN hace dos etapas de pre-processing. Es raro que esto sea un problema, pero si necesitas saber en que etapa esta corriendo el compilador puedes hacer:
De manera alternativa, puedes usar:
y_cell
Esta es una libreria para una rapida manipulacion de bits en cells:
Invierte todos los bits de la cell:
Ejemplo: 0b11110000000000000000000000000000
Pasa a: 0b00000000000000000000000000001111
Ejemplo: 0b10110011100011110000111110000010
Pasa a: 0b01000001111100001111000111001101
Ejemplo: 0b01010101010101010101010101010101
Pasa a: 0b10101010101010101010101010101010
Invierte todos los nibbles de una cell.
Ejemplo: 0x12345678
Pasa a: 0x87654321
Ejemplo: 0x010F0703
Pasa a: 0x3070F010
Ejemplo: 0xF0F0F0F0
Pasa a: 0x0F0F0F0F
Cuenta todos los '1' de una cell.
Ejemplo: 0
Retorna: 0
Ejemplo: 1
Retorna: 1
Ejemplo: 0x01010101
Retorna: 4
Keywords
La mayoria de gente sabe que YSI agrega "foreach" al lenguaje PAWN, aqui una lista de otras keywords añadidas:
task - Timer que siempre esta corriendo mientras el servidor esta encendido (y_timers)
ptask - Similar a la keyword task, pero tiene el parametro de playerid. (y_timers)
loadtext - Carga strings localizados en un archivo para mostrar texto (y_text)
remote - Una funcion publica que puede ser llamada desde otros scripts con verificación de parámetros en la compilación (y_remote)
broadcastfunc - Llama una funcion remota en todos los otros scripts (y_remote)
inline - Declara una función dentro de otra función, con acceso a las variables de la función (y_inline)
using - Pasar una función de inline a otra función como un callback (y_inline)
hook - Usar un callback múltiples veces en múltiples archivos son conflicto (y_hooks)
global - Corriendo multiples scripts, solo uno debe cargar la función. Esto declara la función como global, así todos los scripts pueden usarla pero solo uno debe cargarla. (y_master)
Su diferencia con remote es que esta es solo es llamada en un script mientras que remote es llamada en todos los scripts.
foreign - Informa que esa función se encuentra en otro script. (y_master)
OnScriptInit y OnScriptExit (y_serverinit)
Tiene el mismo funcionamiento que OnGameModeInit/Exit o OnFilterScriptInit, una opción útil para inicializar código sin importar si se esta en un Filterscript o en una Gamemode.
Asignación dinámica de memoria (y_malloc)
Usando YSI puedes alocar y liberar memoria cuando quieras:
Restringiendo conexiones (y_flooding)
Puedes limitar el máximo de conexiones que pueden realizarse a tu servidor desde la misma IP:
Esto permitirá que se conecten hasta 3 personas desde la misma IP. Si otra mas intenta entrar, automáticamente no podrán lograr conectarse. Puedes cambiar el máximo y la acción al superar el limite.
Esto limitara las conexiones a 5, y si otra persona intenta entrar la IP sera baneada y los jugadores sufriran timeout.
Variables temporales
A veces necesitas una variable por una fracción de segundo. YSI ya trae 3 variables para evitar crear mas de estas: [email protected], [email protected] y [email protected][YSI_MAX_STRING].
Estas variables son globales, y no se puede confiar si mantiene los mismos datos luego de llamar una función, así que esto podria no funcionar:
No hay manera de saber si FuncionAleatoria modifica el valor de [email protected]
Funciones acortadas
YSI tiene unas cuantas funciones acortadas, principalmente para utilizarlas en los macros.
Prints de desbug
Si compilas tu Gamemode con alguna libreria de YSI y algun nivel de _DEBUG activo, al iniciar tu servidor YSI imprimirá informacion especifica dependiendo del nivel asignado.
El numero después del _DEBUG es el nivel de debug. Existen 8 niveles.
Para imprimir tus propios mensajes de debug usa "P:<Nivel>(Mensaje)":
Prints especiales
Ademas de los 8 niveles mencionados arriba, hay algunos niveles especiales:
Estos prints especiales siempre estan activos al compilar debido a que le dan información importante al usuario sobre errores en el codigo; no es solo información random de debug. De igual manera, pueden desactivarse poniendo esto en el código:
Prints dinamicos
Con y_debug puede usarse _DEBUG con valor -1, esto activa la posibilidad de modificar el nivel de debug en ejecución, entonces, esto:
Compila como:
Para cambiar el nivel en ejecucion, simplemente se usa esto:
Colocandolo en 0 desactiva la mayoria de prints de desbug (excepto los especiales mostrados arriba). Ademas, es posible obtener el nivel de debug.
Tags especiales
YSI introduce dos tipos especiales de tags para funciones. Estos pueden ser utilizados para optimizar códigos en ciertas circunstancias:
IS_IN_RANGE
YSI incluye una funcion muy util para simplificar la verificación de valores. Como su nombre indica, la función sirve para comprobar si algo esta dentro de un rango.
Este código comprueba si abc esta entre 1 y 100, devolviendo true si esta o false si no.
RUN_TIMING
Esta es una manera simplificada de obtener estadísticas al comparar dos códigos PAWN.
Imprimira algo así en la consola:
Si no sabes de estadística, elige la que tenga el menor "Mean", o mejor aprende estadística.
Hay un segundo parámetro opcional que es el numero de loops si el experimento fue muy rápido o muy corto.
Créditos:
Introduccion
Hay una gran cantidad de temas que hablan sobre gran parte de YSI, pero generalmente se ignoran pequeños detalles de YSI. El punto de este tema es mostrar la mayoría de estos detalles para facilitar el desarrollo a la hora de trabajar con YSI.
GLOBAL_TAG_TYPES
Esto es usado en el lugar de los argumentos de una función, por ejemplo, "printf" esta definido así:
Code:
native printf(const format[], {Float,_}:...);
Usando "{Float,_}" significa que la funcion acepta un rango desde variables "Float" hasta "_" (Integers). Pero que hay de otras como "Text:", "Group:" o "Menu:". Podrias escribir así:
Code:
native printf(const format[], {Float, Text, Menu, _}:...);
Pero YSI incluye GLOBAL_TAG_TYPES, una definicion que permite ahorrarnos esa tarea al agregar la mayoria de tags de variables.
Code:
native printf(const format[], GLOBAL_TAG_TYPES:...);
Que se transformaria en esto en el preprocessor:
Code:
native printf(const format[], {_, Language, Bit, Text, Menu, Style, XML, Bintree, Group, Timer, File, Float, Text3D}:...);
PP_LOOP
"PP_LOOP" es un loop preprocessor, lo que significa que genera multiples bloques de codigo, por ejemplo:
Code:
PP_LOOP<5>(printf("hi");)()
Code:
printf("hi");printf("hi");printf("hi");printf("hi");printf("hi");
La definicion de este macro es esta:
Code:
PP_LOOP<veces>(texto/codigo a imprimir)(separador)
Otro ejemplo de PP_LOOP:
Code:
PP_LOOP<10>(55)(, )
Compilaria como:
Code:
55, 55, 55, 55, 55, 55, 55, 55, 55, 55
Notese la falta de ',' al final ya que no esta separando nada.
__COMPILER_PASS
El compilador PAWN hace dos etapas de pre-processing. Es raro que esto sea un problema, pero si necesitas saber en que etapa esta corriendo el compilador puedes hacer:
Code:
#if __COMPILER_PASS == 0
#else // 1 para la segunda etapa
#endif
De manera alternativa, puedes usar:
Code:
#if COMPILER_1ST_PASS
#else // Si es la segunda etapa (COMPILER_2ND_PASS)
#endif
y_cell
Esta es una libreria para una rapida manipulacion de bits en cells:
Code:
Cell_ReverseBits(cell);
Invierte todos los bits de la cell:
Ejemplo: 0b11110000000000000000000000000000
Pasa a: 0b00000000000000000000000000001111
Ejemplo: 0b10110011100011110000111110000010
Pasa a: 0b01000001111100001111000111001101
Ejemplo: 0b01010101010101010101010101010101
Pasa a: 0b10101010101010101010101010101010
Code:
Cell_ReverseNibbles(cell);
Ejemplo: 0x12345678
Pasa a: 0x87654321
Ejemplo: 0x010F0703
Pasa a: 0x3070F010
Ejemplo: 0xF0F0F0F0
Pasa a: 0x0F0F0F0F
Code:
Cell_CountBits(cell);
Ejemplo: 0
Retorna: 0
Ejemplo: 1
Retorna: 1
Ejemplo: 0x01010101
Retorna: 4
Keywords
La mayoria de gente sabe que YSI agrega "foreach" al lenguaje PAWN, aqui una lista de otras keywords añadidas:
task - Timer que siempre esta corriendo mientras el servidor esta encendido (y_timers)
Code:
task Ping[1000]()
{
printf("Pong!");
}
ptask - Similar a la keyword task, pero tiene el parametro de playerid. (y_timers)
Code:
ptask PlayerPing[1000](playerid)
{
printf("Ping %d", playerid);
}
loadtext - Carga strings localizados en un archivo para mostrar texto (y_text)
Code:
loadtext core[ysi_properties];
remote - Una funcion publica que puede ser llamada desde otros scripts con verificación de parámetros en la compilación (y_remote)
Code:
remote MyFunc(a, b[])
{
}
broadcastfunc - Llama una funcion remota en todos los otros scripts (y_remote)
Code:
broadcastfunc MyFunc(42, "Hello world!");
inline - Declara una función dentro de otra función, con acceso a las variables de la función (y_inline)
Code:
stock Outer(a)
{
inline Inner(b)
{
printf("%d %d", a, b);
}
}
using - Pasar una función de inline a otra función como un callback (y_inline)
Code:
INI_Parse(file, using inline Local_Parse);
hook - Usar un callback múltiples veces en múltiples archivos son conflicto (y_hooks)
Code:
hook OnPlayerConnect(playerid)
{
}
global - Corriendo multiples scripts, solo uno debe cargar la función. Esto declara la función como global, así todos los scripts pueden usarla pero solo uno debe cargarla. (y_master)
Code:
global AC_GiveWeapon(playerid, weaponid, ammo)
{
}
Su diferencia con remote es que esta es solo es llamada en un script mientras que remote es llamada en todos los scripts.
foreign - Informa que esa función se encuentra en otro script. (y_master)
Code:
foreign AC_GiveWeapon(playerid, weaponid, ammo);
OnScriptInit y OnScriptExit (y_serverinit)
Tiene el mismo funcionamiento que OnGameModeInit/Exit o OnFilterScriptInit, una opción útil para inicializar código sin importar si se esta en un Filterscript o en una Gamemode.
Code:
public OnScriptInit()
{
}
public OnScriptExit()
{
}
Asignación dinámica de memoria (y_malloc)
Usando YSI puedes alocar y liberar memoria cuando quieras:
Code:
main()
{
new Alloc:a = malloc(1000); // Reservamos mil celdas de memoria.
mset(a, 0, 50); // Escribimos "50" en el primer slot.
// Pasamos nuestro array a nuestra funcion.
func(mget(a, 0), Malloc_SlotSize(a));
// Y por ultimo liberamos la memoria (o nos quedaremos sin memoria)
free(a);
}
func(arr[], size)
{
for (new i = 0; i != size; ++i) printf("%d", arr[i]);
}
Restringiendo conexiones (y_flooding)
Puedes limitar el máximo de conexiones que pueden realizarse a tu servidor desde la misma IP:
Code:
SetMaxConnections(3);
Esto permitirá que se conecten hasta 3 personas desde la misma IP. Si otra mas intenta entrar, automáticamente no podrán lograr conectarse. Puedes cambiar el máximo y la acción al superar el limite.
Code:
SetMaxConnections(5, e_FLOOD_ACTION_BAN);
- e_FLOOD_ACTION_BLOCK -> No permite mas conexiones (default)
- e_FLOOD_ACTION_KICK -> Kickea a todos usando esta IP.
- e_FLOOD_ACTION_BAN -> Banea la IP, los jugadores sufriran timeout.
- e_FLOOD_ACTION_FBAN -> Banea la IP y kickea a los jugadores conectados con esta IP.
Variables temporales
A veces necesitas una variable por una fracción de segundo. YSI ya trae 3 variables para evitar crear mas de estas: [email protected], [email protected] y [email protected][YSI_MAX_STRING].
Code:
#define ReturnPlayerHealth(%0) (GetPlayerHealth((%0), Float:[email protected]), Float:[email protected])
#define ReturnPlayerName(%0) (GetPlayerName((%0), [email protected], 24), [email protected])
Code:
[email protected] = 123;
FuncionAleatoria();
printf("%d", [email protected]);
Funciones acortadas
YSI tiene unas cuantas funciones acortadas, principalmente para utilizarlas en los macros.
- [email protected] -> setproperty
- [email protected] -> getpropery
- [email protected] -> CallRemoteFunction
- [email protected] -> CallLocalFunction
- [email protected] -> SetTimerEx
- [email protected] -> SetTimer (Parece no funcionar en YSI 5)
Prints de desbug
Si compilas tu Gamemode con alguna libreria de YSI y algun nivel de _DEBUG activo, al iniciar tu servidor YSI imprimirá informacion especifica dependiendo del nivel asignado.
Code:
#include <a_samp>
#define _DEBUG 3
#include <YSI_Coding\y_inline>
El numero después del _DEBUG es el nivel de debug. Existen 8 niveles.
- 0 -> Nada de debug.
- 1 -> Muestra las llamadas a funciones publicas (callbacks y timers)
- 2 -> Muestra las llamadas a las funciones de la API (Funciones principales de YSI)
- 3 -> Muestra las llamadas a stocks de YSI. (Funciones secundarias de YSI)
- 4 -> Muestra las llamadas a funciones internas de YSI
- 5 -> Muestra información extra de debug entre funciones.
- 6 -> Muestra información de loops (Prints entre loops)
- 7 -> Muestra información de loops (Prints en loops)
Para imprimir tus propios mensajes de debug usa "P:<Nivel>(Mensaje)":
Code:
P:5("Este mensaje sera imprimido en el nivel 5 para arriba");
Prints especiales
Ademas de los 8 niveles mencionados arriba, hay algunos niveles especiales:
Code:
P:F("Mensaje de error fatal");
// Imprime "*** YSI Fatal Error: <Tu mensaje>" y hace 5 beeps para alertar del error.
Code:
P:E("Mensaje de error");
// Imprime "*** YSI Error: <Tu mensaje>" y hace 3 beeps para alertar del error
Code:
P:W("Mensaje de advertencia");
// Imprime "*** YSI Warning: <Tu mensaje>" y hace un solo beep para alertar del error.
Code:
P:I("Mensaje de informacion");
// Imprime "*** YSI Info: <Tu mensaje>", no hace ningun beep. Similar a P:0.
Estos prints especiales siempre estan activos al compilar debido a que le dan información importante al usuario sobre errores en el codigo; no es solo información random de debug. De igual manera, pueden desactivarse poniendo esto en el código:
Code:
state ysi_debug : off;
Prints dinamicos
Con y_debug puede usarse _DEBUG con valor -1, esto activa la posibilidad de modificar el nivel de debug en ejecución, entonces, esto:
Code:
P:3("Message");
Code:
if (gDebugLevel >= 3) printf("Message");
Para cambiar el nivel en ejecucion, simplemente se usa esto:
Code:
DebugLevel(3);
Colocandolo en 0 desactiva la mayoria de prints de desbug (excepto los especiales mostrados arriba). Ademas, es posible obtener el nivel de debug.
Code:
new nivel = DebugLevel();
Tags especiales
YSI introduce dos tipos especiales de tags para funciones. Estos pueden ser utilizados para optimizar códigos en ciertas circunstancias:
- void - Gente que conozca el lenguaje de C reconocerá esto como "no return", en resumen; La función no retorna nada.
Usando y_master, este tag genera el código mas rápido, y da un error si se usa return en la función.Code:void:Func()
{
// No return.
}
- string - Este es un tag usado en todo YSI, no solo como un tipo de return. Cualquier cosa con el tag "String:" es solo un string normal, y es completamente compatible con strings regulares, pero hay veces que es util para el compilador saber la diferencia entre un string y un array.
Code:string:Func(string:a[], b[])
{
//Funcion que toma un string (a) y un array (b) y retorna un string.
}
IS_IN_RANGE
YSI incluye una funcion muy util para simplificar la verificación de valores. Como su nombre indica, la función sirve para comprobar si algo esta dentro de un rango.
Code:
if(IS_IN_RANGE(abc, 1, 100))
Este código comprueba si abc esta entre 1 y 100, devolviendo true si esta o false si no.
RUN_TIMING
Esta es una manera simplificada de obtener estadísticas al comparar dos códigos PAWN.
Code:
RUN_TIMING("Version 1 (+)")
{
a = b + 5;
}
RUN_TIMING("Version 2 (+=)")
{
a = b;
a += 5;
}
Imprimira algo así en la consola:
Code:
Timing "Version 1 (+)"...
Mean = 78.00ns
Mode = 76.00ns
Median = 78.00ns
Range = 9.00ns
Timing "Version 2 (+=)"...
Mean = 94.00ns
Mode = 94.00ns
Median = 94.00ns
Range = 15.00ns
Si no sabes de estadística, elige la que tenga el menor "Mean", o mejor aprende estadística.
Hay un segundo parámetro opcional que es el numero de loops si el experimento fue muy rápido o muy corto.
Code:
RUN_TIMING("Version 2 (+=)", 100)
Créditos:
- Ada32 - Escribir la guía en ingles originalmente
- #Fede - Traducción de la guía