// krótki opis mojej wizji ekg-2.0
// 20030416 wojtekka

jeśli dobrniesz do końca tekstu, byłbym bardzo wdzięczny za komentarze
i sugestie. nie chcę robić niczego wbrew reszcie świata.

wszystko wyrzucić do pluginów. ekg samo w sobie nie powinno umieć się
z niczym łączyć, ani nic wyświetlać. ma zawierać funkcje obsługi pluginów,
obsługi komend, obsługi zmiennych i kilku kawałków kodu, które mogą być
dzielone między pluginami (np. formatowanie tekstu, konferencje, przypisane
klawisze). nie wszystkie pluginy muszą być ładowane dynamicznie. kilka na
pewno będzie domyślnie linkowanych statycznie -- chodzi o możliwość łatwego
pozbycia się zależności głównej binarki od wielu bibliotek i zachowanie
jednolitego API.

do głowy przychodzi mi kilka klas pluginów:

1) pluginy interfejsu użytkownika -- czyli to, co do tej pory robią
   ui-readline i ui-ncurses. dojdzie do tego plugin obsługujący rurki,
   sockety lokalne i inne sposoby sterowania klientem.

2) pluginy protokołów -- priorytetem ekg będzie zawsze ,,wzorcowa'' obsługa
   Gadu-Gadu, ale nie można stać w miejscu. wielu ludziom brakuje porządnego
   klienta Jabbera pod konsolę. co więcej, istniejący kod konferencji, po
   lekkim rozszerzeniu może stanowić podstawy pod obsługę irca. niestety
   ciężko będzie od razu zaplanować API pozwalające na napisanie obsługi
   dowolnego protokołu na ziemi, więc każdy nowy plugin tak czy inaczej będzie
   wymagał drobnych zmian w ekg. ale będą mogły się rozwijać niezależnie.

3) pluginy szyfrujące -- póki co, jest tylko SIM, ale nic nie stoi na
   przeszkodzie, żeby ekg obsługiwało prostsze sposoby szyfrowania, np.
   symetryczne z hasłem.

4) pluginy skryptów -- mamy pythona. znajomy poradził, żeby umożliwić pisanie
   skryptów również w innych językach. nie powinno być trudne, zwłaszcza, że
   obsługa skryptów ogranicza się do ładowania, usuwania, wykonywania poleceń
   i wywoływania funkcji. API takiego pluginu można ograniczyć do kilku
   funkcji. poza tym, za pomocą skryptów powinno być możliwe tworzenie każdej
   klasy pluginów.

5) pluginy dźwięku -- jest tylko oss, a to nie wszystkim pasuje. dodawanie
   dziesiątek #ifdefów do obsługi różnych systemów jest bez sensu. poza tym,
   jeśli zrobić plugin, który zamiast z mikrofonu, czyta z socketa, mamy
   proste radio, które chociaż jakością nie grzeszy, zajmuje bardzo małe
   pasmo. do tego możnaby też doliczyć pluginy kodujące dźwięk, żeby inne
   pluginy mogły poprosić od razu o strumień GSM czy MP3.

6) pluginy historii -- widać, że nie wszystkim odpowiada sposób logowania
   w ekg. tutaj wystarczy w zasadzie jedna funkcja dopisująca do historii
   określone zdarzenie, ale możliwość odczytu też by się przydała, żeby móc
   w ekg przeglądać historię (ach, pobożne życzenia!). póki co, są już
   pomysły na 4 pluginy: legacy-ekg, all-new-kadu, sql i xml. głupio byłoby
   linkować ekg z sqlem i expatem. 

6) pluginy ogólnego przeznaczenia -- tutaj pasowałby chociażby ioctld, który
   dodaje dwie nowe komendy, więc ciężko podpiąć go pod interfejs użytkownika.
   pasowałby też każdy skrypt, który nie pełni roli jakiegoś plugina.

każdy plugin dodawałby swoje komendy, zmienne i zdarzenia. mógłby wywoływać
zdarzenia dla innych pluginów. ekg podczas ładowania wywoła funkcję typu
register_plugin(), która będzie miała za zadanie zarejestrować wszystkie
udostępniane komendy i zmienne. w przypadku konfliktu zmiennych i komend,
można je poprzedzić prefiksem określającym plugin. jeśli na przykład mamy
załadowaną obsługę GG i Jabbera, zmienna ,,gg:password'' określałaby hasło
GG, ,,jabber:password'' określałaby hasło Jabbera. jeśli użytkownik nie poda
o jaki plugin chodzi, a np. aktualne okno to sesja GG, brany pod uwagę
byłby plugin ,,gg''. jeśli okno Jabbera, plugin ,,jabber''. podobnie
z komendami. jeśli ktoś w oknie Jabbera chciałby zarejestrować konto GG,
wystarczyłoby ,,/gg:register''.

pluginy muszą posiadać również informacje o kolizjach z innymi, żeby przy
ładowaniu ,,ncurses'' usunąć ,,readline'' i na odwrót, bo oba korzystają
z terminala. obsługa okien powinna trafić do ekg. ui ma wyświetlać to,
co każe mu pokazać ekg i informować o wciśniętych klawiszach funkcyjnych
(nie chodzi tylko o Fx tylko o Alt-x, Ctrl-x itp.) dzięki temu przy zmianie
ui, okna zostaną zachowanie (to ma być efekt uboczny, a nie cel sam
w sobie.)

pozostaje kwestia interakcji pluginów z ekg i między sobą, oznaczania
zdarzeń, kompatybilności API i takichtam bzdur. najprawdopodobniej będzie
coś w rodzaju gtk-owych sygnałów. plugin sobie zarejestruje obsługę danych
sygnałów, przez co odpadną dziesiątki strcmp(), jak to ma miejsce teraz,
przy jednej funkcji callbackowej na cały plugin. niestety będzie to wymagało
porządnego zastanowienia się nad tym, jak zrobić to efektywnie. setki
strcmp() przy każdym pakiecie przychodzącym z sieci i przy wywołaniu
sekundowego timera to przesada. niestety nie studiuję informatyki, więc
pewnie na początku będzie to sporym problemem. w każdym razie optymalizację
przekierowywania sygnałów można zostawić na później, kiedy będzie już co
optymalizować.

jeśli chodzi o API, ekg od chwili ustandaryzowania pierwszej wersji API
pluginów będzie oznaczało plugin jakimśtam identyfikatorem wersji. będzie
trzymać wszystkie stare wersje struktur i funkcji, żeby stare pluginy mogły
ich użyć.

trzeba będzie też wprowadzić zmienne typu lista, żeby móc np. podać listę
rurek kontrolnych (np. ,,pipe:/tmp/rurka'', ,,tcp:12345'' i
,,socket:/var/run/ekg''), z których ekg ma przyjmować polecenia, interfejsów
audio na wypadek zajętości (np. ,,/dev/dsp'', ,,hw:0,2'' czy ,,tcp:8001'')
no i wreszcie naszych ukochanych serwerów (przykładu nie ma. wybaczycie?)

co do wielosesyjności i wieloprotokołowości, to podobnie jak w BitchX czy
irssi, jedno okno mogłoby mieć przypisanych kilka sesji, które zmienianoby
klawiszem Ctrl-X na przykład. zmieniałby się pasek stanu między:

 (17:25) (gg:535333) (win/1)
 (17:25) (jabber:wojtekka@jabber.org) (win/1)
 (17:25) (irc:elluin@poznan.irc.pl) (win/1)

oczywiście powinna być możliwość przypisywania danym sesjom jakichś aliasów,
żeby nie mieć całego paska stanu zajętego przez id sesji.

pozostaje kwestia userlisty. robić osobną na każdy protokół i sesję? osobną
na każdy protokół, ale sesje dzielą? bo albo możemy chcieć wpisać sobie
jednego użytkownika jako gg:123456, irc:ktośtam, jid:ktośtam@gdzieśtam.pl
i raz podać imię, nazwisko, numer telefonu itd, albo trzymać wszystko
oddzielnie dla każdego protokołu, bo np. podczas rozmów na GG nie chcemy
zaśmiecać sobie listy znajomymi, których numery były kiedyśtam wpisane, ale
i tak rozmawiamy tylko na ircu.

wypadałoby też w końcu oddzielić libgadu od ekg, skoro ekg ma obsługiwać
inne protokoły. nie dość, że ulży to autorom innych klientów GG, wymusi
większy porządek w API, wersjach i binarnej kompatybilności.

z okazji pluginów, dobrze byłoby też się przyjrzeć takim wynalazkom jak
automake i libtool. rozmiar pakietu wzrośnie, ale nie będzie problemów
z obsługą platform innych niż te, na których pracują autorzy (pomyśleć,
że jeszcze 2 lata uważałem autoconfa za zło wcielone. pod postacią 
software'u.)

// 2003-04-17 12:53

może jednak zrobić bloga? (; w każdym razie dla testów wydzieliłem libgadu ze
źródeł ekg, przerobiłem do automake i libtoola. faktycznie, pisania mniej, ale
rozmiar wszystkich narzędzi, które autogen.sh pakuje do katalogu mnie
przerasta. tarball z Makefile.am, configure.in i autogen.sh zajmuje 80kB, a po
wygenerowaniu wszystkiego 320kB. trochę to chore. jeśli ekg miałoby mieć dla
każdego plugina tyle śmieci, to ja chyba podziękuję. innym wyjściem byłoby
rozprowadzanie tarballi bez tego wszystkiego i wymaganie od ludzi posiadania
pełnego środowiska: gcc, binutils, make, autoconf, automake, libtool. ludzie,
którzy mają wszystko nie musieliby ściągać niepotrzebnie kilka razy większego
tarballa. co najwyżej możnaby tworzyć osobny ekg-current-foobar.tar.gz, który
miałby wszystko, ale go nie archiwizować. w sumie to możliwe, od kiedy na
dev.null.pl stoi PLD.

