https://wiki.freepascal.org/index.php?title=Main_Loop_Hooks/sk&feed=atom&action=historyMain Loop Hooks/sk - Revision history2024-03-28T23:27:45ZRevision history for this page on the wikiMediaWiki 1.35.6https://wiki.freepascal.org/index.php?title=Main_Loop_Hooks/sk&diff=26047&oldid=prevSlavko: Prvotný preklad2008-01-02T19:25:21Z<p>Prvotný preklad</p>
<p><b>New page</b></p><div>{{Main Loop Hooks}}<br />
<br />
== Prehľad problému ==<br />
<br />
Potrebujete čakať kým nastane nejaká udalosť (v sokete alebo rúre ...), ale chcete to urobiť v základnom (GUI) vlákne a neblokovať GUI a tiež nechcete viacero vlákien? Riešenie tohoto problému je schopnosť pridať extra obsluhy, ktoré čakjú v hlavnej slučke udalostí.<br />
<br />
== Detaily riešenia ==<br />
<br />
Pre poskytnutie tejto schopnosti boli do jednotky [[doc:lcl/lclintf|LCLIntf]] pridané dve funkcie:<br />
<br />
AddEventHandler(AHandle: THandle; AFlags: dword; <br />
AEventHandler: TWaitHandleEvent; AData: PtrInt): PEventHandler;<br />
RemoveEventHandler(var AHandler: PEventHandler);<br />
SetEventHandlerFlags(AHandler: PEventHandler; NewFlags: dword);<br />
<br />
Typ [[doc:lcl/interfacebase/twaithandleevent.html|TWaitHandleEvent]] je deklarovaný v jednotke '''InterfaceBase''' ako:<br />
<br />
TWaitHandleEvent = procedure(AData: PtrInt; AFlags: dword) of object;<br />
<br />
[[doc:lcl/lclintf/addeventhandler.html|AddEventHandler]] pridáva obsluhu čakajúcu v hlavnej slučke udalostí.<br />
<br />
Keď je signalizovaná obsluha, potom je volaná procedúra zadaná v ACallback s parametrom '''AData''', ktorý je poslaný pri registrovaní obsluhy udalosti, a príznakmi, ktoré sú špecifické pre OS. Príznaky, poslané do '''AddEventHandler''', môžu byť upravené pomocou '''SetEventHandlerFlags'''. Handler (ukazovateľ) vrátený '''AddEventHandler''' musí byť poslaný do '''RemoveEventHandler''' pre zastavenie očakávania priradenej obsluhe.<br />
<br />
[[doc:lcl/lclintf/removeeventhandler.html|RemoveEventHandler]] zastavuje očakávanie zadanej obluhy. '''RemoveEventHandler''' nastaví, pred ukončením, '''AHandler''' na nil. Jeho argumentom je ukazovateľ vrátený z '''AddEventHandler'''.<br />
<br />
=== Windows ===<br />
<br />
V aktuálnej implementácii nie je parameter '''AFlags''' v '''AddEventHandler''' použitý a '''AFlags''' v '''TWaitHandleEvent''' bude 0.<br />
<br />
Win32 podporuje nasledujúce typy handle, v podstate veci podporované MsgWaitForMultipleObjects:<br />
* oznamovania zmeny (pre súbory a adresáre)<br />
* konzolový vstup<br />
* udalosti: signalizované WinAPI funkciou SetEvent<br />
* mutexy: signalizované keď ich nikto nevlastní<br />
* procesy: signalizované keď sú skončené<br />
* semfóry: signalizované keď je ich počet väčší ako nula<br />
* vlákna: signalizované keď sú skončené<br />
* časovače: signalizované keď vyprší, viz SetWaitableTimer<br />
<br />
=== Gtk/Unix === <br />
<br />
Parameter '''AFlags''' v '''AddEventHandler''' udáva podmienky, za ktorých má byť signalizovaná obsluha, s možnýmy hodnotami dokuemntovanými v type GIOCondition v použití [http://developer.gimp.org/api/2.0/glib/glib-IO-Channels.html#GIOCondition glib].<br />
<br />
V spätnom volaní bude '''AFlags''' obsahovať podmienky vyššie odkazovaného typu '''GIOCondition''', ktoré boli splnené.<br />
<br />
Gtk/unix podporuje nasledujúce typy obsluhy:<br />
* súbory<br />
* sokety<br />
* rúry<br />
<br />
Všimnite si, že Win32 nepodporuje sokety a rúry (prinajmenšom ich použitie je "odradzované" v MSDN). Návrh: použite '''WSAEventSelect''' na vytvorenie udalosti spojenej so soketom a pošlite obsluhu udalosti.<br />
<br />
=== Rúry a ukončovanie procesu ===<br />
<br />
Pre poskytnutie viac-platformného riešenia pre rúry (neveľmi podporované na Win32) a procesy (nie veľmi podporované na GTK/Unix) boli pridané ďalšie funkcie:<br />
<br />
TChildExitReason = (cerExit, cerSignal);<br />
TPipeReason = (prDataAvailable, prBroken, prCanWrite);<br />
TPipeReasons = set of TPipeReason;<br />
<br />
TChildExitEvent = procedure(AData: PtrInt; AReason: TChildExitReason; AInfo: dword) of object;<br />
TPipeEvent = procedure(AData: PtrInt; AReasons: TPipeReasons) of object;<br />
<br />
function AddProcessEventHandler(AHandle: THandle; <br />
AEventHandler: TChildExitEvent; AData: PtrInt): PProcessEventHandler;<br />
procedure RemoveProcessEventHandler(var AHandler: PProcessEventHandler);<br />
<br />
function AddPipeEventHandler(AHandle: THandle; <br />
AEventHandler: TPipeEvent; AData: PtrInt): PPipeEventHandler;<br />
procedure RemovePipeEventHandler(var AHandler: PPipeEventHandler);<br />
<br />
Keď proces končí, bude volaná zadaná obsluha udalosti. '''AInfo''' bude obsahovať ukončovací kód, ak '''AReason''' je cerExit, alebo (len Unix) ukončovací signál, ak '''AReason''' je cerSignal. Pre GTK/Unix, použite PID ako '''AHandle''' pre sledovanie. Interne, je nainštalovaný popisovač signálu pre pochopenie signálu SIGCHLD. Na Win32, je na čakanie ukončenia procesu použitý '''AddEventHandler'''.<br />
<br />
Pre sledovanie rúry na prichádzajúce dáta, pošlite do '''AddPipeEventHandler''' popisovač súboru (unix) alebo handle konca čítania rúry, so zvolenou metódou obsluhy udalosti ako '''AEventHandler'''. Na GTK/Unix, je volaná '''AddEventHandler''' na čakanie prevádzky popisovača súboru. Na Win32, slučka správ vyprší každých 100 ms, na kontrolu všetkých čakaných rúr na dostupná dáta, ak sú dostupné dáta, je volaná obsluha udalosti.</div>Slavko