Sign in to follow this  
Lord Henry

Qual destes métodos é mais otimizado?

Recommended Posts

Olá senhoras e senhores.

Tenho uma micro-dúvida com relação ao desempenho quando um resource controla os outros.

  • A situação é a seguinte:
    • Tenho 1 resource de painel de gerenciamento de mods de veículos (chamaremos de vehMods). Nesse painel tem uma lista com todos os veículos com as colunas ID, Veículo (nome), Status (ativado/desativado).
    • Quando o jogador clica 2x em um veículo da lista, o painel ativa/desativa a modificação daquele veículo. Mas a modificação está em outro mod de veículo, cada veículo tem seu próprio resource de modificação (exemplo de resource: 420TaxiBMW). Dai o resource do painel vai gerenciar este outro resource do Taxi.
    • Atualmente estou controlando os demais resources apenas forçando o jogador a executar o comando deles depois de clicar no painel. Ex: O jogador clica 2x no item da lista "Taxi". Dai o painel força o jogador que clicou a usar o comando /enableVeh 420 (o 420 ele pega de acordo com o ID que aparece na lista e o comando enableVeh ele usa dependendo do status que aparece na lista. Se estiver como "desativado", ele usa /enableVeh. Se estiver "ativado", ele usa /disableVeh.
    • Dai com esse comando, o mod do Taxi vai aplicar/remover a modificação no Taxi e mandar uma mensagem de confirmação.
  • Como poderia ser:
    • Eu estava pensando em trocar por funções exportadas (call/exports). No entanto na Wiki tem um aviso que essa função é pesada quando executada para chamar funções de outros resources.
    • Cada mod de veículo exportaria sua função que ativa/desativa seu veículo. Logicamente essas funções vão seguir o mesmo padrão, assim como os comandos seguem atualmente. Dai o painel passaria a não precisar mais da permissão especial function.executeCommandHandler (ou acesso Admin).
  • Do jeito que está, além do painel precisar da permissão especial pra funcionar, ele usa triggers para passar o clique do painel (client-side) para o server-side para só então fazer o executeCommandHandler.
  • Já tentei colocar TODOS os veículos no mesmo resource, mas ele estourou o limite de tamanho de segurança do MTA, que passa a não carregar os arquivos excedentes para evitar a queda do servidor. Imagina se eu carregasse isso num server hosteado! Geral ia tomar disconnect!

O que vcs acham? Manter por comando forçado ou trocar por função exportada? (ou uma terceira sugestão)

Share this post


Link to post

eu colocaria exports só porque o sistema ficaria melhor encapsulado, e também eliminaria o serverside.

Share this post


Link to post
2 hours ago, Lord Henry said:
  • Já tentei colocar TODOS os veículos no mesmo resource, mas ele estourou o limite de tamanho de segurança do MTA, que passa a não carregar os arquivos excedentes para evitar a queda do servidor. Imagina se eu carregasse isso num server hosteado! Geral ia tomar disconnect!

Não sabia desse limite por resource, se não fosse essa questão, o melhor seria deixar todos os mods dentro do resource do painel. Não sei qual é esse limite mas para evitar o excesso de resources-mods eu faria um controle em cada um definindo tamanho; pelo menos isso evitaria a quantidade de resources ser muito alta. Também pensei em outras sugestões sobre isso mas pelo trabalho x resultado acho que não vale a pena.

Outra alternativa seria usar triggerEvent no painel chamando o evento para ativar o mod.

Share this post


Link to post
Posted (edited)

triggerEvent funciona para eventos de outros resources?

5 hours ago, Gw8 said:

eu colocaria exports só porque o sistema ficaria melhor encapsulado, e também eliminaria o serverside.

A princípio também achei que não precisaria mais da parte server-side usando exports. Mas depois de uns testes, descobri que não terá como eliminar a parte server-side, pois preciso dele para obter os nomes dos resources de veículos. A função client-side só é capaz de obter o próprio resource.

Edited by Lord Henry

Share this post


Link to post

Funciona, mas pelo que entendi, dessa forma você teria que adicionar eventos novos em cada resource, e no trigger identificar ele de alguma forma - usando o ID do mod no nome do evento por exemplo.

Alternativamente, daria também pra você fazer criando o evento no próprio mod manager e chamando triggerEvent. Então nos outros resources, você iria apenas usar addEventHandler("eventName", root, func) e passar o id lá no triggerEvent, assim você verifica qual modelo substituir e faz o resto.

Exemplo:

-- suponhamos que este é o mod manager
addEvent( 'callClientEvent', true )

addCommandHandler( "replace", function( cmd, value )
	triggerEvent( "callClientEvent", resourceRoot, value )
end)

Resource do mod:

addEventHandler("callClientEvent", root, function( v )
	outputChatBox( "Valor recebido: "..tostring(v) )
end)

Obs: com a primeira alternativa vai funcionar sem precisar ativar o argumento allowRemoteTrigger, já com essa acima, ele deverá ser ativado.

 

Share this post


Link to post

Pois é. Mas qual delas é a mais leve? Se tratando de varias chamadas simultâneas.

Para preencher a lista do painel com os status dos resources, estou usando um loop FOR que vasculha todos os resources e detecta quais são mods de veículos. Quando encontra um, chama um evento exportado dele para obter o status de ativação do resource no cliente. (O resource pode estar ativado mas o veículo desativado no cliente específico).

Share this post


Link to post

Acho a minha segunda alternativa mais viável, leve seria até mais que os dois outros métodos - exports e trigger/executeCommandHandler. Além disso mais fácil para fazer sua tarefa com menos código.

Não tenho 100% de certeza que irá funcionar sem haver imprevistos mas definitivamente vale a pena por em prática.

Share this post


Link to post
Posted (edited)
20 hours ago, Lord Henry said:

triggerEvent funciona para eventos de outros resources?

A princípio também achei que não precisaria mais da parte server-side usando exports. Mas depois de uns testes, descobri que não terá como eliminar a parte server-side, pois preciso dele para obter os nomes dos resources de veículos. A função client-side só é capaz de obter o próprio resource.

não faz sentido isso que voce escreveu, ninguem usa exports em um resource aleatorio, voce precisa do nome dele previamente.

call ( getResourceFromName ( "resource" ), "exportedFunction", 1, "2", "three" )
exports.resource:exportedFunction ( 1, "2", "three" )
exports["resource"]:exportedFunction ( 1, "2", "three" )

e tambem voce consegue utilizar o getResourceFromName e getResourceState para uma pre checagem antes de executar o exports via client.

Edited by Gw8

Share this post


Link to post
Posted (edited)
1 hour ago, Gw8 said:

não faz sentido isso que voce escreveu, ninguem usa exports em um resource aleatorio, voce precisa do nome dele previamente.

Não entendi porque que não fez sentido. Se eu afirmei que precisaria do server-side para obter os resources e verificar os nomes. Em momento nenhum eu disse que usaria exports em um resource aleatório. Você deve estar achando que eu estou dando exports em todos os resources até achar o evento certo, é isso?

1 hour ago, Gw8 said:

e tambem voce consegue utilizar o getResourceFromName e getResourceState para uma pre checagem antes de executar o exports via client.

Não uso getResourceFromName pois não sei o nome dos resources. Eu apenas obtenho todos eles com getResources e depois verifico um por um com loop.
O getResourceState já estou usando pois o painel diferencia os resources ligados e os desligados. Se o resource estiver desligado, ele nem tenta chamar o evento dele.


@DNL291 fiquei meio confuso em meio as mensagens. Só pra confirmar, os dois métodos que vc falou são respectivamente esses? (corrija-me se estiver algo errado)

1. triggerEvent no resource do painel, que vai ativar os eventos criados nos resources pelo addEvent e com addEventHandler. Mas precisa saber os nomes dos eventos de cada resource, ex: ID do veículo junto do nome

-- (painel) [client-side]
triggerEvent ("nomeEvento000", root, parametros) -- 000 seria o ID do veículo que eu supostamente já sei.

-- (resource do veículo) [client-side]
addEvent ("nomeEvento000", true)
addEventHandler ("nomeEvento000", root, function (parametros)
    -- Ativa/Desativa veículo.
end)

2. addEvent no resource do painel, com parâmetro de allowRemoteTrigger = true e com triggerEvent que irá acioná-lo nos outros resources com addEventHandler.

-- (painel) [client-side]
addEvent ("nomeEvento000", true)
triggerEvent ("nomeEvento000", root, parametros)

-- (resource do veículo) [client-side]
addEventHandler ("nomeEvento000", root, function (parametros)
    -- Ativa/Desativa veículo.
end)

Eram essas as alternativas?

Edited by Lord Henry

Share this post


Link to post

Edit: (o tempo pra permitir edição deveria ser maior)

Segundo exemplo corrigido:

-- (painel) [client-side]
addEvent ("nomeEventoGeral", true)
triggerEvent ("nomeEventoGeral", root, 000) -- ID do veículo que eu supostamente já sei.

-- (resource do veículo) [client-side]
addEventHandler ("nomeEventoGeral", root, function (ID)
	if (ID == 000) then
		-- Ativa/Desativa veículo.
	end
end)

 

Share this post


Link to post

Sim, no primeiro método funcionará se deixar o allowRemoteTrigger = false, e isso pode ser vantajoso em performance, mas não posso confirmar, mas o contra seria a quantidade de addEvent's para cada mod. O segundo acho mais viável.

Share this post


Link to post

Pois é... Qual deles é mais leve? Adicionar 1 evento global com allowRemoteTrigger ou adicionar vários eventos diferentes sem allowRemoteTrigger?

Existe alguma forma de testar performance? Sem ser em um servidor cheio de players.

Share this post


Link to post

Acabei escolhendo a primeira alternativa. Vários eventos diferentes sem allowRemoteTrigger, cada um em seu resource de veículo.

Motivo:

  • O server-side do painel obtém todos os resources com getResources e passa um loop FOR entre todos eles, verificando pelo nome quais deles são de veículos.
  • Os resources que forem de veículos, ele salva seus dados (nome, estado de ativação, ID do veículo) numa table temporária. (até então, não ocorre nenhum trigger nos resources, ele apenas verifica os nomes. O estado ele pega com getResourceState e o ID ele pega com os 3 primeiros caracteres do nome do resource.)
  • Depois de terminar o loop, passa a table pro client-side do painel no seguinte formato:
--[[ Supondo que existam os seguintes resources de veículo:
240TaxiBoladao		[running]	No meta.xml: <info name="Taxi Boladão" />
541-1966Ford-GT		[running]	No meta.xml: <info name="Ford GT" />
431onibus_espacial	[loaded]	No meta.xml: (não existe o parâmetro name)
490RangeRover(Sport)	[failed]	No meta.xml: <info name="Range Rover (sport)" />
]]

tableResources = {
	[240] = {"Taxi Boladão", true},
	[541] = {"Ford GT", true},
	[431] = {"", false},
	[490] = {"Range Rover (sport)", false}
}
  • Com a table no cliente, ele verifica o ID que aparece no item da lista que o usuário clicou. Se o ID estiver nessa table, manda o trigger pro evento "renableVeh"..id" onde o ID veio da table.

Se eu fosse fazer do outro jeito, ele ia ativar todos os eventos dos veículos a cada clique.

  • Like 1

Share this post


Link to post

Respondendo sobre allowRemoteTrigger = true: a diferença é que será adicionado para funcionar com triggerClient, e isso forçará uma sincronização com o server.

De qualquer forma, para entender o impacto de uma forma mais precisa, requer um conhecimento de como tudo funciona internamente no mta.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.