[Tutorial] YSeries - Y_INI
#1

YSI Series - Y_INI



Introducciуn
Bueno, dado que mucha gente me ha preguntado sobre el uso de algunos includes pertenecientes a la librerнa YSI, he decidido comenzar una serie de tutoriales al respecto.
El primero sera este en el cual intentare explicar como utilizar Y_INI correctamente y de una forma simple. Claro esta que si quieren alguna librerнa en particular, pueden decirme e intentare realizar dicho tutorial si asн lo creo conveniente y/o posible.
Les recuerdo como siempre que si ven algun error me avisen para poder corregirlo.

Nota: Si bien es un tutorial sobre Y_INI, no me concentrare concretamente en que hace cada funciуn del mismo, si no, mas bien en como utilizarlas de una forma practica con ejemplos.



Indice
  • Introducciуn
  • Indice
  • Introducciуn a INI
    • їQuй es INI?
    • Secciones, entradas y comentarios
      • Secciones
      • Entradas
      • Comentarios
  • Y_INI Bбsico
    • Creando un archivo
    • Escritura
    • Lectura
      • Forma basica
      • Con argumentos extra
  • Y_INI Simplificado
    • Lectura
  • Y_INI ParseFile
    • fname
    • remoteFormat
    • bFileFirst
    • bExtra y extra
    • bLocal
    • bPassTag
    • bFilter & filter
  • Final


Introducciуn a INI
Si queremos poder utilizar todas las caracterнsticas de Y_INI, primero debemos conocer mejor el formato INI.

їQuй es INI?
El formato INI es un formato (valida la redundancia) utilizado para almacenar mas ordenadamente datos. Estos datos tienen la caracterнstica particular de que poseen una descripciуn similar.

Ejemplo:
Si quisiйramos formar una base de datos sobre personas de nuestra empresa tendrнamos datos personales como por ejemplo su nombre, apellido, direcciуn, edad, nacionalidad y datos laborales como por ejemplo la fecha en la que ingreso a trabajar, su sueldo y el puesto que ocupa. Por lo cual para formar nuestra base de datos necesitarнamos almacenar los mismos, por lo que nuestros archivos INI podrнan ser asн:
Код:
[Personales]
Nombre=Nicolas
Apellido=Rodriguez
Edad=25
Direccion=Av. Espora 672
Nacionalidad=Argentina

[Laborales]
FechaIngreso=27/7/1998
Sueldo=18600
Cargo=Director Finanzas
De esta forma el formato INI no solo nos permite almacenar los datos con una breve descripciуn del mismo, si no que tambiйn nos permite organizarlos por secciones. Explicare mas tйcnicamente esto a continuaciуn.

Secciones y entradas

Secciones
Se llaman secciones a las divisiones creadas por los tags. Los tags se encuentran definidos por palabras encerradas entre corchetes ('[' ']'); estas secciones como se ve en el ejemplo anterior se utilizan para la mejor organizaciуn del documento.
Pero si se utilizan lectores relativamente avanzados, tambiйn brinda una mayor permanecer de lectura ya que si necesitamos un dato en particular buscaremos dentro de la secciуn del mismo y no por todo el documento en si.

Entradas
Las entradas estбn representadas por el conjunto de pares y valores que componen cada entrada.
Las entradas estбn compuertas por una llave o descripciуn (key) seguido de un '=' seguido de un valor (value).

Ejemplo:
[code]key=value[/key]

Una particularidad de las entradas es que no pueden repetirse iguales llaves a diferentes valores dentro de una misma secciуn, pues solo se leerб 1 de ellas (dependiendo del mйtodo de lectura sera la primera o ultima).

Ejemplo:
Код:
[Seccion1]
key1=valor1
key2=valor2
key3=valor3
key1=valor54

[Seccion2]
key1=valor1
key2=valor2
key3=valor3
En este ejemplo es muy posible que el valor obtenido al leer 'key1' de la secciуn1 sea 'valor1', pero tambiйn podrнa ser 'valor54'. Es por este motivo que un archivo INI bien formado no puede tener 2 keys idйnticos dentro de una misma secciуn.

Nota: Notemos que como los textos en formato INI se guardan en texto plano en el ejemplo anterior valorN (siendo N un numero) podrнa ser tanto un valor numйrico como el texto en si mismo; el tipo del valor dependerб de como se lo lea.

Comentarios
En este formato tambiйn podemos realizar comentarios, los cuales se indican colocando un ';' al comienzo del mismo.

Ejemplo:
Код:
key=value ;Esto es un comentario y no forma parte de la entrada

Y_INI Bбsico

Creando un archivo
Para poder trabajar con archivos INI primero necesitamos el archivo en si, por lo que debemos crearlo. Esto se realiza mediante una simple funciуn llamada INI_Open.

Ejemplo:
pawn Код:
new INI:file = INI_Open("ruta/de/nuestro/archivo.ini");
Y asi tan simple como esa linea creamos nuestro archivo, pero debemos comprender que el archivo esta abierto para escritura, por lo cual debemos cerrarlo. Entonces utilizamos la funciуn INI_Close.

Ejemplo:
pawn Код:
INI_Open(file);

Escritura

Ahora que sabemos como crear nuestro archivo podemos escribir datos en el mismo. Esta podrнa considerarse la parte simple.

Ejemplo:
pawn Код:
new
    INI:file = INI_Open("/Usuarios/TheChaoz.ini");

//Guardamos datos personales del usuario
//Seteamos el tag
INI_SetTag(file, "account_data");
//Guardamos datos
INI_WriteString(file, "Password", "12345");
INI_WriteInt(file, "Banned", 0);

//Guardamos informaciуn sobre las estadнsticas del usuario
INI_SetTag(file, "account_stats");
INI_WriteInt(file, "Score", 150);
INI_WriteInt(file, "Kills", 1500);
INI_WriteInt(file, "Deaths", 1500);
INI_WriteInt(file, "Money", 10000);
INI_WriteFloat(file, "SpawnX", 100.0);
INI_WriteFloat(file, "SpawnY", 100.0);
INI_WriteFloat(file, "SpawnZ", 1.0);

INI_Close(file);
El archivo que dicho cуdigo crearнa es el siguiente:
Код:
[account_stats]
SpawnZ = 1.000000
SpawnY = 100.000000
SpawnX = 100.000000
Money = 10000
Deaths = 1500
Kills = 1500
Score = 150
[account_data]
Banned = 0
Password = 12345
Nota: Recomiendo el uso de tags no solo para una mejor organizaciуn en caso de tener que leer el archivo, si no tambiйn por movilizaciуn (luego veremos esto con mas detalle).


Lectura

Y_INI brinda una gran variedad de formas de leer archivos, generalmente aquн es donde muchos usuarios no entienden como funciona el sistema y lo abandonan.

Intentare cubrir algunas de ellas con los aspectos mas bбsicos y simples.

Para leer un archivo utilizaremos la funciуn "INI_Load". Esta funciуn tiene algunos parбmetros opcionales los cuales iremos analizando uno por uno.

pawn Код:
INI_Load(filename[], bool:bExtra = false, extra = 0, bool:bLocal = true);
  • filename[] - Es el nombre del archivo que abriremos (con la ruta claro esta).
  • bExtra - Indicamos si enviaremos o no un parбmetro extra.
  • extra - Es el parбmetro extra que podemos enviar
  • bLocal - Indicamos si se carga el archivo solo en el script actual o en todos.
Veamos algunos ejemplos para comprender mejor el funcionamiento de esta funciуn.


Forma bбsica

Esta forma se suele utilizar con archivos cuyos nombres ya conocemos de ante-mano, por ejemplo archivos de configuraciуn, datos del servidor (no de usuarios), etc.

Ejemplo:
Код:
;este es un archivo utilizado como ejemplo para el siguiente cуdigo
[general]
MustLogin=1
MustRegister=0
[version]
Name=XXX Server
Version=1.4
[other]
DisableChat=0
pawn Код:
new
    gLogin,
    gRegister,
    gName[24],
    Float:gVersion,
    gChat;

public OnFilterScriptInit()
{
    INI_Load("/Config.ini");//Cargamos nuestro archivo

    printf("[general] MustLogin: %i  ||  MustRegister: %i", gLogin, gRegister);
    printf("[versiуn] Name: %s  ||  Version: %.1f", gName, gVersion);
    printf("[other] DisableChat: %i", gChat);

    return 1;
}

/*Aqui es donde hay algo de 'magia' que explicaremos mas adelante, pero por el momento lo que necesitamos saber es que luego de utilizar INI_Load, pawn leerб nuestro archivo
y linea por linea llamara a las siguientes callbacks segъn corresponda, indicando en 'name' el key y en value el valor de cada entrada.*/



//Fuera de cualquier callback y/o funciуn

//Este callback sera llamado ъnicamente con las entradas que estйn dentro del tag 'general'
INI:Config[general](name[], value[])
{
    //Aqui leeremos las entradas del tag 'general'
    INI_Int("MustLogin", gLogin);
    INI_Int("MustRegister", gRegister);

    return 0;//Este return solo es necesario pues utilizamos las macros provistas por Y_INI las cuales tienen en su definiciуn un return.
}

INI:Config[version](name[], value[])
{
    //Aquн leeremos las entradas del tag 'versiуn'
    INI_String("Name", gName, 24);
    INI_Float("Version", gVersion);

    return 0;
}

INI:Config[other](name[], value[])
{
    //Aqui leeremos las entradas del tag 'other'
    INI_Int("DisableChat", gChat);

    return 0;
}
La salida del cуdigo anterior seria:
Код:
[general] MustLogin: 1  ||  MustRegister: 0
[version] Name: XXX Server  ||  Version: 1.3
[other] DisableChat: 0
Ahora bien, dado el ejemplo explicare algunas cosas que tal vez se estйn preguntando.

їPorque utilice variables globales?
Esto se debe a que utilice las macros que nos brinda Y_INI (INI_Int, INI_Float, INI_String). Estas macros incluyen un return dentro, es decir que si el valor es leнdo, ya no se ejecutara cуdigo luego de esa
linea. Esto no quiere decir que estemos obligados a utilizar este mйtodo siempre (aun que a veces puede ser ъtil).

Ejemplo:
pawn Код:
//Las siguientes lineas de cуdigo son anбlogas, solo que la primera no ejecutara cуdigo posterior al leer un dato y la segunda si:
INI_Float("Version", version);
if(!strcmp(name, "Version))
    version = floatstr(value);

Con argumentos extra

Lo que esta forma nos permite es pasar un argumento extra al callback de carga (solo puede ser una variable y no un array).

Ejemplo:
Код:
;este es un archivo utilizado como ejemplo para el siguiente cуdigo
[general]
key1=132
key2=251
key3=512
key4=560
key5=2312
key6=1231
pawn Код:
new
    gValues[10];

public OnFilterScriptInit()
{
    INI_Load("/Numbers.ini", .bExtra=true, .extra=3);//Cargamos nuestro archivo indicando que recibirб un argumento extra y que dicho argumento es el numero 3 (este argumento podrнa ser variable)

    for(new i; i<6; i++)
        printf("key%i: %i", i+1, gValues[i]);

    return 1;
}

//Aquн como podemos observar sera nuestro primer parбmetro el que reciba nuestro parбmetro extra.
INI:Numbers[general](number, name[], value[])
{
    new
        key[5];
    //Lo que este cуdigo realiza es comparar uno por uno los nombres de cada entrada (comprobar sean key1-key6) y multiplicar el valor de dicha entrada por el parбmetro extra
    for(new i; i<6; i++){
        format(key, 5, "key%i", i+1);
        if(!strcmp(name, key)) {
            gValues[i] = strval(value)*number;
            return 1;
        }
    }

    return 0;
}
La salida del cуdigo anterior seria:
Код:
key1: 396
key2: 753
key3: 1536
key4: 1680
key5: 6936
key6: 3693

Y_INI Simplificado

Lectura

Al utilizar Y_INI tenemos muchas formas de leer archivos. El siguiente ejemplo es a mi parecer la forma mas simple de leer un archivo, pero tiene como desventaja la dependencia de otra librerнa (y_inline).


Ejemplo: (El siguiente ejemplo supone la correcta definiciуn de pData, array en la cual se almacenan los datos del jugador)
pawn Код:
stock LoginPlayer(playerid)
{
    new
        file[15 + MAX_PLAYER_NAME],
        pName[MAX_PLAYER_NAME],
        Float:P[3];

    GetPlayerName(playerid, pName, MAX_PLAYER_NAME);

    //Este es el callback inline, el cual es llamado 1 vez por cada entrada del archivo (los tags no estбn incluidos en este ejemplo)
    inline Load(name[], value[])
    {
        //Notemos que las siguientes macros solo funcionan si se definieron los argumentos de nuestra funciуn con los nombres "name[]" y "value[]"
        INI_Float("SpawnX", P[0]);
        INI_Float("SpawnY", P[1]);
        INI_Float("SpawnZ", P[2]);
        INI_Int("Deaths", pData[playerid][Deaths]);
        INI_Int("Kills", pData[playerid][Kills]);

        if(!strcmp(name, "Money"))//Podrнamos usar la macro INI_Int, pero deberнamos crear una variable extra, ademas asi se ejemplifica otra forma de leer los datos
            GivePlayerMoney(playerid, strval(value));
        else if(!strcmp(name, "Score"))
            SetPlayerScore(playerid, strval(value));
        else if(!strcmp(name, "Banned") && strval(value))
            Kick(playerid);
    }
    format(file, sizeof(file), "/Usuarios/%s.ini", pName);

    INI_ParseFile(file, using inline "Load");//Realizamos la lectura del archivo indicando que la funciуn es inline (y se llama "Load") y esta en este bloque de codigo.
    SetPlayerPos(playerid, P[0], P[1], P[2]);

    return 1;//Al igual que antes, es necesario el return por utilizar las macros INI_{Float/Int/...}
}


Y_INI ParseFile

Esto en realidad no es avanzado, pero si no se entiende lo que se hace puede llegar a ser algo confuso, es por esto que mucha gente opta por no utilizar este include.

Comenzemos por analizar el header de la funciуn:
pawn Код:
stock bool:INI_ParseFile(fname[], remoteFormat[], bool:bFileFirst = false, bool:bExtra = false, extra = 0, bool:bLocal = true, bool:bPassTag = false, bool:bFilter = true, filter[] = "")
Nota: El header a partir de YSI 4.0 es otro, pero aun no esta definido y provee una forma diferente de utilizaciуn, la cual no es tan eficiente, por lo que no se explicaran las diferencias aquн.
  • fname
    Representa el path del archivo que abriremos. Notemos que este path sigue siendo relativo desde la carpeta de nuestro servidor Scriptfiles como siempre.
    Esta funciуn si el archivo puede ser abierto para lectura con йxito retornara 1, caso contrario 0.

  • remoteFormat
    Se podrнa decir que representa el nombre del callback. Pero es algo mas complicado que eso.
    Aquн no solo indicaremos el nombre del callback, si no que tambiйn indicaremos como se cargara el archivo, o mejor dicho, que secciones.

    Код:
    ;Este es nuestro archivo ini a cargar llamado "test.ini"
    tagless_key = Texto ejemplo
    
    [tag1]
    tag1_key = 10
    tag1_key2 = texto2
    
    [tag2]
    tag2_key = texto3
    Ejemplo:
    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "testLoad");
    }

    forward testLoad(name[], value[]);
    public testLoad(name[], value[])
    {
        printf("%s = \"%s\"", name, value);
    }
    Si ejecutбramos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    tagless_key = "Texto ejemplo"
    tag1_key = "10"
    tag1_key2 = "texto2"
    tag2_key = "texto3"
    Es decir que leyу el archivo por completo (todas las entradas, independientemente de si tenнan o no tag y cual era el mismo en caso de tenerlo).

    Pero que tal si solo quisiйramos cargar las entradas de un tag especifico. Tendrнamos que leer todo el archivo y encontrar los valores de nuestra entrada de alguna forma.
    Bueno, aquн es donde Y_INI nos brinda una forma eficiente y cуmoda de hacer esto.

    Ejemplo:

    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "testLoad%s");
    }

    forward testLoad(name[], value[]);
    public testLoad(name[], value[])
    {
        printf("%s = \"%s\"", name, value);
    }
    Si ejecutбramos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    tagless_key = "Texto ejemplo"
    Esto es porque al final de nuestro callback agregamos un %s, esto luego la funciуn lo utilizara internamente para llamar diferentes callbacks segъn el tag.
    En nuestro ejemplo anterior se carga la secciуn sin tag, es decir que el %s del final, sera reemplazado por la cadena vacнa ("") y se llamara a la misma funciуn.
    De la misma forma si quisiйramos cargar solo el tag "tag1" nuestro callback deberнa ser llamado "testLoadtag1".

    Ejemplo:

    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "testLoad%s");
    }

    forward testLoad(name[], value[]);
    public testLoad(name[], value[])
    {
        printf("[sin tag] %s = \"%s\"", name, value);
    }

    forward testLoadtag1(name[], value[]);
    public testLoadtag1(name[], value[])
    {
        printf("[tag1] %s = \"%s\"", name, value);
    }

    forward testLoadtag2(name[], value[]);
    public testLoadtag2(name[], value[])
    {
        printf("[tag2] %s = \"%s\"", name, value);
    }
    Si ejecutamos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    [sin tag] tagless_key = "Texto ejemplo"
    [tag1] tag1_key = "10"
    [tag1] tag1_key2 = "texto2"
    [tag2] tag2_key = "texto3"
    Como podemos observar, las entradas fueron procesadas por el callback correspondiente a su tag.

    Nota: Podemos utilizar el formato que queramos, no es necesario limitarnos a "NombreCallback%s" podrнamos utilizar algo asн tambiйn "NombreCallback_%s" y tambiйn funcionaria.

    Importante: Si quisiйramos cargar solo un tag, podemos omitir crear los demбs callbacks y las entradas de los mismos no serбn procesadas.


    Asн mismo, si quisiйramos insertar el nombre del archivo dentro del callback como lo hicimos con los tags, podrнamos hacerlo agregando un %s extra.

    Ejemplo:

    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "Load_%s_%s");
    }

    forward Load_tag1_test(name[], value[]);
    public Load_tag1_test(name[], value[])
    {
        printf("[tag1] %s = \"%s\"", name, value);
    }
    Si ejecutamos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    [tag1] tag1_key = "10"
    [tag1] tag1_key2 = "texto2"
    Nota: El tag fue pasado al primer %s mientras que el nombre del archivo fue pasado al segundo.

  • bFileFirst
    Como vimos al final de la explicaciуn anterior, podнamos darle muchos formatos al callback que procesa las entradas para operar con la carga de los archivos.
    Ya fuese solo un nombre estбtico y fijo (Sin ningъn especificado).
    O con 1 especificado (solo 1 '%s'), en cuyo caso utilizarнamos tambiйn los tags del archivo (o bien el tag nulo "" en caso de que el archivo no tuviera tags).
    O bien con 2 especificadores, en cuyo caso utilizarнamos tanto los tags del archivo como su nombre.

    Ahora bien, este parбmetro nos permitirб utilizar solo el nombre del archivo sin necesidad de utilizar tambiйn el tag.

    Ejemplo:

    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "Load_%s", true);
    }

    forward Load_test(name[], value[]);
    public Load_test(name[], value[])
    {
        printf("%s = \"%s\"", name, value);
    }
    Si ejecutamos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    tagless_key = "Texto ejemplo"
    tag1_key = "10"
    tag1_key2 = "texto2"
    tag2_key = "texto3"
    Nota: La utilizaciуn de este parбmetro en 'true' no nos imposibilita el uso de los tags. Pues lo que realmente hace este parбmetro es invertir el orden (del nombre y los tags) dentro del callback.

    Importante: їCуmo se crea el callback si mi archivo tiene un espacio en el nombre y quiero pasarlo al callback? Los espacios dentro de los nombres de archivos serбn reemplazados por un '_'.

  • bExtra y extra
    Si bien son 2 parametros diferentes, se utilizan juntos SIEMPRE.

    Estos argumentos son utilizados para pasar datos extra el callback, pues a veces no alcanza con enviar solo la entrada(key & value). Un caso sonde se ve mucho esto es en la carga de archivos de usuario, pues se necesita saber que usuario se esta cargando en ese momento.
    Mientras que el parбmetro bExtra indicara si se pasara o no un argumento extra, el parбmetro extra sera quien reviva el valor de dicho argumento.

    Nota: Solo podemos pasar 1 variable (no string). Si necesitamos pasar mas podemos utilizar inline o variables globales.

    Ejemplo:

    pawn Код:
    forward LoadUser(playerid, name[], value[]);
    public LoadUser(playerid, name[], value[])
    {
        if(IsPlayerConnected(playerid)) {
            new
                pName[MAX_PLAYER_NAME];

            GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
            printf("Lading user %s(%i): %s = \"%s\"", pName, playerid, name, value);
        }
    }

    LoadPlayer(playerid)
    {
        INI_ParseFile("Users\\player.ini", "LoadUser", .bExtra = true, .extra = playerid);//Utilizamos el . antes del nombre de los parбmetros pues estos no estбn en orden.
    }
    Como podemos observar en el ejemplo, el parametro extra sera pasado como argumento a nuestro callback en primer lugar y sera constante para todas las llamadas de la misma.

  • bLocal
    Como vimos hasta ahora, en Y_INI (excepto que se utilice Y_INLINE) los archivos son cargados mediante callbacks, las cuales se definen con un public y un forward. Esto se debe a que al momento de llamarlas se utiliza
    (hasta YSI 3.1) CallRemoteFunction, es decir que el callback debe estar dentro del MISMO script que la llamada realizada.
    Con este parбmetro, si lo seteamos en true lo que haremos sera eliminar esta restricciуn, pues se realizara el llamado mediante CallRemoteFunction, permitiйndonos de esta forma que el callback este en otro script.

  • bPassTag

    Ya vimos como armar el callback definido en remoteFormat de muchas formas diferentes segъn nuestras necesidades.

    La forma bбsica:
    pawn Код:
    forward Nombre(name[], value[]);
    public CallbackName(name[], value[])
    {
        //cуdigo
    }
    Con el/los tags:
    pawn Код:
    forward_tag Nombre(name[], value[]);
    public CallbackName(name[], value[])
    {
        //cуdigo
    }
    Con el/los tags y el nombre del archivo:
    pawn Код:
    forward Nombre(name[], value[]);
    public CallbackName_tag_nombreArchivo(name[], value[])
    {
        //cуdigo
    }
    Con el nombre del archivo primero:
    pawn Код:
    forward Nombre(name[], value[]);
    public CallbackName_nombreArchivo(name[], value[])
    {
        //cуdigo
    }
    Con el nombre del archivo primero y luego el tag:
    pawn Код:
    forward Nombre(name[], value[]);
    public CallbackName_nombreArchivo_tag(name[], value[])
    {
        //cуdigo
    }
    Con parбmetros extra:
    pawn Код:
    forward Nombre(name[], value[]);
    public CallbackName(extra, name[], value[])
    {
        //cуdigo
    }
    Y obviamente podemos combinar estas a nuestro gusto y necesidades, pues no son excluyentes (excepto que utilicemos bFileFirst en cuyo caso no podremos recibir primero el tag pues asн lo indicamos). їPero que tal si quisiйramos que el tag estuviera como un parбmetro?
    Esto lo que nos permite es recibir dentro del callback el tag como un parбmetro mas.

    Ejemplo:

    Код:
    ;Este es nuestro archivo ini a cargar llamado "test.ini"
    tagless_key = Texto ejemplo
    
    [tag1]
    tag1_key = 10
    tag1_key2 = texto2
    
    [tag2]
    tag2_key = texto3
    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "Load", .bPassTag = true);
    }

    forward Load(tag[], name[], value[]);
    public Load(tag[], name[], value[])
    {
        printf("[%s] %s = \"%s\"", tag, name, value);
    }
    Si ejecutamos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    [] tagless_key = "Texto ejemplo"
    [tag1] tag1_key = "10"
    [tag1] tag1_key2 = "texto2"
    [tag2] tag2_key = "texto3"
    Como podemos observar la entrada que no tenia tag ("tagless_key") es llamada con "" como argumento del parбmetro tag.

    Ejemplo:

    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "Load", .bExtra=true, .extra=100, .bPassTag = true);
    }

    forward Load(extra, tag[], name[], value[]);
    public Load(extra, tag[], name[], value[])
    {
        printf("[%s] %s = \"%s\" || %i", tag, name, value, extra);
    }
    Como podemos observar, si utilizamos este parбmetro en conjunto con bExtra y extra el parбmetro extra seguirб siendo el primero y tag pasara a ser el segundo.

    Nota: Este parбmetro no es excluyente con la utilizaciуn del formato %s para pasar el tag al nombre del callback, pero realmente no veo motivos para hacer esto.

  • bFilter & filter
    Estos parбmetros nos permiten cargar una serie de tags determinada.

    Pero para entender mejor su correcto uso volverй primero sobre la estructura de los archivos INI.
    Si bien esto no es un estбndar, no rompe con ninguno de ellos por lo tanto es completamente valido.

    Dividiremos los nombres de los tags en 2 partes, una parte que llamaremos filtrable, y la otra sera el nombre.
    De esta forma construiremos los tags (no es obligatorio a menos que se quieran utilizar filtros) de la siguiente forma:

    Код:
    [@@Filtrable-nombre]
    El @@ indica el comienzo del nombre filtrable, el cual finalizara con el -; mientras que lo que siga a dicho guion sera el nombre real del tag.

    Ejemplo:

    Код:
    ;Este es nuestro archivo ini a cargar llamado "test.ini"
    tagless_key = Texto ejemplo
    
    [@@TEST-tag1]
    tag1_key = 10
    tag1_key2 = texto2
    
    [@@TEST-tag2]
    tag2_key = texto3
    
    [@@TEST2-tag1]
    tag1_key = 1001
    tag1_key2 = texto254
    
    [@@TEST2-tag2]
    tag2_key = texto3645
    pawn Код:
    main()
    {
        INI_ParseFile("test.ini", "Load", .bPassTag=true, .bFilter=true, .filter="TEST");
    }

    forward Load(tag[], name[], value[]);
    public Load(tag[], name[], value[])
    {
        printf("[%s] %s = \"%s\"", tag, name, value);
    }
    Si ejecutamos el cуdigo anterior obtendrнamos la siguiente salida:

    Код:
    [] tagless_key = "Texto ejemplo"
    [tag1] tag1_key = "10"
    [tag1] tag1_key2 = "texto2"
    [tag2] tag2_key = "texto3"
    Como podemos observar, el nombre del tag que es pasado sera el nombre real (no incluirб la parte real). Y solo se cargaran los tags que no tengan una parte filtrable o bien aquellos que correspondan al filtro aplicado.


Final

Espero que les haya servido y si ven algъn error por favor avнsenme asi lo corrijo.
Reply
#2

Muchas gracias buen post!
Reply
#3

Quote:
Originally Posted by ErickPuga234
Посмотреть сообщение
Muchas gracias buen post!
їTan rбpido lo leнste?

Lo leн a medias pero se ve que estб completo y le va a servir a varios.

Como veo que pusiste "YSeries", їplaneas hacer tutoriales de la librerнa YSI?
Reply
#4

jojojojojo muchas gracias TheChaoz, desde que me dijiste que lo harнas estuve esperбndolo

Quote:
Originally Posted by Glimma
Посмотреть сообщение
Como veo que pusiste "YSeries", їplaneas hacer tutoriales de la librerнa YSI?
creo que si, eso entendн en la introducciуn. Serнa buenнsimo que haga eso!
Reply
#5

Yo creo que a la gente le servirнa tutoriales de y_iterate, y_dialog e y_inline, y_timers, e y_stringhash. Yo podrнa hacer alguno, en teorнa, son fбciles de usar, y son efectivos.
Reply
#6

buen aporte amigo yo que quiero aprender un poco de esto :3
Reply
#7

Gracias por el tutorial habнan unas cosas de "ParseFile" que no me quedaban muy claras.
Reply
#8

Genialidad. Gracias
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)