Viene ora presentata l’interfaccia di comunicazione fra le classi che permetta di strutturare, spedire e ricevere comandi, messaggi e dati da/verso qualunque oggetto istanziato nel software. Per usare questa interfaccia in una classe è sufficiente dichiararne l’eredità: Ad esempio consideriamo la classe DB_OBJECT, che è ereditata da molte altre classi del framework Colibri:
class AFX_EXT_CLASS DB_OBJECT : public TNODE, public FILE_ITF, public PARAM, public OPERATION_CALL
{
public:
DB_OBJECT(void);
virtual ~DB_OBJECT(void);
....
}
Come si può osservare, la classe eredita i metodi dell’interfaccia OPERATION_CALL, oltre a quelli di diverse altre classi. Una volta definita l’interfaccia, la classe può ricevere e mandare informazioni ad istanze diverse o conoscendone l’indirizzo (pointer) o attraverso un messaggio generico, spedito ad un oggetto di id assegnato. I due metodi fanno riferimento a situazioni differenti: nel primo caso la comunicazione avviene attraverso il metodo OPERATION_CALL::Call(..), quando è nota l’istanza con la quale comunicare; nel secondo caso, l’oggetto con il quale comunicare non è noto: si sa solo che, se esiste, è dotato di un identificatore univoco, una stringa, e che si aspetta i dati in una sequenza predefinita. Un tipico caso in cui il secondo metodo è usato in Colibri è quando si deve comunicare con un widget o un componente software che non necessariamente sono installati (ad esempio un plugin che può non essere presente): il comando avrebbe effetto solo in presenza dell’istanza di riferimento, chiariremo meglio nel seguito.
Il linguaggio
Per semplificare la scrittura delle procedure e dei parametri comunicati fra gli oggetti, è utilizzato un linguaggio, definito attraverso un insieme di macro; Il linguaggio utilizza due paradigmi: SLOT e SENDER ;
Slot
Uno slot di ricezione è un frammento di codice, definito attraverso un blocco _____SLOT(nome_slot) … _____END che contiene il codice di ricezione di una chiamata. All’interno del blocco vengono estratti i parametri trasferiti dal SENDER attraverso i comandi A_POP ed eseguite le operazioni desiderate.
Sender
Un sender è un frammento di codice, definito attraverso il blocco ___SENDER(op_call,id) .. __SENDER_END che effettua la trasmissione allo slot della OPERATION_CALL.
Nel blocco è definita, attraverso i comandi A_PUSH la lista degli argomenti trasmessi allo SLOT di ricezione, se richiesti. Il sender può essere definito in qualunque parte del codice dove sia noto il puntatore all’OPERATION_CALL ricevente,
Visibilità degli slot
Uno slot per essere accessibile, deve essere dichiarato tale; l’accessibilità dall’esterno della classe è effettuata attraverso il suo inserimento in un blocco _____SLOTS_____ .._____SLOTS_END_____.
Di seguito è fornito un generico esempio:
___SLOT(CURVE_MODIFY) A_POP(action,TCHAR) // estrazione di un parametro action di tipo STRING A_POP(curva,CURVE) // estrazione di un parametro curva di tipo CURVA*< .... .... ___END
nell’esempio riportato è definito un frammento di codice relativo ad uno slot CURVE_MODIFY, all’interno del quale è effettuata l’estrazione dei parametri ricevuti (macro A_POP, di cui scriveremo in seguito).
Quindi è definito il blocco _____SLOTS_____.._____SLOTS_END_____ all’interno del quale sono dichiarati gli slot accessibili ed il relativo comando OP_CURVE_MODIFY,OP_RESET.. ecc.
L’ultimo passaggio da descrivere è: dove è pubblicata la lista di slot dichiarata nel blocco _____SLOTS_____? Leggete il prossimo capoverso.
Dichiarazione della lista degli SLOT
Per pubblicare la lista degli slot dichiarati nel blocco _____SLOTS_____.._____SLOTS_END_____ è sufficiente inserire nel costruttore della classe che ha l’interfaccia OPERATION_CALL una delle due macro:
- ACTIVATE_OBJECT_SLOTS se gli slot assegnati all’oggetto sono richiamabili dal SENDER attraverso un blocco ___SENDER
- ACTIVATE_GLOBAL_SLOTS(object_identifier) se l’oggetto deve essere globalmente visibile attraverso il suo identificatore object_identifier, una stringa che identifica in modo univoco l’oggetto.
Nota finale
Abbiamo descritto il modo in cui può essere gestita la comunicazione fra gli oggetti utilizzando il paradigma SENDER-SLOT; in particolare abbiamo definita la comunicazione fra oggetti la cui interfaccia è un puntatore OPERATION_CALL. Non abbiamo completato la descrizione del blocco ___SENDER relativo ad oggetti identificati da un object_identifier; di questo discuteremo nel prossimo blog, dove definiremo meglio anche i comandi A_POP e A_PUSH, ed altri definiti nel linguaggio del framework Colibri
1 thought on “l’interfaccia OPERATION_CALL”