Be Book Wygaszacz Ekranu Indeks Wygaszacza Ekranu

BScreenSaver

Pochodzi od: żaden
Zadeklarowany w:  be/add-ons/screen_saver/ScreenSaver.h
Biblioteka: aplikacja preferencji ScreenSaver
Streszczenie: więcej...

 

BScreenSaver dostarcza interfejsu dla programistów tworzących swoje własne moduły wygaszaczy ekranu. Klasy pochodne od BScreenSaver implementują funkcje określające tutaj, żeby rysować na ekranie w chwili gdy jest włączone oszczędzanie i rysować na ekranie podglądu ScreenSaver'a (Patrz do "Mówiąc do wygaszacza ekranu" na ilustrowanie ekranu podglądu).

Klasa BScreenSaver jest abstrakcyjna - do użycia musi być ona subklasowana (czyli trzeba stworzyć klasę pochodną) . Ponadto nigdy nie tworzysz obiektów BScreenSaver (subklas) sam; są one tworzone automatycznie wtedy gdy są potrzebne silnikowi wygaszania ekranu.


Cykl życia wygaszacza ekranu

Kiedy silnik wygaszacza ekranu chce użyć Twojego wygaszacza ekranu, by oszczędzać ekran, to konstruuje egzemplarz Twojej podklasy BScreenSaver (poprzez funkcję instantiate_screen_saver(), jak wyjaśniono w "Wtyczki wygaszacza ekranu") a następnie wywołuje funkcje przechwytujące obiektu, w tej koleności:

Kiedy aplikacja preferencji ScreenSavers ładuje Twój moduł, seria wywołań jest podobna ale z następującymi różnicami:

Następujące funkcje mogą być wywołane za każdym razem:

Co jeśli Ja nie chcę funkcji Draw()?

Nie musisz używać funkcji Draw()/DirectDraw(); są one dostarczone jako wygodne do łatwego pisania prostego wygaszacza ekranu.

Takie podejście do obsługi Twojego własnego rysowania jest zapoczątkowane wątkiem rysującym w StartSaver() i jest wyłączany w StopSaver(). Powinieneś zaimplementować funkcję Draw() aby powiadomić wątek rysujący gdy ekran jest dostępny (frame jest równe 0). Następnie możesz obsłużyć rysowanie w taki sposób jak zechcesz.

Monitor podglądu ScreenSavers nie działa prawidłowo bez wykonania przez Ciebie Twojego rysowania w funkcji Draw().

Jeśli potrzebujesz bezpośredniego dostępu do bufora ramki, będziesz musiał obsłużyć synchronizację z DirectConnected() sam, ponieważ jest to jedyny moment gdy wygaszacz utrzymuje dla Ciebie blokadę wyświetlania (jest ona obsługiwana automatycznie jeśli używasz DirectDraw()).


Funkcje przechwytujące

InitCheck()
Może być zaimplementowana aby dać znać silnikowi wygaszacza ekranu czy Twoja wtyczka (add-on) została właściwie zainicjalizowana.

StartSaver()
Może być zaimplementowana do wykonania tych czynności, których potrzebujesz aby były wykonane tuż przed rozpoczęciem rysowania przez wygaszacz ekranu.

StopSaver()
Może być zaimplementowana do wykonania tych czynności, których potrzebujesz aby były wykonane tuż po zakończeniu rysowania przez wygaszacz ekranu.

Draw()
Może być zaimplementowana do zabawnego rysowania przez wygaszacz ekranu (na ekranie, jak również w podlądzie wyświetlanym przez aplikację preferencji ScreenSaver).

DirectConnected()
Wywoływana gdy zostało wykonane połączenie z ekranem, gdy rozmiar lub format bufora ramki się zmienił, gdy położenie, rozmiar lub kształt widocznej części obszaru zawartości okna się zmienił lub gdy połączenie z ekranem jest zakończone.

DirectDraw()
Może być zaimplementowana do zabawnego rysowania gdy potrzebujesz bezpośredniego dostęu do plikseli (jak w BDirectWindow).

StartConfig()
Może być zaimplementowana do wypisania praw autorskich i informacji konfiguracyjnych w aplikacji preferencji ScreenSaver'a.

StopConfig()
Może być zaimplementowana do obsługi rzeczy, które potrzebujesz wykonać tuż przed przejściem do widoku konfiguracji ScreenSaver'a.

SupplyInfo()
Może być zaimplementowana do dostarczania systemowi wygaszania ekranu informacji o tej wtyczce (add-on). System wtedy przekazuje informację do innych wtyczek wygaszacza ekranu (przez wywołanie ich funkcji ModulesChanged()).

ModulesChanged()
Może być zaimplementowany aby dowiedzieć się o innych wtyczkach (add-ons) wyaszacza ekranu.

SaveState()
Może być zaimplementowany do zachowania bieżącego stanu wygaszacza ekranu, pozwalając na jego późniejsze odtworzenie.

Konstruktor i Destruktor


BScreenSaver()

BScreenSaver(BMessage *state, image_id image)

Buduje obiekt BScreenSaver ze informacji stanu przechowywanej w argumencie state (jeśli jakiś jest, jak wyjaśniono poniżej). Twój świeżo skonstruowany wygaszacz nie jest przyłączany do BView a nie możesz nic zrobić, żeby tego żądać. Będzie na to dużo czasu później jak opisano w StartSaver() i StartConfig(). Aby stwierdzić czy konstruowanie zakończyło się sukcesem, silnik wygaszacza kranu wywołuje InitCheck().

Argument state zawiera absolutnie wszystkie elementy dodane przez Ciebie gdy została wywołana funkcja SaveState() poprzedniego egzemplarza Twojego obiektu - innymi słowy, state jest zapisem stanu Twojego obiektu gdy on ostatnio działał. Jeśli Twój wygaszacz ekranu jest skonstruowany pierwszy raz to argument state będzie pusty a Ty będziesz potrzebował jakichś wrażliwych standardowych wartości. Format argumentu state zależy od Ciebie - Ty go piszesz, Ty go odczytujesz, nikt inny go nie będzie dotykał.

Argument image jest obrazem (w sensie Kernel Kit'u) samej wtyczki (add-on). Jest to szczególnie przydatne, jeśli potrzebujesz wygaszacza ekranu aby znalazł jakieś zasoby przechowywane we wtyczce (add-on). Na przykład, wyobraź sobie, że Twoja subklasa BScreenSaver (SpiffySaver) ma daną członkowską BResources *my_rsrc; tutaj jest pokazane jak odzyskałbyś te zasoby:

#include <kernel/OS.h>
#include <storage/Resources.h>

SpiffySaver::SpiffySaver( BMessage *info, image_id id )
{
   /* Inicjalizacja... */
   ...

   /* Znajdź zasoby SpiffySaver'a aby można ich było później użyć. */
   image_info the_info;
   status_t retval = get_image_info( id, &the_info );
   if( retval != B_OK ) {
      /* przechwycenie przez użytkownika lub zwolnienie. */
   }

   my_rsrc = new BResources;
   retval = my_rsrc->SetTo( new BFile( the_info.name, O_RDONLY ) );
   if( retval != B_OK ) {
      /* przechwycenie przez użytkownika lub zwolnienie. */
   }

   /*
   * Coś innego co potrzebujesz w kostruktorze, takie jak
   * znajdowanie łańcuchów znaków w Twoich zasobach.
   */
   ...
}


~BScreenSaver()

virtual ~BScreenSaver()

Niszczy Twój wygaszacz ekranu; to jest to co zdarza się wtedy gdy użytkownik chce wrócić do tworzenia cyfrowej zawartości. Za każdym razem gdy destruktor jest wywoływany, nie będziesz więcej rysował na ekranie a wtedy będą wywołane StopConfig() i StopSaver().


Funkcje członkowskie


Draw() , DirectDraw()

virtual void Draw(BView *view, int32 frame)
virtual void DirectDraw(int32 frame)

Są to funkcje przechwytujące, które rysują na ekranie. Do "zwykłego" rysowania, przedefiniuj funkcję Draw(); jeśli chcesz trzasnąć te kawałki bezpośrednio (tak jak chciałbyś w BDirectWindow), powinieneś użyć DirectDraw(). Ogólnie powinieneś tylko implementować pierwszą albo drugą funkcję. Jeśli zaimplementujesz obie funkcje, będą wywołane obydwie. DirectDraw() będzie zawsze wywoływana przed Draw() jeśli implementujesz je obydwie.

Draw() jest wywoływana co każde TickSize() mikrosekund. view jest widokiem w którym rysujesz; frame jest licznikiem ramek któe zaczynają się od 0 i są zwiększane za każdym razem gdy jest wywołana funkcja Draw(). Widok pojawia się z kolorem widoku równym B_TRANSPARENT_32_BIT, który oznacza, że biurko (desktop) będzie pokazywany poprzez niego. Jeśli nie chcesz widzieć Desktop'u (maybe your add-on draws some nice line patterns that look best on a black background), powinieneś wyczyścić widok w pierwszej ramce (frame == 0).

Łatwym sposobem wyczyszczenia widoku jest ustawienie koloru widoku w StartSaver() z użyciem BView::SetViewColor().

Protokół DirectDraw() (i częstość wywoływania) jest taki sam jak dla Draw(), ale ponieważ rysuje ona bezpośrednio po ekranie, DirectDraw() nie posiada parametru widku view. Popatrz do DirectConnected() aby zdobyć więcej informacji o bezpośrednim rysowaniu.

Więcej czasu spędzisz w swojej funkcji Draw()/DirectDraw(), to dłużej użytkownik będzie musiał czekać na powrót z jego systemu oszczędzania i będzie to drażniło każdego. Wykonaj swoje rysowanie i wyjdź z niego tak szybko jak to możliwe.


DirectConnected()

virtual void DirectConnected(direct_buffer_info *info)

Funkcja przechwytująca, która jest wywoływana wtedy gdy dostęp do okna bezpośredniego (ang. direct window) jest włączony lub wstrzymany lub or gdy zmieni się stan wyświetlania podczas którego będziesz rysował. Argument info opisuje stan wyświetlania; popatrz do klasy BDirectWindow (w Game Kit) aby uzyskaźć więcej informacji o strukturze direct_buffer_info.

W przeciwieństwie do BDirectWindow::DirectConnected(), nie powinieneś się martwić o synchronizację z Twoim wątkiem rysującym; silnik wygaszacza ekranu obsługuje to za Ciebie.

Twój kod funkcji DirectConnected() powinien być tak krótki jak to tylko możliwe, ponieważ to co on robi może oddziaływać na cały system. Funkcja DirectConnected() powinna obsługiwać tylko najbliższe zadanie dotyczące zmian w kontekście bezpośredniego rysowania, a nie powinna wykonywać właściwego rysowania - od tego jest funkcja DirectDraw().

DirectConnected() powinna zwrócić wartość dopiero wtedy, gdy może gwarantować, że żądanie określone przez info będzie ściśle podporządkowane.

Struktura wskazywana przez info odchodzi (nie będzie dostępna - przyp. tłum.) po zwróceniu wartości przez DirectConnected(), więc powinieneś przechować informację, która Cię interesuje.


Direct  patrz  Draw()


InitCheck()

virtual status_t InitCheck(void)

Funkcja przechwytująca, która używa silnika wygaszacza ekranu aby oszacować powodzenie konstrukcji Twojego obiektu. Twoja wersja InitCheck() powinna zwracać B_OK jeśli obiekt skonstruował się właściwie i B_ERROR jeśli wystąpił jakiś problem. Domyślnie InitCheck() zwraca wartość B_OK.

InitCheck() jest wywoływana po konstruktorze ale przed tym nim obiekt zostanie poproszony, aby dostarczył jakichś usług. Użyj jej do sprawdzenia środowiska w czasie uruchamiania (ang. runtime) i daj znać silnikowi wygaszacza ekranu, jeśli nie chcesz aby on zaczął działać. Przykładowo, jeśli wygaszacz ekranu żąda sprzętowo akcelerowanego OpenGL, to tu byłoby miejsce do zgłoszenia błędu, jeśli sprzęt nie może zostać znaleziony.


LoopOffCount() patrz SetLoop()
LoopOnCount() patrz SetLoop()
ModulesChanged() patrz SupplyInfo()


SaveState()

virtual status_t SaveState(BMessage *state) const

Implementuje ta funkcję do zachowania bieżącego stanu Twojego wygaszacza ekranu więc może on być odtworzony następnym razem gdy Twój obiekt jest konstuowany. Zachowaj stan w komunikacie state, który będzie przekazywany do konstuktora Twojego obiektu.

Jeśli Twoja wersja funkcji SaveState() nic nie zwraca zamiast zwracać B_OK, silnik wygaszacza ekranu będzie ignorował wszystko co umieścisz w komunikacie the state.

SaveState() może być wywoływana w dowolnej chwili a nie jest zagwarantowane, żeby została wywołana ze StopSaver(); Twój wygaszacz nie może zależeć od tego, żeby obsługa uaktualnień zmiennych była sterowana z widoku konfiguracji. Powinieneś obsłużyć je bezpośrednio (i natychmiast) więc użytkownik może wdzieć zmiany podczas ich zachodzenia.


SetLoop() , LoopOnCount() , LoopOffCount()

void SetLoop(int32 on_count, int32 off_count)
int32 LoopOnCount(void) const
int32 LoopOffCount(void) const

Te funkcje są używane do sterowania cyklami pętli animacji. Dla niektórych wygaszaczy ekranu, ma to sens przy wielokrotnym rysowaniu a następnie usypianiu. Przykładowo, wygaszacz, do kreślenia wzorów w kształcie plam mógłby rysować piksele co każdą ramkę, dopóki większość z nich jest na ekranie a następnie część czasu przed wyczyszczeniem ekranu i ponownym rozpoczęciem spędzić będąc uśpionym.

Użyj SetLoop() do zaimplementowaniawygaszacza ekranu, który używa cyki jak ten. Twoja methoda Draw() i/lub DirectDraw() będzie wywoływana co on_count ramek (a zliczona ramka zawsze będzie w zakresie od 0 do on_count - 1) a wtedy wygaszacz ekranu będzie uśpiony (dla TickSize() mikrosekund) na off_count ramek.

Przykladowo, jeśli SetLoop( 10, 5 ), Twój wygaszacz będzie rysował na ramkach od 0 do 9 a nastęnie będzie usypiał 5 razy na TickSize() mikrosekund.

Funkcja LoopOnCount() zwraca bieżącą liczbę rysowanych ramek (czyli on_count).

Funkcja LoopOffCount() zwraca bieżącą liczbę ramek usypiania (czyli off_count).


SetTickSize() , TickSize()

void SetTickSize(bigtime_t size)
bigtime_t TickSize(void) const

SetTickSize() ustawia częstotliwość rysowania na size mikrosekund. Pozwala Ci ona kontrolować jak często Twoja funkcja Draw() i/lub DirectDraw() jest wywoływanad. Domyślny rozmiar tyknięcia jest równy 50000 (50 milisekund).

Ustawienie rozmiaru tyknięcia na 0 powoduje, że funkcje Draw()/DirectDraw() zostana wywołane prawie bez żadnej zwłoki; w rzeczywistości będzie pewna zwłoka zależna od opóźnienia szeregowania (związane z szeregowaniem wątków i przełączeniem kontekstu w jądrze - przyp. tłum.). Właściwie jest to dobra rzecz, ponieważ daje to innym wątkom szansę do działania, jak również pozwala wygaszaczowi ekranu monitora pozostać wrażliwym na to, gdy użytkownik zechce wrócić do pracy .

Jeśli ustawisz rozmiar tyknięcia na 0, nie wywołuj snooze(), snooze_until(), sleep() lub coś, co mogłoby zablokować na czas nieokreślony. Ten rodzaj złego zachowania spowoduje, że użytkownicy usuną Twój wygaszacz ekranu natychmiast, ponieważ nikt nie ceni sobie zablokowanego systemu. Jeżeli potrzebujesz trochę uporządkować opóźnienia, wywołaj SetTickSize() zanim wrócisz z funkcji rysowania i zresetuj go na 0 podczas następnej ramki.

TickSize() zwraca częstotliowść rysowania w mikrosekundach.


StartConfig() , StopConfig()

virtual void StartConfig(BView *configView)
virtual void StopConfig(void)

Twoja funkcja StartConfig() jest wywoływana gdy preferencja (ustawienie) ScreenSaver jest wyświetlana by pokazać widok konfiguracji Tojego modułu. Kontrolki, które musisz utworzyć, aby pozwolić użytkownikowi dostroić Twój moduł powinny zostać dodane doconfigView. Pamiętaj o ustawieniu adresatów kontrolek, które dodajesz; dobrym sposobem żeby to zrobić, jest dodanie własnego BView i SetTarget() Twoich kontrolek do tego własnego widoku w funkcji AttachedToWindow() widoku.

Nie rysuj Twojego zabawnego wygaszacza ekranu do wyświetlannia wewnątrz configView; jest on przeznaczony do wyświetlania informacji o Twoim module i kontrolkach i do bawienia się jego ustawieniami. Aby dać Ci szansę na wyłączenie pokazywania będzie wywołana funkcja StartSaver() (z jej argumentem preview ustawionym na true).

StopConfig() jest wywoływana gdy widok konfiguracji preferencji (ustawienia) ScreenSaver'a powinien zniknąć.


StartSaver() , StopSaver()

virtual status_t StartSaver(BView *view, bool preview)
virtual void StopSaver(void)

Wywołanie StartSaver() oznacza, że silnik wygaszacza ekranu oznacza, że silnik wygaszacza ekranu znajduje się w momencie rozpoczęcia wygaszania ekranu (jeśli preview jest równy false) lub, że ScreenSaver znajduje się w momencie wyświetlania modułu w podglądzie monitora (jeśli preview jest równy true).

W Twojej implementacji funkcji StartSaver(), nie możesz dodać kontrolek-dzieci do widoku i nie możesz jeszcze rysować na ekranie. Do tego poczekaj na wywołania Draw() lub DirectDraw(). Widok staie się widoczny po zwróceniu wartości przez funkcję StartSaver().

StartSaver() daje Ci okazję do ustawienia Twojego wygaszacza, ponieważ mówi Ci on dokładnie jak duży obszar, będziesz wygaszał poprzez argument view. Możesz również użyćview do określenia Twojej przestrzeni kolorów (pośrednio, przez stworzenie obiektu BScreen z view->Window() w konstruktorze).

Zwraca wartość B_OK jeśli wszystko jest dobrze lub B_ERROR jeśli nie jesteś przygotowany, do rysowania na ekranie. Wygaszacze ekranu bez podglądu powinny zwracać wartość B_ERROR gdy są pytane o jego (czyli podglądu - przyp. tłum.) dostarczenie:

status_t SpiffySaver::StartSaver( BView *view, bool preview )
{
   /* SpiffySaver nie ma podglądu... to jest nie TEN spiffy. */
   if( preview ) return B_ERROR;
   
   ...

   return B_OK;
}

StopSaver() jest wywoływany gdy wygaszacz ekranu zakończył wyświetlanie. Jest ona wywoływana po najbardziej ostatecznym wywołaniu Draw() lub r DirectDraw().


StopConfig() patrz  StartConfig()
StopSaver() patrz StartSaver()


SupplyInfo(), ModulesChanged()

virtual void SupplyInfo(BMessage *info) const
virtual void ModulesChanged(const BMessage *info)

Te funkcje nie są obecnie używane przez system wygaszacza ekranu.

Te funkcje są używane do komunikacji pomiędzy modułami wygaszacza ekranu.

Silnik wygaszacza ekranu wywołuje SupplyInfo() gdy chce Cię on poinformować o Twoim wygaszaczu ekranu. Wstawia informację, którą chcesz dać innym modułom do zapoznania w komunikacie info. Komunikat jest następnie przekazywany do innego modułu wygaszacza ekranu poprzez jego funkcje ModulesChanged().

Funkcja przechwytująca ModulesChanged() jest wywoływanakiedy tylko zmieni się lista znanych modułów wygaszacza ekranu. BMessage info zawiera zagnieżdżony BMessage dla każdego prawidłowego modułu. Każdy zagnieżdżony BMessage jest nazywany wg wtyczki jego modułu i zawiera informację, która jest zwracana przez implementację SupplyInfo() modułu.

Jak w przykładzie - chociaż nie jest on bardzo przydatny - drukujemy tutaj nazwę i zawartość każdego zagnieżdżonego komunikatu:

void SpiffySaver::ModulesChanged( const BMessage *info )
{
   int32 num_addons = info->CountNames( B_MESSAGE_TYPE );

   for( int idx = 0; idx < num_addons; idx ++ ) {
      status_t retval;
      type_code found_type;
      char *name;
      
      retval = info->GetInfo( B_MESSAGE_TYPE, idx,
                              &name, &found_type );
      if( retval == B_OK ) {
            BMessage msg;
            retval = info->GetMessage( name, &msg );

            if( retval == B_OK ) {
               printf( "A module named "%s" sent this info:n", name );
            msg.PrintToStream();
            }
      }
   }
}

 


Be Book Wygaszacz Ekranu Indeks Wygaszacza Ekranu

Be Book,
...w ślicznym HTML...
dla BeOS wydanie 5

Copyright © 2000 Be, Inc. Wszelkie prawa zastrzeżone.