|
Tworzenie skryptów dostarcza sposobu do programowego sterowania jakąś inną aplikacją przez wysyłąnie jesj specjalnych poleceń skryptowych. Te polecenia sa zdefiniowane przez samą "scriptowaną" aplikację. Przykładowo, jeśli chcesz aby jakaś inna aplikacja była zdolna powidzieć Twojej aplikacji do wykonania operacji "FlipOver", musisz opublikowac format polecenia "FlipOver". Zbiór operacji, które chcesz przedstawić jest nazywany "suite" (zestaw).BeOS definiuje pewną liczbę zestawów, które odpowiadają poszczególnym klasom. Dla przykładu, wszystkie obiekty BApplication odpowiadają na polecenie zdefiniowane w zestawie "vnd.Be-application". Jedno z tych poleceń w zestawie daje Ci dostęp do okien aplikacji. Kiedy juz masz zlokalizowane okno, które chcesz, możesz je przesunąć, zamknąć, zmienić mu rozmiar i tak dalej, zgodnie z poleceniami w zestawie "vnd.Be-window".
Szkielet tworzenia skryptów określa następujące pojęcia: polecenia, właściwości i specyfikatory. Jeśli jesteś zaznajomiony z AppleScript, to są one równoważne czasownikom, rzeczownikom i przymiotnikom. Polecenia działają na określonym egzemplarzu właściwości, jako orkreślonym przez specyfikatory.
Polecenia przenosi działanie skryptowe i jest przechowywane w polu what skryptowanego BMessage'a. Jest sześć standardowych poleceń (określonych w be/app/Message.h):
- B_COUNT_PROPERTIES zlicza liczbę egzemplarzy właściwości.
- B_CREATE_PROPERTY tworzy nowy egzemplarz właściwości.
- B_DELETE_PROPERTY niszczy egzemplarz właściwości.
- B_EXECUTE_PROPERTY wykonuje egzemplarz właściwości.
- B_GET_PROPERTY podaje wartość egzemplarza wlaściwości.
- B_SET_PROPERTY ustawia wartość egzemplarza wlaściwości. Pole "data" ("dane") zawiera nową wartość właściwości.
Każde z tych poleceń działa na "property" ("właściwość), które nie jest niczym więcej niż sktyptową cechą obiektu. Jak w przykładzie ze świata realnego, okna posiadane przez aplikację sa właściwościami, tak samo jak tytuł każdego okna. Indywidualna interpretacja poleceń zależy od działania jakie jest wykonywane na właściwości. Przykładowo, B_DELETE_PROPERTY, działa na właściwości "Entry" (pozycja, element) okna Tracker'a, powodując przeniesienie pliku do kosza. Jednak to samo polecenie działając na właściwości "Selection" (zaznaczenie) tego samego okna usunie pliki z listy zaznaczonych pozycji (elementów).
Skryptowalne obiekty powinny ograniczyć się do tego kompletu poleceń. Jeśli obiekt używa niestandardowego polecenia, to doprowadzi to do tego, że będzie on nieużyteczny dla ogólnych narzędzi skryptowych.
Właściwość reprezentuje cechę skryptową obiektu. Właściwości sa nazwane; te nazwy są unikalnymi łańcuchami znakówwewnątrz klasy. Przykładowo, BWindow definiuje właściwości takie jak "Frame" (ramka), "Title" (tytuł) i "View" (widok). Typ danych właściwości i jej dozwolone wartości sa określone prze właściwość. Dla przykładu, "Frame" (ramka) okna akceptuje wartości B_RECT_TYPE podczas gdy "Title" (tytuł) jest typu B_STRING_TYPE.Czasami właściwość jest reporezentowana przez kolejny obiekt. Przykładowo,"View" (widok) BWindow'a określa BView, obiekt, który ma zestaw właściwości odmiennych od tych w BWindow.
Obiekt może mieć więcej niż jeden egzemplarz danej właściwości. Przykładowo, właściwość "Window" (okno) obiektu BApplication, ma tak wiele egzemplarzy jak wiele jest okien w aplikacji. Wynikiem jest tutaj pewna dwuznaczność gdy pytasz o to Window (okno) aplikacji. Zamiast tego, bardziej poprawnie jest zapytać o pierwsze Window (okno) lub o or the Window (okno) nazwane "Snyder." Inaczej mówiąc, właściwość nie jest wystarczająca by zidentyfikować cechę; musi zostać także wybrany określony egzemplarz.
Specyfikatory są używane do adresata ("specify" czyli "szczególny") poszczególnych egzemplarzy właściwości. Specyfikator jest obiektem BMessage zawierającym następujące elementy:
- Nazwa właściwości w polu "property" ("właściwość"), przechowywanan jako B_STRING_TYPE.
- Stała specyfikatora, wskazująca metodę identyfikowania egzemplarza właściwości w polu what wraz z koniecznymi polami wspomagającymi.
Jest siedem standardowych stałych specyfikatora (zdefiniowanych w <be/app/Message.h>):
- B_DIRECT_SPECIFIER. Nazwa właściwości jest wystarczająco sprecyzowana przez siebie samą, ponieważ jest zwykle, tylko jeden egzemplarz właściwości. Jeśli jest tutaj więcej niż jedna wartość dla właściwości, B_DIRECT_SPECIFIER powinien określić je wszystkie.
- B_NAME_SPECIFIER. Komunikat specyfikatora ma pole "name" (nazwa) typu B_STRING_TYPE z nazwą określonego egzemplarza właściwości.
- B_ID_SPECIFIER. Komunikat specyfikatora ma pole "id" (identyfikator) z unikalną wartością typu int32 dla określonego egzemplarza właściwości.
- B_INDEX_SPECIFIER. Komunikat specyfikatora ma pole typu int32 z nazwą "index" (indeks) z indeksem do określonego egzemplarza właściwości.
- B_REVERSE_INDEX_SPECIFIER. Indeks odlicza od końca listy.
- B_RANGE_SPECIFIER. Oprócz pola "index" (indeks), Komunikat specyfikatora ma pole typu int32 nazwane "range" (zakres), identyfikujące "range" (zakres) pozycji (elementów) rozpoczynających się od indeksu "index".
- B_REVERSE_RANGE_SPECIFIER . Indeks "index" odlicza od końca listy. Zależy od rodzaju danych i protokołu komunikatu, "range" (zakres) może rozciągać się od indeksu w kierunku początku listy lub w kierunku końca listy. Innymi słowy, indeks działa dwukierunkowo, zakres może albo nie.
Tak samo jak z komunikatami, dokładne znaczenie danego specyfikatora jest zależne od kontekstu. Dodatkowo, specyfikatory mogą być zdefiniowane przez użytkownika (lub być może odpowiednio - zdefiniowane obiektowo). Stałe specyfikatorów zdefiniowane przez użytkownika powinny być większe niż B_SPECIFIERS_END, by zapobiec konfliktom ze specyfikatorami zdefiniowany przez Be.
Specyfikatory są dodane do pola "specifier" komunikatu skryptowego używającego BMessage::AddSpecifier(). Jest kilka wariantów tej metody, zawierających skróy do dodatkowych specyfikatorów B_DIRECT_SPECIFIER, B_INDEX_SPECIFIER, B_RANGE_SPECIFIER, i B_NAME_SPECIFIER . Dla wszystkich innych specyfikatorów, musisz ręcznie skonstruować specyfikator i dodać go do komunikatu skryptowego z AddSpecifier(). Dla przykładu , dodanie B_ID_SPECIFIER:
BMessage specifier(B_ID_SPECIFIER); // tworzy nowy specyfikator
specifier.AddInt32("id", 2827); // dodaje numer identyfikacyjny do specyfikatora
message.AddSpecifier(&specifier); // dodaje specyfikator do komunikatu
![]()
Musisz użyć AddSpecifier() aby dodać specyfikatory do BMessage'a; wykonuje ona dodatkowe działanie wspierające proces skryptowaniae, którego nie robi AddMessage().
Ogólnie, aplikacja nie będzie w stanie otrzymać BMessenger'a dla obiektu adresata; zamiast tego, będzie ona musiała zadowolić się BMessenger'em adresującym obiekt BApplication programu zawierającego wymagany obiekt. W tych przypadkach, pojedynczy specyfikator może być niewystarczający, do zaadresowania komunikatu skryptowego. Prawdziwa potęga specyfikatorów leży w ich zdolności do łączenia razem w stos specyfikatora.Przykład najlepiej ilustruje działanie stosu specyfikatora. Następujący skrawek kodu tworzy komunikat, który będzie adresował celu ramkę drugiego widoku okna nazwanego "egg" (jajko) w docelowej aplikacji:
message.AddSpecifier("Label");
message.AddSpecifier("MenuBar");
message.AddSpecifier("Window", 1);Powtórzone wywołanie funkcji AddSpecifier() buduje stos specyfikatora. Kolejność wywołań jest bardzo ważna; specyfikatory są obliczane w porządku przeciwnym, do tego w którym zostały one dodane. Kiedy ten komunikat jest odbierany przez docelową aplikację, będzie z niego zdejmowany najpierw trzeci specyfikator i kierować komunikat do do drugiego okna aplikacji. BWindow będzie wtedy zdejmować drugi specyfikator i kierować komunikat do kluczowego paska menu okna (window's key menu bar). Pierwszy specyfikator ("Label" czyli etykieta) jest przetwarzany przez BMenuBar. Ten proces jest poniżej ukryty w wielu szczegółach pod ResolveSpecifier().
Odpowiedź jest generowana dla każdego żądania skryptowego. Komunikat odpowiedzi zawiera następujące pola:
- Dana członkowska what domyślnie ustawina na B_REPLY chyba, że stosowana jest jakaś inna stała. Dla przykładu, jeśli komunikat nie był zrozumiany, obiekt odpowiada obiektem BMessage o wartości B_MESSAGE_NOT_UNDERSTOOD.
- Pole "error" typu B_INT32_TYPE zawiera kod błędu dla operacji. To pole jest obecne zawsze.
- Odpowiedzi na żądanie B_GET_PROPERTY zakończone sukcesem będzie dodatkowo zawierać wartość lub wartości żądanej właściwości w tablicy "result" (wynik). Dane będą typu odpowiedniego do właściwości.
Obiekty scryptowalne, które tworzysz powinny słuchać również wyżej wymienionego protokołu. Oczywiście, pojedyncze obiekty są wolne od definiowania swoich własnych protokołów służących do przekazywania dodatkowej informacji w odpowiedzi; w tych przypadkach dla klasy o której mowa poradź się dokumentacji.
Udogodnienia skryptowe aplikacji mogą być wywoływane w trzech łatwych krokach:
- Ustaw stałą polecenia dla komunikatu skryptowego.
- Skonstruuj stos specyfikatora dla komunikatu skryptowego.
- Wyślij komunikat skryptowy do docelowej aplikacji.
Załóżmy, że chcemy uzyskać prostokątną ramkę drugiego widoku okna zatytułowanego "egg" (jajko) w aplikacji z sygnaturą "application/x-fish". Kod:
BMessage message, reply;
BRect result;
// ustaw stałą polecenia
message.what = B_GET_PROPERTY;
// skonstruuj stos specyfikatora
message.AddSpecifier("Frame"); // B_DIRECT_SPECIFIER
message.AddSpecifier("View", 1); // B_INDEX_SPECIFIER
message.AddSpecifier("Window", "egg"); // B_NAME_SPECIFIER
// wyślij komunikat i uzyskaj wynik
BMessenger("application/x-fish").SendMessage(&message, &reply);
reply.FindRect("result", &result)Krótkie i słodkie.
Jeden element jest opuszczny w systemie skryptowym, mianowicie zdolność do zapytania obiektu o jego zdolności skryptowe. Jest to użyteczne gdy aplikacja sterująca nie zna dokładnie typu obiektu który jest skryptowany. Mając metodę odkrywania zdolności skryptowych obiektu pozwala to na bardziej dynamiczne używanie skryptowania.Zdolności skryptowe obiektu sa zorganizowane w jeden lub więcej "suites" (zestawów) zbiór wspieranych komunikatów i przypisanych specyfikatorów. Zestaw jest identyfikowany przez łańcuch znaków MIME z supertypem "suite" (zestaw). Dla przykładu, BControl implementje zestaw skryptowy "suite/vnd.Be-control". Nic nie powstrzymuje dwóch obiektów od implementowania ten sam zestaw; dwa edytory dźwięku, na przykład, mogą mieć różne implementacje wspólnego zestawu skryptowego do filtrowania danych audio.
Aby zapytać obiekt o jego wspierane zestawy skryptowe, wyślij mu standardowy komunikat skryptowy z prośbą B_GET_PROPERTY o właściwość "Suites" (zestawy):
message.what = B_GET_PROPERTY;
message.AddSpecifier("Suites");
... dodaj pozostałe specyfikatory tutaj ...
messenger.SendMessage(&message, &reply);Obiekt docelowy odpowiada obiektem BMessage z wartością B_REPLY mającą nastęujące pola:
- Kod błędu w "error" (błąd).
- Tablica nazwana "suites" (zestawy) zawierająca nazwy zestawów wspieranych przez obiekt.
- Tablica nazwana "messages" (komunikaty) zawierająca spłaszczone (ang. flattened) obiekty BPropertyInfo opisujące wspierane komunikaty i specyfikatory dla różnych wspieranych zestawów.
Mniej użyteczne, możesz wysłąć obiekt BMessage z wartością B_GET_SUPPORTED_SUITES bezpośrednio do obiektu i otrzymać jego wspierane zestawy w identycznie uformowanej odpowiedzi.
Każdy skryptowy obiekt wspiera zestaw "suite/vnd.Be-handler" przez jego dziedzictwo po BHandler'ze. Ten zestaw jest czasami przytaczany jako "universal suite" (zestaw uniwersalny). Pełni on nastęujące funkcje:
- Implementuje właściwość "Suites" (zestawy) i odpowiada na komunikaty B_GET_SUPPORTED_SUITES, jak opisano powyżej.
- Implementuje właściwość "Messenger" (nadawca), pozwalając wysyłającemu otrzymać BMessenger'a do obiektu, upraszczając jeszcze bardziej komunikację z obiektem.
- Implementuje właściwość "InternalName" (nazwa wewnętrzna), zwracając nazwę BHandler'a.
- Odpowiada na inne żądania skryptowe obiektem BMessage z wartością B_MESSAGE_NOT_UNDERSTOOD. Jest to odpowiedź "catch-all" (złap wszystkie), po tym jak wszystkie inne obiekty w hierarchii odrzuciły żądanie skryptowe.
Ponieważ komunikaty skryptowe są przekazywane przez BMessenger'y, obiekty przyjmujące komunikaty skryptowe muszą pochodzić od BHandler'a. Zwykle, dodanie wsparcia skryptowego wymagać niewiele więcej niż przesłonięcie następujących metod:
- BHandler::ResolveSpecifier() kieruje komunikat skryptowy do odpowiedniego BHandler'a.
- BHandler::MessageReceived() implementuje żądania skryptowe.
- BHandler::GetSupportedSuites() publikuje wspierane sestawy skryptowe.
Aby uzyskać szczegóły o tych funkcjach w klasie BHandler patrz do dokumentacji.
|
Be
Book,
...w ślicznym HTML...
dla BeOS wydanie 5
Copyright © 2000 Be, Inc. Wszelkie prawa zastrzeżone.
d..