|
Tutorial per aggiungere nuovi comandi a yab System: BeOS, Haiku, Zeta 1 Introduzione Questo tutorial presuppone conoscenze di base su yab, C, C++ e probabilmente sulle API di BeOS (BeAPI) per aggiungere nuovi comandi a yab. Non sono necessarie conoscenze di flex e bison. 2 Progettare un Comando Un tipico comando yab o è una procedure (una funzione che ritorna void), una funzione che ritorna un numero (double o int) o una funzione che ritorna una stringa (char*). Un comando è formato da - le parole del comando (entità lessicali) - la regola del comando - la funzione di wrapping C che chiama il metodo C++ - il metodo C++ Ciò sarà discusso dettagliatamente qui di seguito. 2.1 Le parole del comando Le parole necessarie ad un comando (tokens) sono definite nel file yabasic.flex. Per favore introdurre nuove parole del comando, solo quando quelle esistenti non sono sufficienti a descrivere i vostri nuovi comandi. Navigate nel file per trovare tutti i comandi yab e yabasic. Una parola del comando è formata dalla parola stessa (in maiuscolo) e dal token che ritorna. Il token molto spesso è semplicemente la parola stessa con una t davanti. Ad esempio: Example:
I nuovi toke vanno dichiarati anche nel file yabasic.bison, semplicemente aggiungendo il nome del token nella lista all'inizio del file. 2.2 La regola del comando L'attuale regola del comando (grammatica) deve essere aggiunta al file yabasic.bison. Se scorrete il file avrete una buona idea di come deve apparire la grammatica. Fondamentalmente in questo file sono interessanti tre sezioni: la sezione per le procedure, la sezione per le funzioni numeriche e la sezione per le funzioni che ritornano una stringa. Indagheremo le differenze tra queste funzioni nelle prossime due sezioni. Ma prima diamo un'occhiata alle similitudini. Una regola del comando è scritta con un leading pipe | seguito dai token e dagli argomentif. Alla fine segue una funzione identifier. Esempio:
Qui, coordinates è un sostituto per expression ',' expression e to è un sostituto del comando TO (che comunque è solo ','). Così fondamentalmente ci sono due tipi di argomenti: expression è un numero (di tipo double) e string expression è una stringa (di tipo char*). Questi possono essere separati da parentesi ','. Sono possibili anche ('(' and ')') ma non li ho utilizzati spesso. Così in questo esempio il comando BUTTON ha 7 argomenti, 4 numeri per le coordinate e 3 stringhe che conterranno il suo ID, il testo del bottone e la ID della view. 2.3 Procedure Come in tutte le procedure, l'esempio menzionato no ritorna un valore (in C è una funzione void). Che da un identificatore interno chiamato cBUTTON. Questo identificatore va dichiarato nel file yabasic.h. Date un'occhiata alla lista degli altri identificatori. Inoltre, in yabasic.h va dichiarato il nome della funzione C che è stata aggiunta al file graphic.c . Le procedure danno sempre una struct di informazioni circa argomenti, linee number ecc. Cioè, in graphic.c la funzione C semplicemente trasmetterà queste informazioni alla classe principale C++ (*, YabInterface *). Prima di aggiungere la funzione in grephic.c essa va aggiunta anche in main.c . La, aggiungetela allo switch che chiama le funzioni in accordo al loro identificatore. Esempio:
Una tipica funzione void in graphic.c appare come nel seguente esempio:
Nel nostro esempio, prima i 7 argomenti yab vengono recuperati dalla struct struct comando.
I numeri possono essere double o int ma per le coordinate, vanno utilizzati sempre i double. La corrente linea di numeri viene passata alla classe YabInterface class chiamando yi_SetCurrentLineNumber. Questa linea è la stessa per tutte le funzioni void. Finalmente, gli argomenti vengono passati alla classe YabInterface class chiamando yi_CreateButton. 2.4 Funzioni Le funzioni che restituiscono un numero o una stringa sono implementate differentemente. Per prima cosa hanno un differente identificatore iniziale con una f es. fLISTBOXGETNUM. Questo identificatore va dichiarato in yabasic.h nella funzione enum.
Inoltre il nome della funzione C che è stata aggiunta al file graphic.c va dichiarato anche in yabasic.h. Differentemente che per le procedure, queste funzioni impostano immediatamente il loro argumento, es.:
listboxgetnum ritorna un int quando gli viene passata una stringa come primo argomento. Gli argomenti che seguono YabInterface *yab, int line, const char* libname vanno aggiunti per fornire alla classe YabInterface ulteriori informazioni. Oltre alla procedura, il recupero degli argomenti dallo stack e la chiamata alla funzione sono tutti effettuati nel file function.c. Li gli argomenti yab vengono recuperati dallo stack ed inoltrati alla funzione wrapper in graphic.c. Esempio:
L'argomento stringa è recuperato da a1->pointer. Gli argomenti numerici vengono indirizzati da es. a3->value (non presente in questo esempio). Gli argomenti vengono numerati da a1 ad a6. Al momento ulteriori argomenti non sono supportati. Qui, il risultato è archiviato come un numero. Per le stringhe, il risultato potrebbe essere archiviato in un pointer and result = stSTRING; va impostato. Date un'occhiata agli altri comandi in questo file per ulteriori esempi. Finalmente, la funzione wrapper va implementate in graphic.c. Per il nostro esempio, ciò appare come nel seguente codice:
La line number corrente viene passata alla classe YabInterface chiamando yi_SetCurrentLineNumber. Questa linea è la stessa per tutte le funzioni. Il numero tornato viene semplicemente passato da yi_ListboxgetNum.
3 La classe C++ YabInterface 3.1 Aggiungere un Metodo Dopo quanto descritto sopra, siamo pronti a scrivere un nuovo metodo. Il metodo ha un nome C++ e una funzione wrapper con un nome esterno che inizia con yi . Entrambe vanno definite in YabInterface.h e implementate in YabInterface.cpp. La funzione wrapper passa il puntatore all'oggetto <>YabInterface e chiama il metodo principale:
Il metodo stesso è una parte della classe YabInterface che è derivata da BApplication. Così ogni metodo BApplication è accessibile dal vostro metodo.
3.2 Accesso alla strutture dati yab yab archivia varie informazioni nelle liste degli oggetti. La lista più desiderata è la lista delle view disponibili. Queste sono archiviate nel YabList object viewList. Per inizializzare un nuovo widget, è spesso sufficiente trovare la parent view. Ciò viene fatto chiamando YabList::GetView(const char*):
Nuovi widgets potrebbero permetter alcuni utili layout. Per favore fate riferimento ai comandi BUTTON e LISTBOX per capire come diversi tipi di layout vengono utilizzati in yab. Se volete trovare uno specifico widget su una view sconosciuta, dovete ciclicamente attraversare le view per trovare quella che contiene il vostro widget. Un simile loop appare come qui (a condizione che MyWidget derivi da BView):
3.3 Alcune brevi osservazioni Alla fine alcune brevi osservazioni su... - BUILD macros: Alcuni comandi hanno BUILD macros che consentono di disabilitare intere parti di yab durante la compilazione. Ciò viene utilizzato per produrre codice di dimensioni più contenute con build factory. Le librerie non utilizzate e parti di codice vengono semplicemente tralasciate se non necessarie. Utilizzate queste macro ogni volta che avete a che fare con comandi che li hanno. - Drawing: I comandi di Drawing sono un pò complicati. Essi spesso disegnano su una view, su una bitmap o un canvas. Specialmente il view drawing che ha un proprio sistema di archiviazione. Osservate gli altri comandi di disegno per capire come essi lavorano. - Own classes: Own classes: Aggiungere proprie classi è bello, ma ricordate di aggiungere queste nuove informazioni anche nel makefile (R5 and ZETA!). 4 Sommario Per darvi in breve una checklist di ciò che è stato fatto, date un'occhiata al sommario: - aggiungere nuove parole di comando (token) in yabasic.flex/i> if necessariamente aggiungere la regola del comando (grammar) in yabasic.bison aggiungere l'identificatore del comando e il nome del metodo C in yabasic.h - aggiungere le chiamate al comando in function.c o main.c - aggiungere la funzione wrapper in graphic.c - aggiungere C alla funzione wrapper C++ in YabInterface.h e YabInterface.cpp - aggiungere il metodo C++ in YabInterface.h e YabInterface.cpp End Traduzione di Giuseppe Gargaro carry over from pdf to html by Christian Albrecht (Lelldorin) September 2006 Made available by BeSly, the BeOS, Haiku & Zeta Knowledgebase. |