next up previous
Next: Dátové súbory alebo "Organizácia Up: grafika Previous: Opakovanie grafiky alebo "Picasso

Timery alebo "Časovaná nálož."

Počítače majú rôznu rýchlosť. Historický exemplár XTčka je asi tisíckrát pomalší, než Pentium III. Vývoj ide dopredu a ľudia sa z toho väčšinou tešia. Však kto by sa netešil, keď mu program behá tisíckrát rýchlejšie. Problémy ale môžu nastať, ak ten program je napríklad Tetris alebo iná počítačová hra. Ak si niekto svoju zamilovanú verziu Tetrisu pre XTčko pustí na nejakom rýchlom stroji, môže iba s hrôzou sledovať, ako sa mu na najpomalšom leveli zaplní v priebehu pol sekundy celý stĺpec bez toho, aby vôbec stihol siahnuť na klávesnicu.

Aby sa tento problém vyriešil, boli vymyslené timery. Sú to hodiny, ktoré má program možnosť sledovať a správať sa podľa nich. Pri ich použití pod niektorými operačnými systémami však treba dodržať niektoré pomerne náročné pravidlá. V nasledujúcej ukážke vôbec neinicializujeme grafiku, používame iba funkcie knižnice allegro týkajúce sa timerov:

 1   #include <allegro.h>
 2 
 3   volatile int sekundy = 0;
 4
 5   void dalsia()
 6   {
 7       sekundy++;
 8   }
 9   END_OF_FUNCTION(dalsia);
10
11
12   int main()
13   {
14      allegro_init();
15      install_keyboard();
16      install_timer();
17     
18      LOCK_VARIABLE(sekundy);
19      LOCK_FUNCTION(dalsia);
20     
21      install_int(dalsia,1000);
22    
23      while(sekundy <= 10)
24          printf("%d s.\n",sekundy);
25    
26      return 0;
27   }
28   END_OF_MAIN();

S prvou zaujímavosťou sa stretávame už na riadku 3. Premenná sekundy má v svojej deklarácii uvedené slovo volatile. Toto slovíčko znamená, že premenná môže nečakane a náhle zmeniť hodnotu zásahom "zvonka". (Všimnite si, že ak by premenná sekundy túto vlastnosť nemala, cyklus na riadkoch 23-24 by nikdy nemohol skončiť!) To že nejaká premenná bude mať túto vlastnosť treba dať kompilátoru vedieť.[*]

Na riadkoch 5-9 sa nachádza funkcia dalsia. Jej jedinou úlohou je zvýšiť hodnotu premennej sekundy.

Riadky 14-16 sú klasické allegrovské inicializačné rutiny. Volanie funkcie
install_timer nám umožní používať timery a veci s nimi zviazané.

Celé tajomstvo timerov sa nachádza na riadku 21. Funkcia install_int nám taký timer vyrobí. Ako prvý parameter treba uviesť funkciu, ktorú timer bude volať (v našom prípade je to funkcia dalsia). Táto funkcia nesmie mať parametre ani vracať hodnotu. Ako druhý parameter sa uvedie časový interval v milisekundách, v ktorom sa uvedená funkcia bude volať. Na riadku 21 teda hovoríme nášmu programu, že okrem toho, že vykonáva naše príkazy, tak "pomimo" ešte každú sekundu (sekunda je 1000 milisekúnd) musí spustiť funkciu dalsia.

Na riadkoch 23-24 sa dokolečka vypisuje obsah premennej sekundy. Nebyť timera, hodnota premennej sekundy je stále 0 a cyklus sa nikdy neskončí. Lenže náš timer (bez ohľadu na to, že program práve vykonáva cyklus) každú sekundu zavolá funkciu dalsia, ktorá hodnotu premennej sekundy zväčší. Takže stačí počkať 11 sekúnd a cyklus a s ním celý program skončí.

Vyzerá to pekne. Lenže v niektorých prípadoch nastávajú problémy. Niektoré prostredia (napríklad DJGPP pod DOSom) sú pomerne prefíkané a ak majú málo pamäte, tak kus z nej si dočasne odložia na disk (tomu sa hovorí memory swap). A niektoré prostredia (opäť napríklad DJGPP pod DOSom) používajú k obsluhe timerov systémové prerušenia. No a ak sa obsluha systémového prerušenia odswapuje na disk, tak v niektorých prostrediach (príklad už ani uvádzať nebudem...) to spôsobí, že systém v hrozných kŕčoch zdochne. Takže sa treba postarať o to, aby sa obsluha prerušenia ani žiadna premenná, ktorú používa neodswapovala -- treba ich zamknúť. Preto na riadkoch 18-19 voláme makrá LOCK_VARIABLE a LOCK_FUNCTION, ktoré patričnú premennú aj funkciu zamknú a na riadku 9 makro END_OF_FUNCTION, ktoré označuje, kde zamykaná funkcia končí.

Z dôvodu problémov zo zamykaním (a nielen z tohto) sa odporúča, aby funkcia obsluhujúca timer bola čo najmenšia a najjednoduchšia.

Úloha č.1 Pochopte, napíšte, skompilujte a vyskúšajte uvedený príklad.

Úloha č.2 Napíšte program stopky, ktorý vám s presnosťou na stotinu sekundy odmeria čas medzi dvoma sltačeniami klávesy <Enter>.

Úloha č.3 Napíšte program, ktorý na obrazovku raz za sekundu nakreslí krúžok náhodnej farby, umiestnenia a polomeru. Krúžok nekreslite vo funkcii obsluhujúcej timer ale kontrolujte si, či sa hodnota premennej, v ktorej máte uložený čas od posledného kreslenia, zmenila!


next up previous
Next: Dátové súbory alebo "Organizácia Up: grafika Previous: Opakovanie grafiky alebo "Picasso
Anino Belan
anino(at)smnd.sk