Este é um tutorial simples e rápido para você compreender algumas coisas básicas sobre declaração de vars/arrays em Pawn (1) e como economizar memória com isso (2).
Vou passar rápido no tópico 1 (declaração de vars/arrays em Pawn) e me estender no tópico 2.
Coisas que você precisa saber para entender este tópico:
- Basicamente, todas as variáveis declaradas em Pawn (seja new, seja static) alocarão 32 bits (4 bytes ou 4B) p/cell.
- Cells são representadas por colchetes var[0] e bytes por chaves var{0}.
- Todo caractere da table ASCII (inclusive os especiais) compreendem nos decimais que vão de 0 a 255
- 8 bits podem armazenar um número de 0 a 255.
Logo podemos concluir que: 8 bits (1B) são suficientes para armazenar qualquer caractere (inclusive os especiais).
Sendo assim, a maneira mais eficiente de armazenar uma mensagem dentro de uma string não é inserindo um caractere por cell (4B), e sim um caractere por byte, ou seja, 4 caracteres por cell.
Como faremos isso?
Fácil, use ' ! ' antes de declarar uma String.
Ao invés de:
Use:
Isso faz com que você economize 12 Bytes de um total de 16 (75%). Imagine fazer isso para um servidor inteiro, a memória cai muito.
Enfim, tudo tem seus prós e contras. O nome desse tipo de string, de acordo com Pawn, é packed strings (mensagens compactadas), em que, realmente, alocam uma quantia menor de memória, mas não é possível que você use a função 'format' com elas, o que ferra tudo, porque são muito poucas as strings em um servidor que não passem por um format.vou mostrar uma alternativa.
Existe um comando que por aí em GameModes chamado /Cores, que basicamente faz com que uma dialog MSGBOX apareça na tela do player com as 256 cores de veículos, cada cor com seu respectivo número, tipo isso:
Mas pensa bem, se você for armazenar as 3072 caracteres que tem aí dentro (não é um palpite, têm exatos 3072 caracteres), você teria que fazer algo mais ou menos assim:
Sim, declarar uma string de 3072 cells, quero dizer 12.288bytes, exatos 12 KILOBYTES.
Será se conseguimos diminuir para 3 KB? diminuir em 75%? Não exatamente, mas conseguimos diminuir muito a memória alocada, e é agora que começa o tutorial.
Já que são 3072 caracteres, precisamos de apenas 768 cells (3072/4). Começamos por aí.
Além disso, vamos ter que criar outra array para armazenar a string que será formatada (usaremos 14 cells).
Por último, usaremos uma função.
a stock strpackcat (que basicamente concatena 2 packed strings, como se fosse strcat só que de packed strings):
Bom, o tutorial é basicamente isso, não tão útil até porque nem sempre criamos uma array assim tão grande. É mais usado nesses casos (raros) mesmo.
Algumas coisas eu não falei durante o tutorial pois não é o foco (já que devem existir outros tutoriais sobre os detalhes que eu deixei de falar, como o uso de 'char', que basicamente retorna o número de cells que são necessárias para armazenar x caracteres, etc).
Créditos ao JohnBlack.
Vou passar rápido no tópico 1 (declaração de vars/arrays em Pawn) e me estender no tópico 2.
Coisas que você precisa saber para entender este tópico:
- Basicamente, todas as variáveis declaradas em Pawn (seja new, seja static) alocarão 32 bits (4 bytes ou 4B) p/cell.
- Cells são representadas por colchetes var[0] e bytes por chaves var{0}.
- Todo caractere da table ASCII (inclusive os especiais) compreendem nos decimais que vão de 0 a 255
- 8 bits podem armazenar um número de 0 a 255.
Logo podemos concluir que: 8 bits (1B) são suficientes para armazenar qualquer caractere (inclusive os especiais).
Sendo assim, a maneira mais eficiente de armazenar uma mensagem dentro de uma string não é inserindo um caractere por cell (4B), e sim um caractere por byte, ou seja, 4 caracteres por cell.
Como faremos isso?
Fácil, use ' ! ' antes de declarar uma String.
Ao invés de:
Código PHP:
new String[16] = "Tutorial Maroto";
Use:
Código PHP:
new String[4] = !"Tutorial Maroto";
Isso faz com que você economize 12 Bytes de um total de 16 (75%). Imagine fazer isso para um servidor inteiro, a memória cai muito.
Enfim, tudo tem seus prós e contras. O nome desse tipo de string, de acordo com Pawn, é packed strings (mensagens compactadas), em que, realmente, alocam uma quantia menor de memória, mas não é possível que você use a função 'format' com elas, o que ferra tudo, porque são muito poucas as strings em um servidor que não passem por um format.vou mostrar uma alternativa.
Existe um comando que por aí em GameModes chamado /Cores, que basicamente faz com que uma dialog MSGBOX apareça na tela do player com as 256 cores de veículos, cada cor com seu respectivo número, tipo isso:
Mas pensa bem, se você for armazenar as 3072 caracteres que tem aí dentro (não é um palpite, têm exatos 3072 caracteres), você teria que fazer algo mais ou menos assim:
Código PHP:
if(!strcmp(cmd, "/cores", true))
{
new color_list[3072];
for (new colorid; colorid != sizeof gVehicleColors; colorid++)
{
format(color_list, sizeof color_list, "%s{%06x}%03d%s", color_list, gVehicleColors[colorid] >>> 8, colorid, !((colorid + 1) % 16) ? ("\n") : (" "));
}
ShowPlayerDialog(playerid, 1, DIALOG_STYLE_MSGBOX, "Color List", color_list, "Close", "");
return 1;
}
Sim, declarar uma string de 3072 cells, quero dizer 12.288bytes, exatos 12 KILOBYTES.
Será se conseguimos diminuir para 3 KB? diminuir em 75%? Não exatamente, mas conseguimos diminuir muito a memória alocada, e é agora que começa o tutorial.
Já que são 3072 caracteres, precisamos de apenas 768 cells (3072/4). Começamos por aí.
Além disso, vamos ter que criar outra array para armazenar a string que será formatada (usaremos 14 cells).
Por último, usaremos uma função.
Código PHP:
if(!strcmp(cmd, "/Cores", true)) {
new Result[768]; // Os 3072 caracteres do resultado final
new String[14]; // Os 14 caracteres que serão formatados a cada looping
for(new i; i != 256; ++i) { // 256 cores
format(String, 14, "{%06x}%03i%s", (VehicleColors[i] >>> 8), i, (((i+1) % 16) ? (" ") : ("\n"))); // Não precisa entender isso, apenas que fique claro que estamos usando format
strpack(String, String); // compactando as 14 cells em 14 bytes (que fique claro que a array String NÃO diminuiu de tamanho, apenas a informação foi compactada)
strpackcat(Result, String); // juntando a array Result com a array String (formatada e depois compactada)
} // Depois do processo ter terminado, a array Result estará prontinha para uso
ShowPlayerDialog(playerid, DIALOG_NOANS, DIALOG_STYLE_MSGBOX, "Cores", Result, "Ok", "");
return 1;
}
a stock strpackcat (que basicamente concatena 2 packed strings, como se fosse strcat só que de packed strings):
Código PHP:
stock strpackcat(dest[], const source[], maxlength=sizeof(dest)) {
if(dest{3}) { if(!dest{0}) { print("JBScript [strpackcat] ERROR: The destiny string must be already packed before using this function."); return 0; } }
if(source{3}) { if(!source{0}) { print("JBScript [strpackcat] ERROR: The source string must be already packed before using this function."); return 0; } }
new dl = strlen(dest), sl = strlen(source);
maxlength *= 4;
if(maxlength < dl) { print("JBScript [strpackcat] ERROR: The maxlength is lesser then destiny string length."); return 0; }
if(maxlength < sl+dl) { sl = maxlength-dl; }
for(new i; i != sl; ++i) { dest{dl+i} = source{i}; }
return 1;
}
Bom, o tutorial é basicamente isso, não tão útil até porque nem sempre criamos uma array assim tão grande. É mais usado nesses casos (raros) mesmo.
Algumas coisas eu não falei durante o tutorial pois não é o foco (já que devem existir outros tutoriais sobre os detalhes que eu deixei de falar, como o uso de 'char', que basicamente retorna o número de cells que são necessárias para armazenar x caracteres, etc).
Créditos ao JohnBlack.
Discord:https://discord.gg/Vg5HMqgdP9