Omówienie
W tej części kursu opowiem Ci czym są zdarzenia oraz czym jest kolejka zdarzeń. Bardzo ważne jest aby omówić te zagadnienie na samym początku nauki biblioteki Allegro 5, ponieważ wykorzystuję się to w praktycznie każdym programie. Jeżeli wcześniej nie spotkałeś się z tym, nie martw się. Te zagadnienie jest bardzo proste.
Wprowadzenie do zagadnienia
Czym jest
zdarzenie (z angielskiego
event)? Wyobraź sobie to tak. Siedzisz sobie spokojnie w biurze przy komputerze i pracujesz, nagle szef krzyczy że masz mu zrobić kawę. Czyli krótko mówiąc, coś przyszło ci zrobić, wystąpiło zdarzenie. W tej sytuacji możesz, wykonać polecenie szefa lub udać że nie słyszysz. Jeśli wykonasz polecenie szefa, wszystko będzie powolutku toczyć się dalej. Jeżeli jednak nie wykonasz tego, takich zdarzeń nazbiera się dużo (w jakieś kolejności) i w końcu szef cie wyrzuci. Dodając, twój szef jest źródłem zdarzeń. Jak to teraz przełożyć na informatykę?
W bibliotece Allegro 5 wygląda to tak że, twój program działa i wykonuje swoją pracę. Nagle gdy zaczynasz przesuwać myszkę, wciskać klawisze klawiatury itp. występują zdarzenia (eventy). Użytkownik przekazuje programowi polecenia jakie chce żeby on wykonał. Wtedy twój program musi zareagować na to co się dzieje, wykonać jakąś czynność (obsłużyć event). W końcu gdyby program tego nie wykonał, zirytowany użytkownik wyłączył by go czy nawet skasował.
Tak więc:
Event - jest zdarzeniem generowanym przez źródło zdarzeń (event source).
Event Source - jest tym skąd pochodzą zdarzenia, czyli przykładowo mysz, klawiatura, display.
Event Queue - jest miejscem w którym gromadzą się zdarzenia które trzeba wykonać.
Taki system jest bardziej efektywny niż zajęcie procesora ciągłym sprawdzaniem każdego możliwego wystąpienia, dopiero wtedy reagowania.
Od teorii do praktyki
Aby zaprezentować główne działanie eventow, posłużę się tylko kilkoma funkcjami i obiektami.
ALLEGRO_EVENT_QUEUE * al_create_event_queue( void )
Funkcja tworzy (allokuje pamieć na) kolejkę zdarzeń, będą w niej przetrzymywane po wystąpieniu eventy.
Funkcja w razie poprawnego działania zwraca wskaźnik na obiekt
ALLEGRO_EVENT_QUEUE
, w przypadku błędu zwraca wartość
NULL
.
ALLEGRO_EVENT_QUEUE
Obiekt który pozwoli nam przetrzymywać zgromadzone zdarzenia. My będziemy odbierać wskaźnik na pamięć gdzie on będzie się znajdywać.
void al_register_event_source( ALLEGRO_EVENT_QUEUE * queue, ALLEGRO_EVENT_SOURCE * source )
Tą funkcją zarejestrujemy w odpowiedniej kolejce źródło z którego ma czytać zdarzenia.
ALLEGRO_EVENT_SOURCE * al_get_display_event_source( ALLEGRO_DISPLAY * display )
Tę funkcje znajdziemy w sekcji
Display oficjalnej dokumentacji. Służy ona do tego, aby pobrać wskaźnik na źródło zdarzeń określonego display'a.
Przykładowo wybrałem tę, może być również funkcja pobierająca źródło event'owe od klawiatury itd.
void al_wait_for_event( ALLEGRO_EVENT_QUEUE * queue, ALLEGRO_EVENT * ret_event )
Funkcja ta pobiera z samej góry kolejki event, który trafił do niej jako pierwszy. Następnie wpisuje go do obiektu
ALLEGRO_EVENT * ret_event
, jeżeli wskaźnik
ret_event jest wartością inną niż
NULL.
Jeżeli event zostanie wpisany do tego obiektu, zostaje skasowany z góry kolejki. Jeżeli wartość
ret_event jest równa
NULL, event z góry kolejki zostaje zniszczony.
ALLEGRO_EVENT
Obiekt w którym przetrzymywany będzie jeden pobrany event, który aktualnie jest do obsłużenia.
void al_destroy_event_queue( ALLEGRO_EVENT_QUEUE * queue )
Funkcje tę wywołujemy, aby zwolnic pamięć wcześniej allokowaną dla kolejki.
Przykład użycia powyższych informacji
Zwróć uwagę na komentarze, tłumaczą kod.
#include <stdio.h>
#include <allegro5/allegro.h>
int main( int argc, char * argv[] )
{
ALLEGRO_DISPLAY * display = NULL;
ALLEGRO_EVENT_QUEUE * kolejka = NULL;
ALLEGRO_EVENT ev1;
if( !al_init() )
{
fprintf( stderr, "Failed to initialize allegro!\n" );
return - 1;
}
kolejka = al_create_event_queue();
if( kolejka == NULL )
{
fprintf( stderr, "Failed to create event queue!\n" );
return - 1;
}
display = al_create_display( 640, 480 );
if( display == NULL )
{
fprintf( stderr, "Failed to create display!\n" );
return - 1;
}
al_register_event_source( kolejka, al_get_display_event_source( display ) );
al_clear_to_color( al_map_rgb( 20, 75, 80 ) );
al_flip_display();
while( 1 )
{
al_wait_for_event( kolejka, & ev1 );
if( ev1.type == ALLEGRO_EVENT_DISPLAY_CLOSE )
{
break;
}
}
al_destroy_display( display );
al_destroy_event_queue( kolejka );
return 0;
}
Przykład pozwala na obsłużenie wciśnięcia przycisku exit. Oczywiście można zarejestrować jako źródło eventów np. klawiaturę, następnie sprawdzać czy zostały wciśnięte klawisze.
Należy wtedy sprawdzić w oficjalnej dokumentacji jak zainstalować
sterownik klawiatury, dodać źródło do kolejki. Następnie sprawdzić za pomocą instrukcji if typ klawiatury, następnie klawisz.
Zaglądamy do dokumentacji
Czas rozejrzeć się po więcej możliwości. Zaglądamy do oficjalnej dokumentacji w zakładce
EventsW sekcji
A znajdują się funkcje. W sekcji
B znajdują się typy eventów.
Dostajemy funkcje do sprawdzenia czy źródło eventów jest zarejestrowane, do skasowania źródła z kolejki. Możemy pauzować kolejkę, sprawdzać czy jest spauzowana. Dostajemy inne funkcje do sprawdzenia czy wystąpił event i do jego pobrania. Nawet dostajemy możliwość stworzenia własnego źródła eventów, następnie generowania eventów które wpiszemy do określonej kolejki.
Typów jest dużo więcej. Możemy obsłużyć joystick, reagować na wciśnięcie lub puszczenie klawisza. Reagować na ruch myszy, wciskanie klawiszy myszy. Wykrycie dotyku, dla urządzeń z taką możliwością. Odebranie timerów, czyli regularnie pojawiających się eventów które regulują procesy w programie. Czy nawet sprawdzenia co dzieje się z oknem programu.
Możliwości jakie dostarczają eventy jest ogrom. Głównie z ich użyciem korzysta się z biblioteki Allegro 5. Myślę że udowodniłem Ci, że warto ten temat nauczyć się na początku.