Skip to content

narrow screen resolution wide screen resolution auto screen resolution Increase font size Default font size Decrease font size default color brick color green color
Home Tutorial Sviluppo
Sviluppo PDF Stampa E-mail
Indice articolo
  1. Definizione delle funzioni di metrica e di action
  2. Inizializzazione dell'interprete XAL

1. Definizione delle funzioni di metrica e di action

Ora che abbiamo un'idea della "logica" della nostra applicazione, andiamo ad implementare effettivamente le funzioni di metrica e di action. Le nostre funzioni di metrica e di action saranno "abbozzate", e sono i metodi definiti in test/DeliveryWeb.lib.php. Abbiamo anche creato un file ausiliario (lib/WebPager.php). Vedremo come esso ci aiuterà nella generazione di interfacce utente HTML da parte delle funzioni di azione.

Facciamo notare che per ciascuno stato chiamato stato, abbiamo creto due metodi all'interno della classe DeliveryWeb: uno chiamato stato + Metric (che rappresenta la metrica associata allo stato stato) e l'altro stato + Page (che rappresenta la action function dello stato stato). La "regolarità" di questi nomi e` stata una nostra scelta, ovviamente i metodi avrebbero potuto avere nomi differenti. L'importante è che tali nomi siano coerenti con quelli specificati negli action pointer specificati nel file xml/DeliveryWeb.xml (gli elementi Action, per intenderci).

Notiamo ancora una volta, inoltre, che mentre le funzioni di azione non ritornano alcun valore come risultato della loro valutazione, le funzioni di metrica ritornano una stringa. Se vediamo ad esempio la metrica dello stato OrderPerformed (e cioè orderPerformedMetric) notiamo (in xml/DeliveryWeb.xml) che l'elemento Enumeration ha impostato l'attributo a Type pari a 'string' e tale elemento ha per figli tre elementi Const, con attributo Value rispettivamente "CANCEL_TASK", "KO_CARR" e "PROCESSING". Questo significa che il codice di orderPerformedMetric potra` ritornare una stringa fra quelle specificate negli elementi Const, e difatti cosi` e` se andiamo a leggere il codice del metodo.

Un altro aspetto importante, sono i parametri accettati in ingresso dalle funzioni di metrica e dalle funzioni di azione. Entrambi questi tipi di funzione riceveranno (primo parametro) un array associativo che rappresenta la porzione di ambiente "visto" dalla funzione stessa. Abbiamo chiamato questo parametro formale $state in tutte le funzioni, ma avrebbe potuto assumere qualsiasi altro nome. E` importante osservare che l'array $state e` passato per riferimento: oltre che essere un metodo efficente di passare dati ad un metodo, questo consente anche alla funzione di metrica o di azione di modificare l'ambiente in cui la funzione stessa si trova ad operare, come specificato dalla semantica del linguaggio. Ricordiamo che per specificare quali variabili saranno visibili all'interno della funzione di azione e all'interno della funzione di metrica occorre specificare il nome di tali variabili nel sottoelemento Input di ciascun elemento Action all'interno del file sorgente (nel nostro caso xml/DeliveryWeb.xml).

Osserviamo, inoltre, che le funzioni di azione possono ricevere un secondo parametro (quello che abbiamo chiamato $debugInfo nelle funzioni del nostro esempio) le quali contengono informazioni sullo stato attuale dell'interprete. Esse sono, come spiega il loro stesso nome, delle informazioni utili in fase di debug dell'applicazione (simili allo StackTrace messo a disposizione da un linguaggio ad oggetti quando si tratta di debuggare eventuali eccezioni).

In questo nostro esempio, ciascuno stato dell'automa è uno stato interattivo. Ciò significa che ciascuna funzione di azione si fa carico di mostrare l'interfaccia grafica tramite la quale interagire ed accettare input dall'utente. Per velocizzare, in minima parte, queste operazioni abbiamo pensato di raccogliere nella classe WebPager (in lib/WebPager.php) alcuni metodi che sono stati poi richiamati dalle funzioni di action. Non commentiamo tutti questi metodi (statici) ausiliari, bensì ci soffermiamo su alcuni che consideriamo più significativi.

Il metodo ClosePage si occupa di ricevere le informazioni di debug eventualmente passategli, mostrandole nella parte
bassa dello schermo.

I metodi Link e OpenForm realizzano concretamente il meccanismo di "salto" del nostro automa. Tale salto, infatti, in uno stato interattivo, si traduce in una nuova richiesta di tipo GET o POST, rispettivamente. Entrambi i metodi si occupano di passare alcune informazioni sulla sessione corrente:

  1. il nome della sessione (session_name())
  2. l'identificativo della sessione (session_id())
  3. il tempo della richiesta (ottenuto con la funzione microtime())

I nomi delle variabili con cui questi valori vengono "passati" sono definiti per mezzo di opportune costanti in lib/WebInterpreter.php. Questo perche` tali nomi di variabili rappresentano di fatto un "protocollo" di comunicazione fra il programmatore e l'interprete del linguaggio. In particolare, l'informazione sul tempo della richiesta aiuta ad "ignorare" eventuali refresh della pagina, avvenuti senza effettivamente cliccare un link (salto via GET) o inviare una form (salto via POST).

Di seguito vediamo un esempio di implementazione per le funzioni di metrica e di action per lo stato Start e la loro definizione all'interno dell'Action Pool.

   1 <?php    2     3 require_once '../lib/WebPager.php';    4     5 class DeliveryWeb {    6     // State Start    7         8     public function startPage(&$state, &$debugInfo=NULL)    9     {   10         WebPager::OpenPage("Delivery Web");   11         WebPager::Title("Process Beginning");   12         print "This is the introductive page.    13         This page may contain a login form.\n";   14         print   "<ul><li>[".   15                     WebPager::Link("START").   16                 "]:<i>it simulates authentication operation</i>\n";   17         print "</ul>\n";   18         WebPager::ClosePage($debugInfo);   19     }   20        21     public function startMetric(&$state)   22     {   23         return "CREATE";   24     }   25        26     // Other States...       27 }   28 ?>

   1 <?xml version="1.0" encoding="UTF-8"?>    2     3 <Automa xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     4     xsi:noNamespaceSchemaLocation="automa.xsd"    5     Id="Delivery">    6 <GlobalState>    7 ...    8 </GlobalState>    9 <Clocks>   10 ...   11 </Clocks>   12 <ActionPool>   13 <!--  ACTIONS  -->   14     <Action Id="startPage" Type="object">   15         <Input>   16             <Parameter Name="operator" />   17             <Parameter Name="lineChosen" />   18         </Input>   19         <System Path="../test/DeliveryWeb.lib.php"    20             Class="DeliveryWeb"   21             Name="startPage"/>   22     </Action>   23     ...   24 <!--  METRICS  -->   25     <Action Id="startMetric" Type="object">   26         <Input>   27             <Parameter Name="operator" />   28             <Parameter Name="lineChosen" />   29         </Input>   30         <System Path="../test/DeliveryWeb.lib.php"    31             Class="DeliveryWeb"   32             Name="startMetric" />   33         <Enumeration Type="string">   34             <Const Value="CREATE"/>   35         </Enumeration>   36     </Action>   37     ...   38 </ActionPool>   39 <States>   40     <State    41         Id="Start" IdAction="startPage"   42         IdMetric="startMetric"   43         Interactive="true">   44         <ClockReset ClockVar="cStart"/>   45     </State>   46 </States>   47 <FinalStates>   48 </FinalStates>   49 <InitialState IdState="Start"/>   50 <Transitions>   51     ...   52 </Transitions>   53 </Automa>

 

2. Inizializzazione dell'interprete XAL

Ora che abbiamo creato le funzioni di metrica e di action possiamo finalmente costruire la pagina in cui invochiamo l'interprete XAL per eseguire la nostra applicazione.

   1 <?php    2     3 /**    4  * It is the entry point for a web-interactive automaton.    5  * It cares about freezing the state of the automaton on    6  * the session when an interactive state is met.    7  */    8     9 /**   10  * The implementation of the WebIntepreter   11  */   12 require_once("../lib/WebInterpreter.php");   13    14 $interpreter = new WebInterpreter("../xml/DeliveryWeb.xml");   15    16 $interpreter->Run();   17    18 ?>

Alcune osservazioni sul codice:

  • riga 12: viene incluso il codice della classe WebInterpreter, cioè il nostro interprete XAL
  • riga 14: viene creata una nuova istanza di WebInterpreter specificando il file XML contente la descrizione dell'automa (nel nostro caso ../xml/DeliveryWeb.xml)
  • riga 16: viene invocato il metodo Run di WebInterpreter che provoca l'esecuzione vera e proprio della nostra applicazione XAL
 

Login