Logo Hardware.com.br
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas

Programação orientada a plugins

#1 Por tpcvasco 30/11/2015 - 15:05
Comecei a estudar o assunto, querendo fazer uma aplicação que pudesse ser estendida de forma simples, através de plugins.
O problema é q, até agora, encontrei apenas exemplos simples de plugins, do tipo que faz apenas algum cálculo a mais... Isso não é um plugin.... rsrs
O q eu entendi até agora (me corrijam se eu estiver errado), no ponto do código q eu achar q pode haver alguma brecha para uma funcionalidade nova na minha app, eu chamo a API (q eu criei) de algum plugin que, porventura, estiver carregado. Isso é ok para uma aplicação específica, com novas funcionalidade limitadas àquele escopo.
Mas e aplicações grandes, tipo Eclipse ou Firefox (ele chama plugin de extension, mas dá no mesmo...)? Essas apps possuem plugins das mais diversas naturezas, q podem fazer coisas nos momentos mais bizarros: ao abrir arquivo, ao fechar aba, ao abrir um menu, ao selecionar alguma parte da tela, mudar várias configurações, cores, etc, etc,etc.... Aí eu fico me perguntando: será q, dentro do código desses programas, em TODO momento os métodos das APIs de plugin são chamados, prevendo q possa ter uma ação de algum plugin alí? Se é isso mesmo, como isso pode ser eficiente? Se não é isso, como então?

Desculpem, eu sei q é uma dúvida bem genérica em relação a um problema bem específico, mas espero q tenha sido claro.
"Milhouse: - Médicos e bombeiros são heróis.
Bart Simpson: - Olha, as casas continuam pegando fogo e as pessoas continuam doentes. Os verdadeiros heróis são os Schwarzenegger's, os Stallone's, e, em menores proporções, os Vandame's..."
Shura16
Shura16 Ubbergeek Registrado
2.5K Mensagens 601 Curtidas
#2 Por Shura16
30/11/2015 - 16:33
As funcionalidades do seu plugin não precisam ser exatamente no mesmo escopo da aplicação principal.

Pense em uma aplicação desktop, com um menu. Esse menu seria público (podendo ser acessado por outras classes externamente). Então eu chamaria este menu (da minha classe externa) e adicionaria um item de menu.

O meu item de menu por sua vez chama uma outra tela que realiza determinada funcionalidade.

A cada inicialização do programa, eu verifico se há algum plugin instalado e mando carregar um método que seria padrão.
Coragem não é ausência de medo e sim o controle dele.

Linux em casa!
Windows 10, na empresa!
Agora: Android no bolso!
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#3 Por tpcvasco
30/11/2015 - 19:36
O meu problema não é com o menu, em relação a isso eu estou tranquilo, pq ao se clicar no menu, uma ação será realizada. Meu problema são ações dos plugins "não previstas".
Vou dar o exemplo do q estou imaginando pra ver se fica mais claro: estou pensando em criar um app de um jogo de tabuleiro baseado em criaturas. Eu queria criar um jogo que permitisse expansões, com novas e diferentes criaturas através de plugins.
Acontece q as novas criaturas podem ter poderes dos mais variados... Alguns poderes só funcionam no início de cada rodada, outros no meio, outros no final, outros poderes só funcionam em determinadas condições... Um poder poderia, por exemplo, durar várias rodadas, outro poder poderia ser ficar "escondido" no jogo e reaparecer em um determinado momento.
Enfim, como eu posso programar a chamada do "poder" da criatura, se ela pode acontecer em qq momento do jogo (e inclusive durar vários loops)? Qual seria a melhor forma de montar esse código?
"Milhouse: - Médicos e bombeiros são heróis.
Bart Simpson: - Olha, as casas continuam pegando fogo e as pessoas continuam doentes. Os verdadeiros heróis são os Schwarzenegger's, os Stallone's, e, em menores proporções, os Vandame's..."
Shura16
Shura16 Ubbergeek Registrado
2.5K Mensagens 601 Curtidas
#4 Por Shura16
01/12/2015 - 09:04
Tecnicamente não sei fazer isso, mas a ideia seria verificar essas possibilidades. Isso vai virar quase uma inteligência artificial.

Já vi isso acontecer em outros jogos. Basicamente você teria uma base de dados com os dados das criaturas.

No próprio banco de dados você tem os poderes disponíveis bem como scripts para cada poder que são executados durante o mesmo.

O pessoal costuma usar alguma linguagem de script para tal como Lua, Perl ou Python.

Então, em caso de querer aumentar as criaturas ou novos poderes, o seu plugin insere os dados no banco e os arquivos de imagem e som quando necessário.
Coragem não é ausência de medo e sim o controle dele.

Linux em casa!
Windows 10, na empresa!
Agora: Android no bolso!
Fergo
Fergo Highlander Registrado
9.3K Mensagens 1.1K Curtidas
#5 Por Fergo
03/12/2015 - 14:43
Normalmente os plugins são implementados através de classes abstratas ou interfaces. Essas classes fornecem os métodos padrão que toda classe derivada deverá implementar, sendo que alguns desses métodos são obrigatoriamente chamados pelo aplicativo principal. É meio complicado de explicar, mas usando o seu exemplo do jogo talvez fique mais fácil:

É comum um jogo possuir alguns métodos padrão como "Start", chamada na primeira vez que algo inicia ou é instanciado, "Update", que é chamada eternamente dentro do gameloop (onde ocorre a lógica do jogo, processamento de entrada, etc) e "Draw", que também é chamada constantemente e cuida da parte de renderização propriamente dita. Imaginando que você queria implementar um sistema de plugins para esse jogo, você pode criar uma interface com o protótipo desses três métodos, que deverão ser obrigatoriamente implementados pela classe que herda a interface. Você também precisa herdar a classe global do aplicativo, para que você tenha acesso ao que está acontecendo dentro dele.

No caso, a interface:
[code=C#]
namespace MeuJogo {
interface IPlugin {
void Start();
void Update();
void Draw();
}
}
[/code]

Um plugin:
[code=C#]
//Esse plugin acessaria a posicao da camera e incrementaria 5 no eixo X
namespace MeuJogo {
class MeuPlugin : IPlugin {
void Start() {
//insira o código que seria rodado apenas uma vez
}

void Update() {
camera.position.x += 5;
}

void Draw() {
//bla bla bla
}
}
}
[/code]

Dessa forma, dentro do jogo principal, você pode iterar entre todos os plugins carregados e chamar suas respectivas funções, por exemplo:

[code=C#]
namespace MeuJogo {
public void Update() {
//Aqui você faz o processamento do jogo em si, entrada, lógica, etc...

//E aqui você processa o método Update() de cada plugin
foreach (plugin in todosPlugins) {
plugin.Update();
}
}
}
[/code]

Não sei se era isso que você precisava, mas essa é forma mais comum de trabalhar com plugins em linguagens orientadas a objetos. Se estiver trabalhando com uma linguagem de código nativo, você vai precisar usar exports e coisas do tipo para conseguir compilar uma DLL externa.
Site pessoal www.fergonez.net
Portfolio
www.fbirck.com
Artigos
Informática
tpcvasco
tpcvasco General de Pijama Registrado
2.9K Mensagens 330 Curtidas
#6 Por tpcvasco
08/12/2015 - 10:54
Fergo disse:
Normalmente os plugins são implementados através de classes abstratas ou interfaces. Essas classes fornecem os métodos padrão que toda classe derivada deverá implementar, sendo que alguns desses métodos são obrigatoriamente chamados pelo aplicativo principal.


Era esse meu entendimento mesmo. Meu grande problema, no fundo, é ter certeza q meu programa vai conseguir prever de antemão todas as possibilidades de plugins q podem existir. Enfim, programar o "core" da aplicação de tal modo q seja bem genérica para aceitar qq novo plugin, q possa fazer coisas q eu não pensei.

Fergo disse:
Dessa forma, dentro do jogo principal, você pode iterar entre todos os plugins carregados e chamar suas respectivas funções, por exemplo:

[code=C#]
namespace MeuJogo {
public void Update() {
//Aqui você faz o processamento do jogo em si, entrada, lógica, etc...

//E aqui você processa o método Update() de cada plugin
foreach (plugin in todosPlugins) {
plugin.Update();
}
}
}
[/code]


Então, outra preocupação minha é a eficiência. Será q isso é eficiente? Vamos supor q eu tenha 100 plugins (criaturas diferentes), será q iterar por todas elas não será muito custoso (e as vezes desnecessário, já q muitas vezes a criatura não vai ter ação naquele "turno" do jogo)?
E no meu caso específico, cada "turno" tem 5 fases diferentes (pode até ter mais) e as criaturas podem ter ações em cada um desses turnos, então teria esse loop foreach em cada uma das 5 fases...
Ou seja, pelo q vc explicou até agora meu entendimento tava certo, mas será q esse é o melhor modo?

Fergo disse:
Não sei se era isso que você precisava, mas essa é forma mais comum de trabalhar com plugins em linguagens orientadas a objetos. Se estiver trabalhando com uma linguagem de código nativo, você vai precisar usar exports e coisas do tipo para conseguir compilar uma DLL externa.


Não se preocupe com isso, estou programando em Java.
"Milhouse: - Médicos e bombeiros são heróis.
Bart Simpson: - Olha, as casas continuam pegando fogo e as pessoas continuam doentes. Os verdadeiros heróis são os Schwarzenegger's, os Stallone's, e, em menores proporções, os Vandame's..."
Fergo
Fergo Highlander Registrado
9.3K Mensagens 1.1K Curtidas
#7 Por Fergo
09/12/2015 - 20:41
Talvez não seja o mais eficiente, mas imagino que seja o com melhor "custo benefício". Como você mencionou o Java, dê uma olhada no sistema de plugins para o Minecraft, que também é programado nessa linguagem. Ele funciona basicamente da forma que mostrei:

http://wiki.bukkit.org/Plugin_Tutorial
Site pessoal www.fergonez.net
Portfolio
www.fbirck.com
Artigos
Informática
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal