Ir para conteúdo
Fórum Script Brasil
  • 0

Plugin - Extensões - Addons


Churc

Pergunta

opa

então tava pensando em fazer um sistema de Plugins, extensões, addons pro

meu sistema, na verdade seria uma extensão mas nós entendemos mais

como Plugins, Addons... vou citar como plugin né rs

Eu iria carregar os plugins da seguinte forma, quando o programa inicia

ele procura por todos os plugins na pasta, e cada plugin tem um Hook Event

onde ele inicia quando determinado evento no programa é iniciado...

O problema é qual a melhor forma de iniciar estes plugins, eu iria fazer um jeito

que eu acho um pouco tosco, primeiro eu faria criando um TList pra cada evento

e na hora de listar os plugins, adicionar aos TList os plugins que tem aquele evento

associado...

exemplo

lstStart: TList; //Esse seria o TList para os plugins de quando o programa inicia...

Depois a cada vez que determinado evento no sistema fosse ocorrer, procurar no

TList daquele evento se há algum plugin para ser chamado, e se houver carregá-lo...

Outra maneira seria criando uma array de um Type-Record guardando informações

dos plugins e os executando conforme os eventos que o mesmo for assimilado...

Bom, alguém já trabalhou com isso, tem alguma idéia ou sabe de algum site, material

que fale sobre?

Qualquer coisa é bem vinda rsr

Abraçoss

Link para o comentário
Compartilhar em outros sites

12 respostass a esta questão

Posts Recomendados

  • 0

Churc, eu ainda não trabalhei com plug-ins não. Mas, pretendo no próximo ano (tá logo aí), começar a modularizar uma aplicação e fazer justamente uso deste tipo recurso.

Neste sentido, o que tenho feito é dar uma olhada pela net e ver o que há implementado, observando suas características e se possível observando fontes. A idéia é descobrir se já existe algo FREE que possa ser aproveitado, ou pelo menos obter conhecimento das funcionalidades necessárias a uma implementação.

Não sei se ajuda muito, mas seguem esses link's são de plug-ins de onde tirei algumas informações/idéias:

- SmartPlugin;

- TMS Plugin Framework;

Esses eu baixei da página Torry - Componentes FREE com código fonte (ainda não implentei nada - só estudando...)

- TPlugin;

- UIL Plugin;

- TMX Plugin Loader;

- WildFireZ Plugin SDK.

[]s

Link para o comentário
Compartilhar em outros sites

  • 0

opa Micheus blzz ;)

Então, eu também tava dando uma estudada em uns plugins,

especialmente o JvPlugin Framework do Project Jedi, deu pra

tirar bastante idéia...

Vou olhar estes ai que você me passou, ai se estiver interessado

podemos montar um esquema de plugins juntos!

Já estou de saída, desejo a você um feliz natal e tudo de bom pra

você e sua família :D

abraçoss

Link para o comentário
Compartilhar em outros sites

  • 0
Vou olhar estes ai que você me passou, ai se estiver interessado

podemos montar um esquema de plugins juntos!

É possível.

Já estou de saída, desejo a você um feliz natal e tudo de bom pra

você e sua família :D

Obrigado e desejo o mesmo a todos os colegas aqui do Script Brasil

[]s

Link para o comentário
Compartilhar em outros sites

  • 0
Vou olhar estes ai que você me passou, ai se estiver interessado

podemos montar um esquema de plugins juntos!

É possível.

Então acho que não vai dar certo desenvolvermos algo junto porque

acredito que seus plugins irão interagir visualmente com o sistema, digo por

exemplo adicionar itens em MainMenus, popupmenus e tal e o meu não rs..

de qualquer forma, se você fosse carregar plugins conforme um evento da

aplicação, como você faria?

exemplo, quando o programa vai fechar teria um evento que eu chamaria de OnFinish

quando o programa carregar os plugins, digo, definir qual é qual, então ele vai associar

os plugins que tiver um Hook no evento OnFinish e armazenar em algum lugar, assim

quando o programa for ser finalizado, ele procurar qual plugin tem um Hook nesse evento

e chamá-lo, passando o evento associado pois um plugin por ter mais de um Hook de

evento...

como/onde você armazenaria estas informações dos plugins?

Pensei em usar uma Array de um Type com informações exemplo

Type
TPluginInfo = packed record
{..}
Events: String; //aqui o plugin passa os eventos que ele terá Hook, exemplo: OnStart;OnFinish;...
end;

e depois pra cada evento do sistema, eu dar um loop na array desse type e procurar e chamar os plugins

que tem o tal evento associado...

Qualquer opinião, sugestão é bem vinda! :D

abração

Link para o comentário
Compartilhar em outros sites

  • 0
...

quando o programa carregar os plugins, digo, definir qual é qual, então ele vai associar

os plugins que tiver um Hook no evento OnFinish e armazenar em algum lugar, assim

quando o programa for ser finalizado, ele procurar qual plugin tem um Hook nesse evento

e chamá-lo, passando o evento associado pois um plugin por ter mais de um Hook de

evento...

como/onde você armazenaria estas informações dos plugins?

Pensei em usar uma Array de um Type com informações exemplo

Type
TPluginInfo = packed record
{..}
Events: String; //aqui o plugin passa os eventos que ele terá Hook, exemplo: OnStart;OnFinish;...
end;

e depois pra cada evento do sistema, eu dar um loop na array desse type e procurar e chamar os plugins

que tem o tal evento associado...

Churc, esses eventos serão, digamos assim, pré-definidos (você citou:OnStart; OnFinish; ...) ?

Porque se forem, você poderia utilizar um array de TList, onde cada linha do array, seria o evento predefinido, e cada item da lista conteria as informações do plugin (que informações você imagina gardar?)

Mas se não forem pré-definidas, acho que você poderia utilizar então um TStringList com os TList. Neste caso você teria no stringlist, a lista de eventos retornados pelos plugins (não duplicados) e na propriedade Objects você armazenaria os TList com as informações sobre os plugins.

Será que era mais ou menos isso ou estou viajando? :huh:

Link para o comentário
Compartilhar em outros sites

  • 0

Churc, esses eventos serão, digamos assim, pré-definidos (você citou:OnStart; OnFinish; ...) ?

Porque se forem, você poderia utilizar um array de TList, onde cada linha do array, seria o evento predefinido, e cada item da lista conteria as informações do plugin (que informações você imagina gardar?)

Mas se não forem pré-definidas, acho que você poderia utilizar então um TStringList com os TList. Neste caso você teria no stringlist, a lista de eventos retornados pelos plugins (não duplicados) e na propriedade Objects você armazenaria os TList com as informações sobre os plugins.

Será que era mais ou menos isso ou estou viajando? :huh:

opa, não está viajando não :D

Isso, serão pré-definidas...

Então, uma array de TList é realmente pode ser uma boa idéia!

Bom usando TList, pegaria a Index da array baseada nos eventos

e armazenaria apenas o nome do plugin em cada linha da TList

Apenas o nome do arquivo de plugin eu armazenaria na TList

pois então na hora do evento, eu apenas carregaria o plugin e

mandasse a informação pra ele... e no plugin ele ia pegar o evento

passado e fazer o que for pra fazer... exemplo bem simples

Plugin.dll

Function PluginEvent(szEvent: String): Boolean; StdCall;
begin
if (lowercase(szEvent) = 'onexit') then
bla.free;
end;
Usando TList, será que não vai ocupar muito memória do que se criar um array de um Type? exemplo
type
TPluginInfo = packed record
  Plugin: String;
  Events: String;
end;

var
aPlugins: array [0..255] of TPluginInfo;
no caso quando o programa inicializa, eu listaria em uma StringList todos os arquivos de plugins, e carregaria um por um pedindo os eventos no qual ele se associa exemplo (fiz fora do delphi rs)
for i := 0 to slPlugins.Count - 1 do
begin
  hHandle := LoadLibrary(sl[i]);
  {...}
  PluginEvents := GetProcAddress(....
  if Assigned(PluginEvents) then
  begin
    aPlugins[i].Plugin := sl[i];
//o plugin retorna os eventos que ele quer se
//associar separados por (ponto e vírgula) exemplo: onStart;onExit;
    aPlugins[i].Events := PluginEvents;
  end;
  slPlugins.Free;
end;

Então ai pra cada evento no programa eu daria um loop nessa

array e comparava o evento que está acontecendo se ele está

em .Events do plugin... usando Pos() por exemplo...

e se o evento que está acontecendo for encontrado em .Events

daquele array eu carregaria o Plugin, pegando a informação

em .Plugin da array e passaria o evento pro plugin...

Se não ocupar muita memória eu vou usar TList mesmo né

valeu ai pela ajuda

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
...

Isso, serão pré-definidas...

...

mandasse a informação pra ele... e no plugin ele ia pegar o evento

passado e fazer o que for pra fazer... exemplo bem simples

Plugin.dll

Function PluginEvent(szEvent: String): Boolean; StdCall;
begin
if (lowercase(szEvent) = 'onexit') then
bla.free;
end;
Sendo pré definidas, não ficaria melhor o uso de constantes para indicar o tipo de evento? Neste caso, sua função poderia utilizar um CASE e não if's testando string.
Usando TList, será que não vai ocupar muito memória do que se criar um array de um Type? exemplo
type
TPluginInfo = packed record
  Plugin: String;
  Events: String;
end;

var
aPlugins: array [0..255] of TPluginInfo;
Apesar de não ocupar muita memória, o uso de array de um type, pode ser uma saída simples, mas a questão de limitar e, ao mesmo tempo, pré alocar 256 posições será que é uma boa idéia. Complicado usar uma dinâmica? Também imaginei que seria armazenado apenas o nome do plugin (não os eventos - o que não requer um record), já que o nome dele será repetido em outros eventos caso ele os processe.
...
for i := 0 to slPlugins.Count - 1 do
begin
  hHandle := LoadLibrary(sl[i]);
  {...}
  PluginEvents := GetProcAddress(....
  if Assigned(PluginEvents) then
  begin
    aPlugins[i].Plugin := sl[i];
//o plugin retorna os eventos que ele quer se
//associar separados por (ponto e vírgula) exemplo: onStart;onExit;
    aPlugins[i].Events := PluginEvents;
  end;
  slPlugins.Free;
end;

Então ai pra cada evento no programa eu daria um loop nessa

array e comparava o evento que está acontecendo se ele está

em .Events do plugin... usando Pos() por exemplo...

e se o evento que está acontecendo for encontrado em .Events

daquele array eu carregaria o Plugin, pegando a informação

em .Plugin da array e passaria o evento pro plugin...

Bom, eu imaginei que se você tem uma lista dos plugins na stringlist, ao obter a lista de eventos do plugin, você faria uma "triagem", onde cada evento corresponde a uma posição na lista de eventos, e daí, nesta posição, você inclui o nome do plugin numa outra lista. Deste modo ao ser disparado o evento, você tem o índice no array de eventos (direto) e com isso acessa a lista de plugins que você tem que acionar. (não era isso?)

* quando falo lista, pode ser um array, ok?!

[]s

Link para o comentário
Compartilhar em outros sites

  • 0

Sendo pré definidas, não ficaria melhor o uso de constantes para indicar o tipo de evento? Neste caso, sua função poderia utilizar um CASE e não if's testando string.

Putz totalmente eheh eu nem pensei na possibilidade, vou utilizar constantes mesmo fica muito mais fácil e organizado...

Apesar de não ocupar muita memória, o uso de array de um type, pode ser uma saída simples, mas a questão de limitar e, ao mesmo tempo, pré alocar 256 posições será que é uma boa idéia. Complicado usar uma dinâmica?

Também imaginei que seria armazenado apenas o nome do plugin (não os eventos - o que não requer um record), já que o nome dele será repetido em outros eventos caso ele os processe.

Então sabe porque se no caso eu for usar Type eu pretendo colocar um lugar pra armazenar os Eventos do plugin, pra não ficar carregando a cada evento todos os plugins e ficar passando o evento, acho que pode prejudicar na performance da aplicação, dar um LoadLibrary e FreeLibrary em todos os plugins a cada evento sendo que se eu der um loop e apenas chamar os plugins que tem aquele evento associado acho que vai ser bem melhor...

Claro não precisa ser especificamente uma array, apenas um exemplo do porque eu queria armazenar os eventos dos plugins rs

Bom, eu imaginei que se você tem uma lista dos plugins na stringlist, ao obter a lista de eventos do plugin, você faria uma "triagem", onde cada evento corresponde a uma posição na lista de eventos, e daí, nesta posição, você inclui o nome do plugin numa outra lista. Deste modo ao ser disparado o evento, você tem o índice no array de eventos (direto) e com isso acessa a lista de plugins que você tem que acionar. (não era isso?)

* quando falo lista, pode ser um array, ok?!

[]s

Não entendi muito bem o que você quis dizer, eu vo fazer um exemplo aqui ai vo postar pra você ver se você acha que fica legal ou não, mais fácil né, e assim até pode colocar do seu jeito se puder é claro :D

ps: só não sei se sai hj rs amanhã ainda trabalho

valeu ai

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
Apesar de não ocupar muita memória, o uso de array de um type, pode ser uma saída simples, mas a questão de limitar e, ao mesmo tempo, pré alocar 256 posições será que é uma boa idéia. Complicado usar uma dinâmica?

Também imaginei que seria armazenado apenas o nome do plugin (não os eventos - o que não requer um record), já que o nome dele será repetido em outros eventos caso ele os processe.

Então sabe porque se no caso eu for usar Type eu pretendo colocar um lugar pra armazenar os Eventos do plugin, pra não ficar carregando a cada evento todos os plugins e ficar passando o evento, acho que pode prejudicar na performance da aplicação, dar um LoadLibrary e FreeLibrary em todos os plugins a cada evento sendo que se eu der um loop e apenas chamar os plugins que tem aquele evento associado acho que vai ser bem melhor...

Claro não precisa ser especificamente uma array, apenas um exemplo do porque eu queria armazenar os eventos dos plugins rs

Bom, se entendi direito, cada DLL será um plugin, que poderá responder a diferentes eventos. É isso.

Se for, você vai ter que carregar ela (DLL) ao menos uma vez para obter a lista de eventos que o plugin manipula, certo?!

Vou exemplificar o que eu estava pensando:

const 
  OnStart = 1;
  OnExit  = 2;
  OnDraw = 3;

- Relação dos plugins a carregar(instalados)
ListaPlugins ('Plug1', 'Plug2', 'Plug3', 'Plug4')

- Relação dos plugins que respondem a determinado evento
ListaEventos(('Plug1', 'Plug2', 'Plug3'),   // OnStart
             ('Plug1', 'Plug2', 'Plug3'),   // OnExit
             ('Plug2', 'Plug4'))  //OnDraw
Daí para responder ao evento OnExit, iria na ListaEventos e passaria por todos Plugins para execução do evento:
for Idx := Lo(ListaEventos(OnExit)) to Hi(ListaEventos(OnExit)) do
begin
  Carrega/executa plugin -> ListaEventos(OnExit)(Idx) passando o evento OnExit
  ..
end;

Bom, eu imaginei que se você tem uma lista dos plugins na stringlist, ao obter a lista de eventos do plugin, você faria uma "triagem", onde cada evento corresponde a uma posição na lista de eventos, e daí, nesta posição, você inclui o nome do plugin numa outra lista. Deste modo ao ser disparado o evento, você tem o índice no array de eventos (direto) e com isso acessa a lista de plugins que você tem que acionar. (não era isso?)

* quando falo lista, pode ser um array, ok?!

Não entendi muito bem o que você quis dizer
Com os detalhes acima, será que ficou mais claro?

eu vo fazer um exemplo aqui ai vo postar pra você ver se você acha que fica legal ou não, mais fácil né, e assim até pode colocar do seu jeito se puder é claro :D

ps: só não sei se sai hj rs amanhã ainda trabalho

Ok. Amanhã estarei on-line somente a noite.

Link para o comentário
Compartilhar em outros sites

  • 0

opa

Bom, se entendi direito, cada DLL será um plugin, que poderá responder a diferentes eventos. É isso.
Exatamente!
Se for, você vai ter que carregar ela (DLL) ao menos uma vez para obter a lista de eventos que o plugin manipula, certo?!
Isso mesmo!

Fiz um pequeno sistema para testar, "acredito" eu que esteja até

bom, não vi meio de melhorá-lo, claro levando em conta que isso

é só para testes, somente a estrutura é válida as informações são

inúteis rs

Da uma olhada aqui

Qualquer opinião, crítica, sugestão será bem vinda!

ps: o carregamento dos plugins e execução dos mesmos estão no

source principal...

valeu!

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Churc, a título de implementação de teste, acho que era isto mesmo; o uso de array deixou-o bem simples.

Apenas acho que será mais conveniente, que a declaração das constantes e tipo (TInfoPlugin e similares) fiquem numa unit separada, a ser compartilhada pelos projetos. Também acho conveniente que comece a numerar os eventos a partir de 1 e não zero.

Outra coisa, haverá a possibilidade de existirem mais que 32 eventos diferentes? Se ouver, talvez tenha que ser encontrada outra solução (apesar que tem o tipo int64).

Não sei com que frequência seus plugins serão acionados, entretanto valeria avaliar se vale à pena carregar a DLL a cada chamada a um evento e descarregá-la depois.

Quando for necessário carregar a DLL para executar um evento, você não a descarrega mais da memória. Só no término do programa.

Então você poderia utilizar a propriedade Objects da sua lista de plugins para armazenar o handle do plugin carregado. Na hora de carregar, checa se já está inicializado, se não estiver carrega, do contrário utiliza o handle alocado.

[]s

Link para o comentário
Compartilhar em outros sites

  • 0

opa Micheus

Apenas acho que será mais conveniente, que a declaração das constantes e tipo (TInfoPlugin e similares) fiquem numa unit separada, a ser compartilhada pelos projetos. Também acho conveniente que comece a numerar os eventos a partir de 1 e não zero.
Isso realmente eu vou deixar em uma unit Global, que contém todas as definições, constantes, etc... a API rs

Quanto a começar a enumerar do 1 e não do 0 vou fazer isso sim, alias ia deixar 0 mas uma opinião é

sempre bem vinda... mas tem algum problema em iniciar do 0? pensei até em criar números sem sentidos tipo ON_START = 58752; rs

Outra coisa, haverá a possibilidade de existirem mais que 32 eventos diferentes? Se ouver, talvez tenha que ser encontrada outra solução (apesar que tem o tipo int64).
nem tinha pensado nisso mas ainda bem que não vai ter não, deve chegar a uns 15 somente acho que nem vou precisar mudar isso

Não sei com que frequência seus plugins serão acionados, entretanto valeria avaliar se vale à pena carregar a DLL a cada chamada a um evento e descarregá-la depois.

Quando for necessário carregar a DLL para executar um evento, você não a descarrega mais da memória. Só no término do programa.

Então você poderia utilizar a propriedade Objects da sua lista de plugins para armazenar o handle do plugin carregado. Na hora de carregar, checa se já está inicializado, se não estiver carrega, do contrário utiliza o handle alocado.

então, serão com pouca frequência mas sua idéia foi perfeita, vou até pensar na possibilidade de por na função que carrega alguma propriedade pra manter ou não carregada e fazer como você falou, colocar uma variável no Type armazenando o Handle da DLL e carrega-la conforme necessário...

Micheus valeu pela força! :D

abraço

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      652k
×
×
  • Criar Novo...