SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

Participe do fórum, é rápido e fácil

SSGamers - 13 Anos online por você.

#SSGamers - A Comunidade que mais crescer no brasil!

SSGamers - 13 Anos online por você.

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Chegou o novo tema 6.5.5 - SSGamers - Servidores online de qualidade - Aproveite e entre para nossa comunidade, inscreva-se já! - Ouça nossa web radio - Veja nossas novidades - Participe dos nossos setores de jogos online - Parcerias aberta fale já com um administrador.

    [Tutorial] y_iterate (foreach 3.0)

    Weslley_Script
    Weslley_Script
    SS - Fundador
    SS - Fundador


    Steam Steam : WeslleySSGames
    Zello : WeslleySSGames
    Mensagens : 11625
    Moedas : 1032881
    Data de inscrição : 06/10/2011
    Idade : 28
    Localização : Brasil

    [Tutorial] y_iterate (foreach 3.0) Empty [Tutorial] y_iterate (foreach 3.0)

    Mensagem por Weslley_Script Qui 30 Mar 2023 - 8:57

    foreach 3.0


    Introdução

    Esta é uma nova versão importante do "foreach", vou assumir alguma familiaridade com a versão existente. Se você não tem isso, leia primeiro este tópico: [LINK PERDIDO]

    Mudanças recentes
    • A maioria dos nomes internos, prefixos e macros foram alterados. Isso não deve ser um problema, pois você não deve usar os internos diretamente ...

    • "Iter_InternalArray" agora é "Iter_TrueArray" e "Iter_InternalSize" agora é "Iter_TrueCount". O uso de "Interno" no nome foi confuso, porque eles foram projetados como uma API externa para fornecer acesso direto a alguns detalhes de implementação.

    • As funções iteradoras especiais mudaram significativamente. O estilo antigo parecia:

      Код:

      Código:
      iterfunc Tag:MyIterator(outros, Tag:cur)
      {


      Marca de

      Código:
      retorno:-1;
      }


      A nova versão se parece com:

      Код:

      Código:
      #define iterstart@MyIterator -1
      iterfunc Tag:MyIterator(cur, other)
      {


      Marca de

      Código:
      retorno:-1;
      }


      Há duas mudanças principais: A definição "iterstart@" informa ao sistema qual é o valor inválido para o seu iterador - costumava ser -1 por padrão, mas precisava ser mais genérico. O valor "cur" foi movido para o início da lista de parâmetros e perdeu todas as tags opcionais (mesmo que a função ainda retorne uma tag) - isso permite mais de um parâmetro adicional para a função do iterador: "MyIterator(cur , outro, mais, sim)" e "foreach (novo i: MyIterator(3, 4, 5))"

    • Os valores de retorno de "Iter_Add", "Iter_Remove" e algumas outras funções não são mais booleanos. Em vez disso, eles retornam o valor recém-adicionado/removido do iterador ou -1 em caso de falha.

    • Isso agora REQUER YSI - há muitas alterações para manter duas versões paralelas, pois muitos recursos exigiriam o dobro do código sem o YSI.


    Observe que essas alterações não devem afetar os usos básicos apenas dos iteradores "Player" e outros.


    Novas características
    • Multi-Iteradores


    Um multi-iterador é um iterador em que existem várias listas em um conjunto de elementos e cada elemento pode estar em apenas uma lista. Por exemplo, uma lista de carros próprios. O conjunto de elementos é o conjunto de todos os veículos, cada jogador pode ter uma lista de veículos que possui, e cada veículo pode ter no máximo um proprietário. Anteriormente, isso parecia:
    Код:

    Código:
    novo
     Iterator:OwnedVehicles[MAX_PLAYERS]<MAX_VEHICLES>;
    Iter_Init(OwnedVehicles);
    foreach (new i: OwnedVehicles[playerid])
    {
    }


    Isso funciona, mas é muito ineficiente. Cada jogador tem um espaço para cada veículo, mas como cada veículo só pode pertencer a um jogador, a maioria desses espaços é desperdiçada. Além do mais, não há nada realmente impedindo você de fazer:
    Код:

    Código:
    Iter_Add(OwnedVehicles[5], 5);
    Iter_Add(OwnedVehicles[7], 5);

    Para atribuir o veículo "5" como propriedade de duas pessoas diferentes.

    Um multi-iterador para isso ficaria assim:
    Код:

    Código:
    novo
     Iterator:OwnedVehicles<MAX_PLAYERS, MAX_VEHICLES>;
    foreach (novo i: OwnedVehicles<playerid>)
    {
    }


    Existem várias vantagens nisso. Em primeiro lugar, esta matriz é muito menor - em vez de usar (mais de) slots "MAX_PLAYERS * MAX_VEHICLES", ele usa apenas "MAX_PLAYERS + MAX_VEHICLES", que está próximo do ideal. Em segundo lugar, como cada veículo só pode aparecer em um único iterador, este código falhará:
    Код:

    Código:
    Iter_Add(OwnedVehicles<5>, 5);
    Iter_Add(OwnedVehicles<7>, 5);


    Ao tentar adicionar um veículo, você pode verificar se conseguiu:
    Код:

    Código:
    if (Iter_Add(OwnedVehicles<7>, 5) == -1)
    {
     // Não é possível adicionar o veículo a este iterador.
    }


    Você pode verificar se um valor está em uma lista específica:
    Код:

    Código:
    if (Iter_Contains(MyIter<5>, 11))
    {
    }


    Ou está em alguma das listas:
    Код:

    Código:
    if (Iter_Contains(MeuIter<>, 11))
    {
    }


    Remover um valor da lista errada não fará nada, porque não está nessa lista!
    Код:

    Código:
    Iter_Add(MeuIter<5>, 11);
    foreach (new i : MyIter<5>) printf("%d", i);
    Iter_Remove(MeuIter<7>, 11);
    foreach (new i : MyIter<5>) printf("%d", i);


    Saídas:
    Код:

    Código:
    11
    11


    • Iteradores Reversos


    A versão antiga do foreach tinha iteradores reversos na forma de "Iter_Prev(iter, x)", mas eles eram desajeitados e lentos. A nova versão fez duas mudanças importantes. Em primeiro lugar, para iteradores NORMAIS (ou seja, não multi-iteradores ou iteradores especiais), retroceder é quase tão rápido quanto avançar). Em segundo lugar, você pode reverter um iterador diretamente:
    Код:

    Código:
    Iter_Add(MeuIter, 4);
    Iter_Add(MeuIter, 7);
    Iter_Add(MeuIter, 20);
    foreach (novo i: Reverse(MyIter))
    {
    }


    Saídas:
    Код:

    Código:
    20
    7
    4


    • Novos iteradores


    A versão antiga de "foreach" vinha com quatro iteradores: "Player", "NPC", "Character" e "Bot". Esta nova versão terá mais, atualmente só tem mais uma, e isso é principalmente para uma demonstração especial da função iteradora:
    Код:

    Código:
    foreach (novo i: Faixa(4, 8))
    {
     printf("%d", i);
    }


    Saídas:
    Код:

    Código:
    4
    5
    6
    7


    Код:

    Código:
    foreach (novo i : Range(4, 8, 2))
    {
     printf("%d", i);
    }


    Saídas:
    Код:

    Código:
    [size=14][size=13]4
    6[/size][/size]


    [size=14]Код:
    [size=13]foreach (novo i : Range(10, 6, -1))
    {
     printf("%d", i);
    }[/size][/size]


    Saídas:
    Код:

    Código:
    10
    9
    8
    7


    • Iteradores YSI


    Eles não são novos nesta versão, mas não estão realmente documentados. YSI inclui vários iteradores:
    Код:

    Código:
    novo
     BitArray:x<100>;
    foreach (novo i: Bits(x))
    {
     // Pega todos os slots que são "1" em "x".
    }


    Код:

    Código:
    novo
     BitArray:x<100>;
    foreach (novo i: espaços em branco (x))
    {
     // Pega todos os slots que são "0" em "x".
    }


    Код:

    Código:
    foreach (novo i: Command())
    {
     // Percorre todos os comandos y_commands.
    }


    Код:

    Código:
    foreach (novo i: PlayerCommand(playerd))
    {
     // Percorre todos os comandos y_commands que um determinado jogador pode usar.
    }


    Код:

    Código:
    foreach (novo Grupo:i : GroupChild(g))
    {
     // Percorre todos os grupos filhos de y_groups Group:g.
    }


    Код:

    Código:
    // Deve ser "PlayerGroup", desculpe!
    foreach (novo Grupo:i: PlayerGroups(playerid))
    {
     // Percorre todos os grupos em que um jogador está.
    }


    Код:

    Código:
    foreach (novo i: GroupMemeber(g))
    {
     // Percorre todos os jogadores de um grupo.
    }


    Код:

    Código:
    foreach (novo Grupo:i: CreatedGroup())
    {
     // Percorre todos os grupos em y_groups.
    }


    • depreciação


    A sintaxe "foreach (Player, i)", que foi obsoleta ANOS atrás, agora dá um aviso quando usada. O aviso contém o texto "using_deprecated_foreach_syntax". Esta é a única alteração que afetará os usuários regulares, e é por isso que a tornei ininterrupta.
    • Erros mais agradáveis


    Fazendo isso:
    Код:
    novo

    Código:
    Iterator:ArrayIter[10]<20>;
    Iter_Add(ArrayIter[5], 10);


    Agora dá o seguinte aviso:
    Код:
    O símbolo nunca é usado "Iter_Init@ArrayIter"

    A solução, como acontece com todos os iteradores multidimensionais, é chamar "Iter_Init":
    Код:
    novo

    Código:
    Iterator:ArrayIter[10]<20>;
    Iter_Init(ArrayIter);
    Iter_Add(ArrayIter[5], 10);


    Infelizmente, o aviso não é infalível. Isso não funcionará, mas compilará silenciosamente:
    Код:
    novo

    Código:
    Iterator:ArrayIter[10]<20>;
    Iter_Add(ArrayIter[5], 10);
    Iter_Init(ArrayIter);

    Usar um iterador padrão como um multi-iterador dará o seguinte erro:
    Код:

    Código:
    Símbolo indefinido "Iter_Multi@IterName"


    Da mesma forma, usar um iterador múltiplo como um iterador regular dirá:
    Код:

    Código:
    Símbolo indefinido "Iter_Single@IterName"


    • Sintaxe de perdão


    Com a versão antiga de "foreach", você tinha que fazer este espaçamento:
    Код:

    Código:
    foreach (novo i: jogador)


    O seguinte código sutilmente diferente deu erros horríveis:
    Код:

    Código:
    foreach (novo i: Jogador)


    Agora não. Na verdade, quase todos os espaçamentos em quaisquer funções agora são aceitos.
    • Iter_AllocName


    Anteriormente, "Iter_Free" retornaria um valor não presente em um iterador e "Iter_Add" adicionaria um valor. "Iter_Alloc" simplesmente combina os dois recursos - localiza um valor não utilizado, adiciona-o ao iterador e o retorna:
    Код:

    Código:
    novo
     val = Iter_Alloc(MeuIter);


    • Ortografia correta


    Durante anos, houve duas cópias de todas as funções, porque a primeira versão as grafava todas erradas - por exemplo, "Iter_Add" e "Itter_Add". "Iterar" não tem um "t" duplo! As cópias incorretas já foram removidas.
    • Limpeza de código


    Isso não é realmente uma mudança que afeta o usuário final, mas tudo o que é interno à biblioteca agora é MUITO mais agradável de se trabalhar e ler. Na verdade, ficou ainda melhor durante o desenvolvimento, mas renomeei algumas macros para tornar o código resultante mais curto.
    • testes


    Eu adicionei isso ao y_testing, para que as alterações possam ser verificadas rapidamente.


    Download


    Esta versão de "foreach" está na versão mais recente de "YSI" no github:

    https://github.com/Misiur/YSI-Includes/tree/YSI.tl

    Creditos: Misiur



    [Tutorial] y_iterate (foreach 3.0) D07Xwqb
    [Tutorial] y_iterate (foreach 3.0) Yjab9HN

      Data/hora atual: Sex 8 Nov 2024 - 2:55