FlightGear/Gli script XML: differenze tra le versioni

Wikibooks, manuali e libri di testo liberi.
Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
Riga 10: Riga 10:
Nei linguaggi di programmazione il concetto di ''Binding'' è quello di generare un legame tra due differenti insiemi di codice. Ad esempio il nucleo portante di codice di FlightGear è formato da una serie di programmi in C++ che causa la loro intrinseca complessità sono gestiti solo da pochi ed esperti programmatori. Il Bindig fa si che i dati provenienti da alcune proprietà, dette per l'appunto ''<PropertyList>'' possano essere modificate da appositi comandi XML i quali non solo altro che chiamate al codice C++ che costituiscono il nucleo del programma.
Nei linguaggi di programmazione il concetto di ''Binding'' è quello di generare un legame tra due differenti insiemi di codice. Ad esempio il nucleo portante di codice di FlightGear è formato da una serie di programmi in C++ che causa la loro intrinseca complessità sono gestiti solo da pochi ed esperti programmatori. Il Bindig fa si che i dati provenienti da alcune proprietà, dette per l'appunto ''<PropertyList>'' possano essere modificate da appositi comandi XML i quali non solo altro che chiamate al codice C++ che costituiscono il nucleo del programma.


Un binding si attiva quando capita un evento, ad esempio in FlightGear quando si clicca su un oggetto presente nello scenario o nell'aereo, quando si opera con la tastiera o con il joystick, quando si clicca su una voce di menu o si clicca su bottoni e/o si inserisce valori nelle aree di testo. In questo caso si ha un binding tra le azioni di input intercettate dal sistema operativo, ritrasmesse a dei processi di ascolto presenti nel codice in C++ di FlightGear e quindi analizzate dal processo descritto all'interno del binding.
Un tipico esempio è la modifica dei valori rilasciati da un asse del joystick in modo che siano compatibili con i valori previsti da FlightGear. Ovviamente alcune cose, come l'interfacciamento tra il PC ed il joystick, avviene tramite programmi di sistema operativo e quindi per mezzo di chiamate scritte in C++. Queste chiamate di basso livello permettono la generazione di un albero delle proprietà del dispositivo joystick raffigurato in questo esempio per il solo asse '''0''' e bottone '''0''' da una struttura XML del seguente tipo:

Ad esempio, un caso molto semplice è il binding che gestisca la chiusura di una finestra:

<source lang="xml">
<binding>
<command>dialog-close</command>
</binding>
</source>

Il comando '''dialog-close''' è un comando di sistema per la chiusura di una finestra, diversamente è possibile aprire una qualsiasi finestra di dialog descritta come codice xml nella directory ''$FG ROOT/fgdata/gui/Dialogs''.

<source lang="xml">
<binding>
<command>dialog-show</command>
<dialog-name>location-in-air</dialog-name>
</binding>
</source>

In questo caso si mostra la finestra di dialog il cui codice xml è definito nel file ''location-in-air.xml''.

==Esempio di binding per il joystick==

Un esempio più complesso è la modifica dei valori rilasciati da un asse del joystick in modo che siano compatibili con i valori previsti da FlightGear. Ovviamente alcune cose, come l'interfacciamento tra il PC ed il joystick, avviene tramite programmi di sistema operativo e quindi per mezzo di chiamate scritte in C++. Queste chiamate di basso livello permettono la generazione di un albero delle proprietà del dispositivo joystick raffigurato in questo esempio per il solo asse '''0''' e bottone '''0''' da una struttura XML del seguente tipo:


<source lang="xml">
<source lang="xml">
Riga 59: Riga 82:


Il questo caso il comando C++ richiamerà l'interprete Nasal (''<command>'''nasal'''</command>'') seguito come parametro dal codice Nasal (''<script>'''...'''</script>'') che nel nostro esempio è semplicemente una chiamata ad una funzione Nasal di nome ''controls.throttleAxis()'' posizionata all'interno dell'aerea che raccoglie tutti gli script Nasal standard di FligtGear.
Il questo caso il comando C++ richiamerà l'interprete Nasal (''<command>'''nasal'''</command>'') seguito come parametro dal codice Nasal (''<script>'''...'''</script>'') che nel nostro esempio è semplicemente una chiamata ad una funzione Nasal di nome ''controls.throttleAxis()'' posizionata all'interno dell'aerea che raccoglie tutti gli script Nasal standard di FligtGear.

==Elenco dei binding==

I binding ammessi dal sistema sono riportati integralmente in questo [http://wiki.flightgear.org/Bindings|link], ma comunque conviene soffermarci su alcuni che sono particolarmente importanti nell'uso quotidiano degli script XML.

===Nasal===

È il bindig che permette di attivare uno script in linguaggio [[FlightGear/Il_linguaggio_NASAL|Nasal]], ad esempio il semplice script permette di stampare il valore dell'asse n. 2 del joystick normalizzato tra 0 ed 1:

<source lang="xml">
<axis n="2">
<desc>Throttle</desc>
...
<binding>
<command>nasal</command>
<script>
var th = (cmdarg().getNode("setting").getValue() - 0.5)*5/8+1;
print(th);
controls.throttleAxis();
</script>
</binding>
</axis>
</source>

Come si vede viene definita all'interno dello script una variabile ''th'' nella quale viene assegnato un valore con il comando Nasal: ''cmdarg().getNode("setting").getValue()'' dopo una certa elaborazione numerica. Poi questo valore viene stampato su consolle: ''print(th);''. Finalmente viene invocato un comando Nasal con ''controls.throttleAxis();'', questo comando si trova definito all'interno del file Nasal posto in ''$FG ROOT/fgdata/Nasal/controls.nas''. Niente quindi impedisce che tutto il codice Nasal sia posto direttamente dentro la parte ''<script>...</script>''.


=Riferimenti=
=Riferimenti=

Versione delle 11:59, 5 mar 2012

Indice del libro

In questo capitolo si descrive come costruire l'impalcatura principale di FlightGear, impalcatura fatta di codice XML che si appoggia sulle fondamenta di programmi scritti in C++. L'utilizzo del cosce XML ha permesso, all'inizio, di definire la possibilità di programmare facilmente l'interfaccia grafica GUI (Graphical user interface) senza dover scrivere righe in codice C++. Questo approccio, molto simile a quello utilizzato per costruire le interfacce grafiche Web, ha permesso di allargare notevolmente la fascia dei possibili programmatori di FlightGear prima spaventati dalla complessità del codice C++.

Successivamente l'uso dell'XML si è allargato ad altre parti del programma ed è diventato lo strumento di interfaccia tra il nucleo di FlightGear in C++ ed il linguaggio di programmazione Nasal utilizzato per scrivere efficaci script che di fatto coprono la maggior parte del codice scritto.

Binding

Nei linguaggi di programmazione il concetto di Binding è quello di generare un legame tra due differenti insiemi di codice. Ad esempio il nucleo portante di codice di FlightGear è formato da una serie di programmi in C++ che causa la loro intrinseca complessità sono gestiti solo da pochi ed esperti programmatori. Il Bindig fa si che i dati provenienti da alcune proprietà, dette per l'appunto <PropertyList> possano essere modificate da appositi comandi XML i quali non solo altro che chiamate al codice C++ che costituiscono il nucleo del programma.

Un binding si attiva quando capita un evento, ad esempio in FlightGear quando si clicca su un oggetto presente nello scenario o nell'aereo, quando si opera con la tastiera o con il joystick, quando si clicca su una voce di menu o si clicca su bottoni e/o si inserisce valori nelle aree di testo. In questo caso si ha un binding tra le azioni di input intercettate dal sistema operativo, ritrasmesse a dei processi di ascolto presenti nel codice in C++ di FlightGear e quindi analizzate dal processo descritto all'interno del binding.

Ad esempio, un caso molto semplice è il binding che gestisca la chiusura di una finestra:

  <binding>
    <command>dialog-close</command>
  </binding>

Il comando dialog-close è un comando di sistema per la chiusura di una finestra, diversamente è possibile aprire una qualsiasi finestra di dialog descritta come codice xml nella directory $FG ROOT/fgdata/gui/Dialogs.

  <binding>
   <command>dialog-show</command>
   <dialog-name>location-in-air</dialog-name>
  </binding>

In questo caso si mostra la finestra di dialog il cui codice xml è definito nel file location-in-air.xml.

Esempio di binding per il joystick

Un esempio più complesso è la modifica dei valori rilasciati da un asse del joystick in modo che siano compatibili con i valori previsti da FlightGear. Ovviamente alcune cose, come l'interfacciamento tra il PC ed il joystick, avviene tramite programmi di sistema operativo e quindi per mezzo di chiamate scritte in C++. Queste chiamate di basso livello permettono la generazione di un albero delle proprietà del dispositivo joystick raffigurato in questo esempio per il solo asse 0 e bottone 0 da una struttura XML del seguente tipo:

  <PropertyList>
    <name>Logitech Inc. WingMan Force 3D</name>
    <axis n="0">
      <desc>Aileron</desc>
    </axis>
    <button n="0">
      <desc>Brakes</desc>
    </button>
  </PropertyList>

Questa struttura contiene tre oggetti, il nome della proprietà (<name>..</name>) e due variabili <axis n="0">..</axis> e <button n="0">..</button>. A questo punto è possibile fare il binding ovvero legare il valore presente in una certa proprietà con qualche trasformazione che può avvenire richiamando un codice in C++ e/o utilizzando uno script in Nasal.

  <PropertyList>
  ...
  <axis n="0">
    <desc>Aileron</desc>
    <binding>
      <command>property-scale</command>
      <property>/controls/flight/aileron</property>
      <factor type="double">1.9</factor>
      <offset type="double">-0.055</offset>
      <dead-band type="double">0.15</dead-band>
      <power type="double">1.0</power>
    </binding>
  </axis>

In questi caso all'interno di <binding>..</binding> vi è il codice che potrà modificare il valore dell'asse 0 (<axis n="0">) tramite il comando di sistema <command>property-scale</command> che contiene alcuni parametri, il primo è il nome della proprietà dell'albero globale delle proprietà (<property>/controls/flight/aileron</property>) che dovrà essere unito in binding con il valore dell'asse 0 (<axis n="0">). I successivi quattro parametri sono richiesti, tutti o solo in parte, dipende la contesto, dal comando property-scale e definiscono il tipo di trasformazione del dato numerico che realizza il comando property-scale.

È anche possibile fare un binding non verso una chiamata C++ come property-scale ma verso uno script in Nasal, in questo caso potremo avere il seguente codice XML:

  <PropertyList>
  ...
  <axis n="0">
  <desc>Aileron</desc>
    <binding>
      <command>nasal</command>
      <script>controls.throttleAxis()</script>
    </binding>
  </axis>

Il questo caso il comando C++ richiamerà l'interprete Nasal (<command>nasal</command>) seguito come parametro dal codice Nasal (<script>...</script>) che nel nostro esempio è semplicemente una chiamata ad una funzione Nasal di nome controls.throttleAxis() posizionata all'interno dell'aerea che raccoglie tutti gli script Nasal standard di FligtGear.

Elenco dei binding

I binding ammessi dal sistema sono riportati integralmente in questo [1], ma comunque conviene soffermarci su alcuni che sono particolarmente importanti nell'uso quotidiano degli script XML.

Nasal

È il bindig che permette di attivare uno script in linguaggio Nasal, ad esempio il semplice script permette di stampare il valore dell'asse n. 2 del joystick normalizzato tra 0 ed 1:

  <axis n="2">
    <desc>Throttle</desc>
    ...
    <binding>
      <command>nasal</command>
      <script>
        var th = (cmdarg().getNode("setting").getValue() - 0.5)*5/8+1;
        print(th);
        controls.throttleAxis();
      </script>
     </binding>
   </axis>

Come si vede viene definita all'interno dello script una variabile th nella quale viene assegnato un valore con il comando Nasal: cmdarg().getNode("setting").getValue() dopo una certa elaborazione numerica. Poi questo valore viene stampato su consolle: print(th);. Finalmente viene invocato un comando Nasal con controls.throttleAxis();, questo comando si trova definito all'interno del file Nasal posto in $FG ROOT/fgdata/Nasal/controls.nas. Niente quindi impedisce che tutto il codice Nasal sia posto direttamente dentro la parte <script>...</script>.

Riferimenti