Architektura pluginów - jakieś przykłady?

Architektura pluginów - jakieś przykłady?
0

Cześć,
czy ktoś mógłby podać przykład jakiegoś open-sourceowego IDE pisanego w Delphi? Nie mogę wydumać sensownej architektury pluginów dla mojego projektu, chętnie popatrzyłbym jak inni rozwiązali problem ...

Z góry dzięki!

JU
  • Rejestracja:około 22 lata
  • Ostatnio:około 2 miesiące
  • Postów:5042
0

W necie faktycznie jest dość mało na ten temat. Znalazłem jedną bardzo dobrą stronę(w dodatku polską ;>) i się udało.

Może napisz najpierw co chcesz osiągnąć i poszukaj info o pisaniu pluginów w Delphi.

AD
  • Rejestracja:około 18 lat
  • Ostatnio:5 miesięcy
  • Postów:206
0

Juhas rzuć linkiem.

Ja uważam że jest to mało znane w naszych kręgach ze względu na jedną sprawę. Programiki są nieduże a rozszerzając jakiś program dodatkowo poprawia się błędy, które w nim powstają.
Moim zdaniem należy zrobić coś w stylu zewnętrznej biblioteki z funkcjami programu i ją modyfikować wówczas ona będzie tym pluginem. Jeśli chodzi o jego konstrukcję to też mnie ciekawi :)

entek
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 4 lata
0

W projekcie SharpE jest sporo pluginów :)

http://www.sharpe-shell.org/page.php?7

migajek
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 6 lat
  • Postów:370
0

Juhas, bądź tak miły i daj linka jakiegoś :) Zwróć uwagę że wiem co chcę osiągnąć - piszę własne IDE dla kilku języków programowania, i zamiast upychać funkcje do głównego programu chciałbym by były to pluginy.

Przykładowo, w programie mamy obsługę otwierania plików do edycji [używając SynEdita oczywiście ;) ]. Potrzebne będą podpowiedzi do kodu, i to już bym chciał by było realizowane przez plugin. Podobnie debugger - jest zaimplementowany w programie, ale fajnie by było gdyby pluginy miały do niego dostęp - w ten sposób można by np po stronie plugina zrealizować podpowiedzi do kodu w czasie debuggowania (podgląd zmiennych itp).

Czemu tak się upieram przy pluginach? Otóż z doświadczenia wiem że w jednym programie to już będzie za dużo ... po to przepisuje program od nowa by uniknąć starych błędów. Między innymi właśnie tego ...

Obecnie jestem w trakcie implementowania prostego (na razie) systemu pluginów opartego o COMy. Tyle tylko, że niestety - aby udostępnić jakąś część programu muszę napisać wrappera - u mnie zrealizowałem to w ten sposób (kawałek [pseudo]kodu mówi więcej niż 1000 słów)

Kopiuj
type
  TSDKEditor = class(TObject, ISDKEditor) //
  private
   fEditor: TSynEdit;
  public
   function GetXY: TPoint; 
  end;

Tak więc w momencie gdy plugin chce dostęp do np aktywnego pliku, z odpowiedniego serwisu udostępnionego przez aplikację wywołuje metodę "GetActiveEditor" która tworzy obiekt TSDKEditor ustawiając mu zmienną fEditor - i zwraca to jako interfejs ISDKEditor.

Plugin sobie cośtam wywołuje, obiekt zaś wykonuje odpowiednie akcje na fEditor.

W teorii proste, w praktyce - pisanie wrapperów to mordęga. A później jeszcze debuggowanie, dbanie o pamięć ... masakra [glowa]

Stąd chciałbym podpatrzeć jakąś metodę "jak to robią profesjonaliści"

adydan - w moim przypadku akurat to nie jest potrzebne, główny program raczej ma docelowo być mocno okrojony ...

PS. temat pisałem ja tylko nie chciało mi się logować :P


JU
  • Rejestracja:około 22 lata
  • Ostatnio:około 2 miesiące
  • Postów:5042
0

Linkiem nie rzucę, bo nie pamiętam. Ale autor strony to zdaje się Grzegorz Skoczylas, czy Jerzy Skoczylas. Jakoś tak. Tak więc wpiszecie to w google i coś powinno wyjść :)

Są dwie metody pisania pluginów - z użyciem obiektów COM, lub z użyciem zwykłych dll.
Ja u siebie robię to za pomocą zwykłych dll, bo nie potrzebowałem obiektów COM.

Po krótce wygląda to tak, że jest interfejs, w którym są wszystkie metody jakie plugin musi posiadać.
Plugin udostępnia na zewnątrz(eksportuje) np. tylko jedną funkcję, która zwraca jego obiekt(zdaje sie jako interfejs) i od tej pory z poziomu programu głównego można się porozumiewać z pluginem. Ponadto można stworzyć drugi interfejs - interfejs aplikacji głównej, dzięki któremu plugin będzie mógł wtedy, kiedy potrzebuje wykonać jakąś operację w programie głównym(a konkretnej wywołać udostępnioną metodę z programu głównego).

Może trochę to niejasno napisałem, ale na stronie pana Skoczylasa jest całkiem ok opisane to. Z jakimiś tam przykładami. Pamiętam, że miałem na początku duże problemy ze zwróceniem obiektu pluginu do programu głównego(jakieś duże problemy z pamięcią), ale w końcu dałem se radę. Tak więc jak coś, to mogę służyć radą :D

Aha, ważna rzecz: NIE UŻYWAJCIE SHAREMEM, róbcie tak biblioteki, żeby chodziły bez tego. Bo z tego, co wiem, jeśli będzie inaczej zaprojektowane, no to pluginy będą mogłby być tylko pisane w Delphi, a nie o to chodzi :)

Tak więc głównie, zero używania stringów, tablic dynamicznych itp. tworzyw jako parametrów lub typów zwracanych funkcji.

AM
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 14 lat
  • Postów:16
0

Proponuję zajrzeć do JVCL, jest tam PluginWizard i kilka przykładów zastosowań. Rozwiązanie to jest oparte o dynamicznie ładowane dll'ki.


Andrzej M
migajek
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 6 lat
  • Postów:370
0

Juhas, wprawdzie artykułu nie czytałem (zaraz przeczytam, dla zainteresowanych: http://gskoczylas.rekord.pl/index.php?page=http://gskoczylas.rekord.pl/Delphi/PlugIn_PL.php ) ale powiem Ci ze u mnie działa to teraz dokładnie identycznie jak opisane przez Ciebie rozwiązanie. Tyle że używam od dawna FastMM4 więc w kwestii ShareMem ... :]

Dla mnie ważnym problemem jest kwestia przechwytywania zdarzeń. Przykładowo, zmiana aktywnej zakładki w programie - i jak o tym powiadomić plugin?
Myślałem nad kilkoma rozwiązaniami, np implementowany po stronie plugina interfejs I...EventHandler, który byłby rejestrowany w programie - następnie wszystkie zarejestrowane w programie miałyby wywoływaną odpowiednią metodę...

a może coś na wzór windowsowych Messages z kilkoma parametrami? ...

andy-m: dzięki, znam :) ale to nie w tym rzecz, mi nie chodzi o kwestię ładowania bibliotek i udostępniania odpowiednich interfejsów. Mi chodzi o zaprojektowanie sensownej architektury...


JU
  • Rejestracja:około 22 lata
  • Ostatnio:około 2 miesiące
  • Postów:5042
0
migajek napisał(a)

Juhas, wprawdzie artykułu nie czytałem (zaraz przeczytam, dla zainteresowanych: http://gskoczylas.rekord.pl/index.php?page=http://gskoczylas.rekord.pl/Delphi/PlugIn_PL.php ) ale powiem Ci ze u mnie działa to teraz dokładnie identycznie jak opisane przez Ciebie rozwiązanie. Tyle że używam od dawna FastMM4 więc w kwestii ShareMem ... :]
FastMM to lepsza wersja ShareMem, a więc też nie powinieneś jej używać, jeśli chcesz mieć możliwość pisania pluginów w innych językach niż Delphi.

Dla mnie ważnym problemem jest kwestia przechwytywania zdarzeń. Przykładowo, zmiana aktywnej zakładki w programie - i jak o tym powiadomić plugin?

Mniej więcej tak jak napisałeś. Po prostu w odpowiednim momencie wywołujesz odpowiednią metodę w pluginie. Tylko teraz pytanie czy to ma być coś w sensie: "ActiveTabChanged", czy bardziej ogólnie "AnyChange" :P
W drugim przypadku oczywiście nie obejdzie się bez jakiś parametrów, ale to już Ty wiesz co potrzebujesz.

AM
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 14 lat
  • Postów:16
0

Proponując JVCL miałem na myśli zajrzenie do kodu kontrolek związanych z PluginWizardem i ich analizę a nie koniecznie żywcem wykorzystanie gotowca.

Pozdrawiam


Andrzej M
migajek
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 6 lat
  • Postów:370
0
Juhas napisał(a)

FastMM to lepsza wersja ShareMem, a więc też nie powinieneś jej używać, jeśli chcesz mieć możliwość pisania pluginów w innych językach niż Delphi.
Zgadza sie, jest to lepszy manager pamieci dla Delphi :) fakt, uzywajac go nie moge przekazywac stringow, obiektow itp - ale wole chyba poswiecic inne jezyki (nie sadze by ktos chcial szybko pisac pluginy dla mojego programu) na rzecz wygody przy pisaniu modulow w Delphi :) a ze uzywam FastMM zamiast ShareMem to nie dotyczy mnie problem z borlandmm.dll (czy jak sie zwala ta biblioteczka) ... to mialem na mysli ;)

Tylko teraz pytanie czy to ma być coś w sensie: "ActiveTabChanged", czy bardziej ogólnie "AnyChange" :P
W drugim przypadku oczywiście nie obejdzie się bez jakiś parametrów, ale to już Ty wiesz co potrzebujesz.

Dokladnie, zapewne w przypadku "AnyChange" bym to rozwiazal tak jak w Windows Messages - ID zdarzenia, i kilka parametrow ;)

andy-m: owszem, to tak :) ale ja bardziej pytam o takie aspekty jak omawiane z Juhasem :P


Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)