Progettazione e Realizzazione di una Library per Agenti Context-Aware

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "Progettazione e Realizzazione di una Library per Agenti Context-Aware"

Transcript

1 UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Matematica e Informatica Corso di Laurea in Informatica Progettazione e Realizzazione di una Library per Agenti Context-Aware Design and Implementation of a Library for Context-Aware Agents Relatore: Chiar.mo Prof. Federico Bergenti Candidato: Serri Cristiano Anno Accademico 2012/2013

2 Ai miei genitori ai miei zii e ai miei colleghi di studio che mi hanno sostenuto e supportato in questi anni

3 Indice 1 Introduzione 1 2 Introduzione a Jade Creazione di Piattaforme e Container Creazione di Agenti e Agenti Speciali Inizializzazione degli Agenti Gestione Eccezioni e Terminazione Agente I Behaviour Scambio di Messaggi tra gli Agenti Creare una Ontology e i suoi Componenti Programmazione su Android Ambiente di Sviluppo: ADT Creare ed Eseguire un Android Project Importare Progetti e Librerie Activity e Intent Manifest della Applicazione Costanti di Stringa usate dalla Applicazione Descrizione del Menu di una Activity Descrizione della Videata di una Activity La Library Dave Le Informazioni Geografiche La Posizione: EarthPoint Aggiungiamo la Direzione: EarthVector Il Punto di Vista: EarthPartialCircle Classe Helper per Jade Gli Agenti di Dave DaveClientAgent FixedAgent RandomAgent AndroidRealAgent DaveServerAgent

4 INDICE iii 4.4 UpdatePlanner NeverUpdatePlanner Riduzione del Carico Computazionale LevelAccessRule AccessRules QualityOfService NoService Esempio di Creazione e Configurazione Client Struttura Dati del Server ClientMatrix ClientRow OtherClient Levels Following Visualizzazione Agenti sulle GoogleMaps DaveReceiver IntentFilter Azioni compiute Esempio Applicazione Dave Le Fasi del gioco Fase di Posizionamento dei Tesori Fase di Ricerca dei Tesori Fine del Gioco Gli Agenti di DaveTreasureHunt TreasureAgent ExplorerAgent PirateAgent GameStorage ExplorerMatrix ExplorerRecord Screenshot del Gioco Conclusioni 64 Bibliografia 66

5 Capitolo 1 Introduzione Dave (Discover Agents Viewed on Earth) è una libreria scritta in Java che permette ai dispositivi Android che la utilizzano di acquisire la propria posizione geografica (tramite WiFi o GPS) e la direzione in cui sono rivolti (tramite Giroscopio), elaborare tali informazioni (per vedere se ci sono stati cambiamenti significativi) e trasmetterle. Le informazioni geografiche dei vari dispositivi vengono ricevute, memorizzate e rese disponibili da un processo Server che risiede su un pc il cui indirizzo ip è raggiungibile dai vari dispositivi Client. Queste operazioni consentono ad ogni dispositivo Android di individuare (e visualizzare opportunamente su una mappa con cui l utente del dispositivo può interagire) quali altri dispositivi si trovano nel suo punto di vista. Dave è stata sviluppata utilizzando le funzionalità e i concetti della libreria Jade, sviluppata da Telecom Italia. Jade (Java Agent DEvelopment framework) è un framework che permette di costruire applicazioni Java basate sul concetto di Agente. Gli Agenti si distringuono dai normali oggetti Java (che possiedono solo attributi e metodi) perchè possiedono dei comportamenti (Behaviour) che vengono eseguiti e prendono decisioni in modo autonomo, eseguiti in modo concorrente da uno Scheduler (di tipo Round Robin senza prelazione) interno all Agente stesso. Gli Agenti che fanno parte di una stessa Piattaforma possono comunicare tramite scambio di messaggi. Questa comunicazione è asincrona poichè i messaggi inviati vengono depositati nelle mailbox dei destinatari, ciascuno dei quali deciderà in modo autonomo se e quando leggerli. Utilizzando Jade in particolare si semplificano le comunicazioni via rete nelle applicazioni multi-utente. In Dave, sia i vari Client (Android) sia il Server (PC) sono implementati come Agenti. Inoltre ci sono alcuni Agenti Client che possono essere creati su PC. Questi Agenti non potranno ovviamente rilevare la propria posizione e direzione, la quale potrà essere definita all inizio e rimanere costante (op-

6 2 pure cambiare in modo rotatorio o random). La prima fase del mio lavoro di Tesi consiste nello studio e nell utilizzo della libreria Jade e nell allestimento dell Ambiente di Sviluppo per Android, comprendendo la struttura dei progetti e i principi alla base della programmazione su tale piattaforma. Le nozioni che ho appreso durante questa fase sono trattate (con un approccio di tipo operativo) rispettivamente nei capitoli 2 e 3. La seconda fase consiste nello sviluppo e nel test della libreria Dave (capitolo 4), e di un gioco (DaveTreasureHunt, una caccia al tesoro) che si appoggi su tale libreria (capitolo 5).

7 Capitolo 2 Introduzione a Jade Questo capitolo ha lo scopo di illustrare il funzionamento e i concetti base della libreria Jade (Java Agent DEvelopment framework), evidenziando principalmente le sue parti che sono state utili alla costruzione della libreria Dave. La guida completa, e il download della versione aggiornata della libreria (comprensiva anche di esempi), è possibile scaricarla dal sito ufficiale di Jade, ovvero jade.tilab.com. Come anticipato nell introduzione, Jade consente di creare applicazioni basate sul concetto di Agente. Verrà descritto come allestire il luogo (la Piattaforma e i vari Container) dove creare gli Agenti, e per ciascuno di questi come definire i vari comportamenti autonomi e come interagire con gli altri Agenti. Nel corso della trattazione di questa sezione riguardante Jade, verrà utilizzato il classico esempio nel quale gli Agenti sono venditori e compratori di Libri (BookTrading): Ciascun venditore inizia avendo in suo possesso un certo insieme di libri, ciascuno dei quali ha un nome e un prezzo. I venditori vengono contattati dai compratori per sapere se posseggono un determinato libro, i venditori rispondono in modo opportuno, comunicando il prezzo in caso affermativo. Inoltre i venditori vengono contattati dai compratori anche in caso di acquisto, dove forniscono il libro al compratore rimuovendolo dai libri posseduti. I compratori hanno lo scopo di acquistare un singolo libro, al prezzo minore tra quelli di tutti i venditori che posseggono il libro richiesto, poi terminano. Durante il lavoro di tesi, per integrare lo studio delle funzionalità di Jade con una prova pratica, è stato esteso l esempio base, ovvero quello presente nella directory examples/booktrading (scaricando il pacchetto completo di Jade). Le principali modifiche consistono:

8 2.1 Creazione di Piattaforme e Container 4 Nell utilizzo di un automa a stati finiti (FSMBehaviour) come Behaviour principale del compratore. Nell aggiunta di una Ontology specifica per i Libri, in modo tale che lo scambio di messaggi non sia più string-based ma costituito da Concetti e Predicati ad hoc. Usufruendo dell interfaccia grafica per creare e rimuovere compratori o venditori in momenti arbitrari, dello standard output per capire che cosa sta facendo ciascun Agente e come avviene la loro comunicazione, e degli strumenti messi a disposizione da Jade stesso, quali l Rma e lo Sniffer, questo esempio BookTrading può essere utilizzato come ottimo strumento di studio per i programmatori che si avvicinano a Jade. 2.1 Creazione di Piattaforme e Container Quando avviamo Jade (tramite la procedura descritta in seguito) dobbiamo decidere se creare una nuova Piattaforma con un Container Principale (Main) oppure se connetterci ad una Piattaforma già esistente tramite un Container Periferico. I Container sono il luogo dove gli agenti di Jade sono in esecuzione. Solo gli Agenti che vivono nella stessa Piattaforma (all interno dello stesso container o di container differenti) possono interagire (ovvero comunicare tramite scambi di messaggi). Di seguito vengono descritte le principali caratteristiche delle due tipologie di Container: Il Main Container deve esistere ed essere unico in ciascuna Piattaforma di Jade. La creazione di un Main Container coincide con la creazione di una Piattaforma. Tale operazione di creazione è possibile effettuarla solo da PC, e non da dispositivo Android. Non ci sono limiti al numero di Container Periferici che una Piattaforma può avere. Quando si crea un Container Periferico bisogna indicare una Piattaforma già esistente (nella quale in particolare si trova già il Main Contaiber) alla quale tale Container si registrerà. I Container Periferici possono essere creati indifferentemente da Android o da PC. Per poter creare una nuova Piattaforma è necessario che non ci sia alcun servizio attivo sulla porta 1099 (è quella che di default Jade usa, se non specificato diversamente). La porta 1099 può essere occupata ad esempio da vecchie istanze di Jade non terminate correttamente. L eccezione che tipicamente viene lanciata quando la porta è già in uso è: jade.core.imtpexception: No ICP active at jade.imtp.leap.leapimtpmanager.initialize(leapimtpmanager.java:138) at jade.core.agentcontainerimpl.init(agentcontainerimpl.java:319) at jade.core.agentcontainerimpl.joinplatform(agentcontainerimpl.java:489) at jade.core.runtime.createmaincontainer(runtime.java:166)

9 2.1 Creazione di Piattaforme e Container 5 Inoltre, per consentire ai Container Periferici di connettersi al Main Container su questa Piattaforma bisogna controllare che la porta non sia bloccata dal Firewall del sistema operativo. Per sbloccarla occorre aggiungere nel Firewall una nuova regola che consenta le connessioni in ingresso su tale porta da parte di qualsiasi applicazione (in Windows è possibile farlo nelle Impostazioni Avanzate del Windows Firewall, accessibile dal Pannello di Controllo nella scheda Sistema e Sicurezza). Queste istruzioni consentono di creare un Main Container su PC: import jade.core.profile; import jade.core.profileimpl; import jade.core.runtime;... Profile profile = new ProfileImpl(); AgentContainer container = Runtime.instance().createMainContainer(profile); Supponiamo di avere creato una Piattaforma su un pc con indirizzo Ip nella porta di default (1099), ovvero di avere eseguito su tale pc un programma che contenga le istruzioni soprastanti (il costruttore di default di ProfileImpl imposta come indirizzo ip localhost e come porta la 1099). Se questo punto vogliamo creare da un altro PC un Container Periferico facente parte della stessa piattaforma, utilizziamo il codice seguente: import jade.core.profile; import jade.core.profileimpl; import jade.core.runtime;... Profile profile = new ProfileImpl(" ", 1099, null, false); AgentContainer container = Runtime.instance().createAgentContainer(profile); Abbiamo usato il costruttore più generico di ProfileImpl. Il terzo parametro è l etichetta da applicare al container (null significa di usare quella di default), e il quarto parametro impostato a false significa che il container che vogliamo creare non è Main. Creare un Container Periferico da Android è più complesso, poichè bisogna connettere (bindservice) il servizio di Jade per Android (MicroRuntimeService) all Activity (il concetto di Activity, così come quello di Intent, verranno trattati nel capitolo riguardante Android). La ServiceConnection e la CallBack contengono codice che viene eseguito rispettivamente al completamento dell operazione di bind e di creazione del Container Periferico (tali operazioni non vengono fatte istantaneamente, quindi questo procedimento è necessario).

10 2.2 Creazione di Agenti e Agenti Speciali 6 Properties properties = new Properties(); properties.setproperty(profile.main_host, " "); properties.setproperty(profile.main_port, "1099")); properties.setproperty(profile.main, "false"); properties.setproperty(profile.jvm, Profile.ANDROID); properties.setproperty(profile.local_host, AndroidHelper.getLocalIPAddress()); properties.setproperty(profile.local_port, "1099"); ContainerStartupCallback contcallback = new RuntimeCallback<Void>() public void onsuccess(void thisisnull) { // Container Creato public void onfailure(throwable throwable) { // Fallimento nella creazione del Container ServiceConnection ServiceConnection = new ServiceConnection() public void onserviceconnected(componentname name, IBinder service) { microruntimeservicebinder = (MicroRuntimeServiceBinder) service; if (!MicroRuntime.isRunning()) { microruntimeservicebinder.startagentcontainer( properties, contcallback ); public void onservicedisconnected(componentname name) { microruntimeservicebinder = null; //Suppongo che activity sia il puntatore all Activity che invoca questo codice activity.bindservice( new Intent(activity, MicroRuntimeService.class), this.serviceconnection, Context.BIND_AUTO_CREATE ); 2.2 Creazione di Agenti e Agenti Speciali Quando il Container (Main o Periferico) è pronto, possiamo creare gli agenti e collocarli in tale Container. L istruzione seguente consente (in modo compatto) di creare ed eseguire 1 Agente da PC: container.createnewagent(nome, classe, args).start();

11 2.2 Creazione di Agenti e Agenti Speciali 7 Di seguito descrivo lo scopo di ciascuno dei parametri: Il nome verrà usato come nome locale del nuovo Agente deve essere univoco all interno della Piattaforma (quindi non si può scegliere come nome quello di un altro Agente presente nello stesso Container o in un altro) La classe (comprensiva di package) è una qualsiasi classe che estende jade.core.agent, usata per creare e personalizzare il nuovo Agente. Il terzo parametro, args è un array di Object che verrà passato al nuovo Agente una volta creato, che può essere usato per personalizzarlo. Se all Agente non servono argomenti, è possibile usare null. Prima di vedere come eseguire la stessa operazione su Android, presentiamo un Agente molto comodo, contenuto nella classe jade.tools.rma.rma. Possiamo crearlo con il codice sopradescritto, ovvero: container.createnewagent("rma","jade.tools.rma.rma", null).start(); L rma è provvisto di una interfaccia grafica, che offre molte comodità e funzionalità, tra cui: Possiamo vedere i vari Container presenti nella Piattaforma e per ciascuno di essi gli Agenti contenuti. E possibile effettuare le operazioni di creazione o distruzione di utenti e containers. Nella barra del titolo è presente l indirizzo Ip e la porta della Piattaforma in uso Possiamo avviare gli altri Tools di Jade, ad esempio l utile Sniffer, che consente di catturare e leggere tutti i messaggi inviati tra gli Agenti.

12 2.3 Inizializzazione degli Agenti 8 Notiamo subito che oltre all Agente che abbiamo appena creato (l rma), nel Main Container erano già presenti due Agenti (creati insieme alla Piattaforma stessa): L ams registra i nomi di tutti gli Agenti che vengono creati, e assicura che ciascuno abbia un nome univoco. Inoltre rappresenta l autorità all interno della piattaforma, ovvero è l Agente al quale gli altri Agenti devono rivolgersi per compiere determinate operazioni. E in grado di fornire l elenco dei nomi degli Agenti a coloro che lo richiedono, ovvero offre un servizio di Pagine Bianche. Il df fornisce invece un servizio di Pagine Gialle, ovvero è in grado di fornire su richiesta la lista degli Agenti che rispecchiano determinate caratteristiche (che offrono determinati servizi). Una differenza importante rispetto all ams è che gli Agenti presenti nella Piattaforma non sono automaticamente riconosciuti dal df, ma devono registrarsi per poter essere trovati con le ricerche fatte dagli altri Agenti. Per concludere la sezione, il codice seguente consente di fare l operazione di creazione di un Agente da Android. Anche qui dobbiamo ricorrere ad una Callback: agentstartupcallback = new RuntimeCallback<Void>() public void onsuccess(void thisisnull) { // Agente creato correttamente public void onfailure(throwable throwable) { // Creazione fallita microruntimeservicebinder.startagent(nome, classe, args, agentstartupcallback); 2.3 Inizializzazione degli Agenti Una volta che un Agente è stato creato, ha assunto un regolare nome univoco e un indirizzo, e l ams è venuto a conoscenza della sua presenza, allora il corrispondente Thread può cominciare la sua esecuzione. Il primo metodo dell Agente che viene invocato è il setup(), nel quale solitamente si effettuano le seguenti operazioni: si recuperano i parametri passati all Agente al momento della sua creazione, che serviranno per personalizzarlo. ci si registra con il DF (fornendo l elenco dei Servizi offerti) se si desidera essere trovati tramite il servizio di Pagine Gialle

13 2.3 Inizializzazione degli Agenti 9 si aggiungono tutte le Ontology che l Agente deve conoscere e gestire (il concetto di Ontology sarà trattato in seguito) si aggiungono i codec che verranno utilizzati per codificare e decodificare il contenuto degli ACLMessage nella forma appropriata (tra cui Stringhe o sequenze di byte). si definiscono e si aggiungono all Agente i suoi comportamenti autonomi (Behaviour) si creano e inizializzano le strutture dati che servono all Agente per memorizzare informazioni e prendere così le proprie decisioni. public class BookSellerAgent extends Agent{ // Place where the Books owned by this Seller Agent are stored private Books library; // Codec for the SL Language (ACLMessages) private SLCodec protected void setup(){ codec = new SLCodec(); super.getcontentmanager().registerlanguage(codec); super.getcontentmanager().registerontology(bookontology.getinstance()); this.library = new Books(); for (Object o: super.getarguments()) if (o instanceof Book){ this.library.add((book) o); DFAgentDescription agentdescription = new DFAgentDescription(); agentdescription.setname(super.getaid()); ServiceDescription servicedescription = new ServiceDescription(); servicedescription.setname("book Selling"); servicedescription.settype("book Selling"); agentdescription.addservices(servicedescription); try { DFService.register(this, agentdescription); catch (FIPAException e) { e.printstacktrace(); super.dodelete();... // Creation and addition of Behaviours to the scheduler super.addbehaviour(new ReceiveQueriesBehaviour()); super.addbehaviour(new SellBookBehaviour());

14 2.4 Gestione Eccezioni e Terminazione Agente Gestione Eccezioni e Terminazione Agente Nel metodo setup() del venditore di libri illustrato nella sezione precedente notiamo che se la registrazione con il DF fallisce viene lanciata una Eccezione (di classe FIPAException). Il comportamento che dobbiamo adottare nella gestione delle Eccezioni all interno di un Agente varia a seconda della categoria: Per quanto riguarda le Eccezioni che estendono RuntimeException, il linguaggio Java stesso ci permette di non gestirle (ovvero il compilatore non segnala errori se non dichiariamo l eccezione dell intestazione del metodo o non allestiamo un blocco try-catch). Esempi di queste Eccezioni sono IllegalArgumentException, NullPointerException, StringIndexOutOfBoundsException... Le eccezioni non catturate in Jade vengono stampate nella console (con printstacktrace) e innescano la terminazione dell agente, tramite la chiamata al metodo dodelete() dell Agente, che inizia la transizione verso lo stato Dead. Le Eccezioni che non estendono RuntimeException (ad esempio FI- PAException) devono essere gestite dal programmatore. In particolare dovremo (se non lo facciamo il compilatore segnerà errore) catturarle tramite try-catch, poichè i metodi della classe Agent che abbiamo sovrascritto (tra cui setup) non ci permettono di dichiarare eccezioni tramite la clausola throws. Nel mio caso ho gestito la FIPAException con la stessa strategia di Jade, ovvero stampare l eccezione e far terminare l Agente. Durante la transizione di stato verso Dead (ovvero poco prima di terminare) viene invocato il metodo speculare di setup(), ovvero takedown(), che possiamo sovrascrivere allo scopo di effettuare tutte le operazioni di cleanup necessarie, tra cui solitamente è presente la deregistrazione al DF se nel setup è stata fatta la registrazione. Ha lo stesso compito del distruttore delle classi del C++. Mentre l Agente esegue il metodo takedown è ancora in grado di inviare messaggi agli altri public void takedown(){ // When this Agent terminates, he has to remove himself from the Yellow Page Service (DF) // Otherwise he will still considered a valid result even dead try { DFService.deregister(this); System.out.println(getLocalName()+": Taking down..."); catch (FIPAException e) { e.printstacktrace();

15 2.5 I Behaviour I Behaviour Le operazioni che l Agente compie durante la sua vita e le decisioni che vengono compiute in autonomia dall Agente in risposta a determinati eventi sono contenute all interno di uno o più Behaviour. Ciascun Agente può avere un numero arbitrario di Behaviour, che può anche cambiare durante l esecuzione, tramite addbehaviour(behaviour) e removebehaviour(behaviour) dell Agente. Tuttavia solo un Behaviour per volta è in esecuzione, infatti la classe Agent implementa (in modo automatico e invisibile all esterno) un meccanismo di Scheduling Round Robin senza Prelazione. Ciò significa che se uno dei Behaviour entra in un ciclo infinito (o svolge operazioni molto pesanti), gli altri non avranno possibilità di essere eseguiti, poichè l intero Thread dedicato all Agente in questione sarà bloccato. E quindi una buona norma costruire i Behaviour in modo tale da compiere operazioni leggere e brevi, o comunque interrompibili in uno o più punti (e essere in grado di riprendere da dove ci si era interrotti) per lasciare spazio anche agli altri. I metodi che possiamo (o dobbiamo, a seconda dei casi) sovrascrivere quando definiamo un nostro Behaviour sono: action(), nel quale definiamo le azioni che vengono compiute quando lo Scheduler manda in esecuzione questo Behaviour. Se abbiamo progettato il Behaviour come interrompibile, dobbiamo gestire in modo adeguato i casi in cui il Behaviour ha iniziato il suo lavoro o lo ha ripreso dal punto in cui si era interrotto. Quando il metodo action() termina viene invocato il metodo done(). done(), nel possiamo distinguere i casi di terminazione di action(). Se action() è terminato perchè il Behaviour ha concluso il suo lavoro allora restituiamo true (in questo caso il Behaviour verrà rimosso dalla coda dello Scheduler). Se invece action() è terminato per interrompersi e riprendere in seguito, allora restituiamo false. Ciò che succede in quest ultimo caso dipende dal fatto che il programmatore abbia invocato o meno il metodo block() del behaviour. Normalmente (ovvero se block non è stato invocato), il Behaviour torna in fondo alla coda dello Scheduler. onend(), il quale viene invocato quando done() restituisce true, possiamo usarlo per definire un valore di ritorno (intero) per il Behaviour, oltre ad eventuali operazioni di cleanup. onbegin(), che è speculare rispetto a onend(), viene invocato solo una volta, prima di eseguire per la prima volta il metodo action(). I Behaviour possono decidere di portarsi in stato di sleep, qualora stiano aspettando il verificarsi di un determinato evento per proseguire con il loro

16 2.5 I Behaviour 12 lavoro (ad esempio lo scadere di un certo timeout o la ricezione di un messaggio con determinate caratteristiche). Per spostarsi nello stato di sleep, i Behaviour (dentro il metodo action) devono invocare il metodo block() oppure block(timeout) e fare in modo che done() restituisca false (in caso contrario il Behaviour verrebbe eliminato). I Behaviour che si trovano nello stato di sleep non vengono più considerati dallo Scheduler, il quale farà proseguire altri Behaviour. Un Behaviour esce dallo stato di sleep (e torna quindi nella coda dello Scheduler) quando: Il timeout associato alla chiamata di sleep è scaduto (ovviamente se si è utilizzato il metodo block con 1 parametro). Un altro Behaviour (che non si trova a sua volta nello stato di sleep) decide esplicitamente di risvegliarlo con il metodo restart(). L Agente ha ricevuto un nuovo messaggio. In questo caso tutti i Behaviour vengono risvegliati. Ciascuno di questi, quando verrà rimandato in esecuzione dallo Scheduler, dovrà verificare che il nuovo messaggio non sia già stato letto da un Behaviour mandato in esecuzione prima di lui, e di essere interessato a quel tipo di messaggio. Nel caso che queste condizioni non siano verificate il Behaviour potrà decidere di tornare nello stato di sleep. Quando definiamo i nostri Behaviour, oltre a poter estendere la classe base Behaviour (in questo modo dobbiamo definire action e done), possiamo anche adottare alcune scorciatoie andando ad estendere alcune sottoclassi (intese nella gerarchia) di Behaviour: OneShotBehaviour modella un Behaviour che non ha bisogno di tornare nella coda dello Scheduler poichè gli basta una sola esecuzione per compiere il leggero carico di lavoro ad esso assegnato. In particolare il metodo done() restituisce sempre true, quindi non è necessario farne l override. CyclicBehaviour modella un Behaviour che deve essere sempre presente durante la vita dell Agente (in esecuzione, nella coda o in stato di sleep), vengono utilizzati solitamente per gestire i vari tipi di messaggi che l Agente può ricevere, o per fornire i servizi che ha specificato quando si è registrato al DF. Il metodo done() restituisce sempre false. TickerBehaviour è un particolare Behaviour che non segue il normale funzionamento della coda. Infatti viene selezionato dello Scheduler e portato in esecuzione solo ed esclusivamente ogni X millisecondi (dove X è stato specificato dal Behaviour stesso), molto utile per effettuare operazioni periodiche (ad esempio la ricerca sul DF di un determinato Agente, effettuata ogni 10 secondi fino a che non viene trovato). Il

17 2.5 I Behaviour 13 metodo done() restituisce sempre false come per le CyclicBehaviour, quindi per terminare l esecuzione si deve esplicitamente invocare il metodo removebehaviour() dell Agente. WakerBehaviour è un Behaviour temporizzato come TickerBehaviour. E possibile specificare una data superata la quale (o un timeout preciso trascorso il quale) il Behaviour si sveglia e esegue (in una unica soluzione) le istruzioni nel suo metodo onwake(). FsmBehaviour modella un Behaviour interrompibile che può trovarsi in uno stato (che definisce le azioni da compiere quando lo Scheduler lo rimette in esecuzione) appartenente ad un certo insieme. Ogni volta che il metodo action() termina lo stato del Behaviour può cambiare (o rimanere lo stesso), a seconda delle transizioni che vengono definite. In altre parole il Behaviour è un Automa a Stati Finiti Deterministico (DFA). Il metodo done() restituisce true solo quando il Behaviour è giunto in uno stato finale. SequentialBehaviour è un DFA semplificato che non necessita di definire le transizioni, perchè per ogni stato è presente solo una transizione, che è verso il successivo, mentre l ultimo è lo stato finale (quindi conta solo l ordine nel quale gli stati vengono aggiunti). A titolo di esempio, la seguente immagine rappresenta il Behaviour principale degli Agenti Buyer, si tratta di un Behaviour complesso implementato con un Automa a Stati Finiti Deterministico (ovvero FSMBehaviour).

18 2.6 Scambio di Messaggi tra gli Agenti Scambio di Messaggi tra gli Agenti Per identificare univocamente un Agente all interno della Piattaforma (e quindi poter interagire con esso) si utilizza il suo nome completo (AID - Agent IDentifier), che unisce il nome locale dell agente (univoco, come anticipato nella sezione dedicata alla creazione degli Agenti), la piattaforma di appartenenza e in container in cui trovarlo. Ciascun Agente ottiene il proprio AID appena dopo la sua creazione, che può essere recuperato con il metodo getaid() dell Agente. Gli Agenti che vivono nella stessa Piattaforma possono comunicare scambiandosi messaggi modellati dalla classe ACLMessage (dove ACL sta per Agent Communication Language). Il messaggio consta di vari campi, accessibili con i metodi getter e setter: Sender è l AID dell Agente che ha creato e che spedirà il messaggio (viene impostato in automatico con il costruttore di ACLMessage). Receivers è una lista di AID ai quali il messaggio verrà recapitato. Inizialmente la lista di destinatari è vuota, è necessario aggiungerne almeno uno (con il metodo addreceiver) per poter inviare il messaggio. Performative è l intento con il quale il messaggio viene inviato, è possibile anche definirlo nel costruttore. La classe ACLMessage prevede alcune costanti che possono essere usate in questo ambito, quali Propose, Refuse, Inform, QueryIf... ConversationID (facoltativo) può essere utile per raggruppare logicamente messaggi e risposte facenti parte di una stessa conversazione. Language indica la codifica del contenuto del messaggio (il mittente e i destinatari devono essere in grado di codificare e decodificare il linguaggio scelto), quello di default è SLCodec (che trasferisce stringhe leggibili dall essere umano), possibili alternative prevedono il trasferimento di sequenze di bytes. Ontology è un insieme di simboli, concetti, predicati e azioni che hanno senso per il mittente e i destinatari. Di default nessuna Ontology è usata, quindi il contenuto dovrà essere interpretato dai destinatari. Content è il contenuto del messaggio, ovvero ciò che si vuole comunicare ai destinatari. Deve rispettare il Linguaggio e la Ontology scelte. In particolare per conversazioni poco articolate e monotematiche si può pensare di non utilizzare nessuna Ontology e di lasciare il Language di default, ovvero la conversazione è basata su scambi di Stringhe, in questo caso è possibile specificare il contenuto normalmente con setcontent(string). Se invece si utilizzano Language e

19 2.6 Scambio di Messaggi tra gli Agenti 15 Ontology, quindi la conversazione è più articolata e strutturata, bisogna usare il metodo getcontentmanager.fillcontent(aclmessage, ContentElement) che in automatico effettua la conversione di ContentElement (che è un Predicato o una Azione che fa parte della Ontology scelta) nel formato specificato dalla Language e lo inserisce nel messaggio come contenuto. Per inviare il messaggio (dopo averlo creato e riempito i campi desiderati) è sufficente invocare il metodo send(aclmessage) dell Agente. In questo modo il messaggio sarà recapitato nella mailbox dei destinatari dopo avere individuato il Container nel quale vivono. L arrivo di un nuovo messaggio nella mailbox di un Agente fà si (come abbiamo visto in precedenza) che tutti i behaviours dell Agente stesso che avevano invocato il metodo block() vengano risvegliati dallo stato di sleep e posizionati nuovamente nella coda dello Scheduler. Il messaggio verrà gestito da uno solo di questi Behaviour (o di quelli che non erano in sleep), quello che è interessato a quel tipo di messaggio. Ciascun behaviour può definire quali sono i messaggi al quale è interessato mediante la classe MessageTemplate, che definisce dei filtri (combinabili con le operazioni logiche) sui campi dell ACLMessage. Quando un Behaviour trova un messaggio di suo interesse dentro la mailbox, questo viene rimosso dalla mailbox, e quindi agli eventuali altri Behaviour la mailbox risponderà che non ci sono più nuovi messaggi. Un Agente (o meglio i Behaviour dell Agente) può accedere alla propria mailbox per prelevare messaggi, con due strategie differenti: receive, che ritorna null se nessun nuovo messaggio è presente nella mailbox. Se invece ci sono uno o più nuovi messaggi, il metodo restituisce uno di questi (in un oggetto di classe ACLMessage). E possibile utilizzare un MessageTemplate per fare sì che il metodo restituisca null anche quando i nuovi messaggi presenti nella mailbox non sono di nostro interesse. blockingreceive, che funziona esattamente come il precedente, ma quando quest ultimo restituirebbe null, invece questo manda tutti i behaviour in stato di sleep.

20 2.6 Scambio di Messaggi tra gli Agenti 16 private class ReceiveQueriesBehaviour extends CyclicBehaviour{ private MessageTemplate t; public ReceiveQueriesBehaviour(){ // Accepting only queries about Books decodable with the SL Codec t = MessageTemplate.and( MessageTemplate.MatchPerformative(ACLMessage.QUERY_IF), MessageTemplate.and( MessageTemplate.MatchOntology(BookOntology.INSTANCE.getName()), MessageTemplate.MatchLanguage(codec.getName()) ) public void action() { try{ ACLMessage message = myagent.receive(t); if (message == null){ // If no message respecting template arrived super.block(); // The Behaviour goes into the Sleep State return; // If a message has arrived, I decode the content ContentElement c = getcontentmanager().extractcontent(message); // Creating the reply ACLMessage (Reply receiver = Message sender) ACLMessage reply = message.createreply(); if (c instanceof Own){ // An Agent is asking me if I own a book Own own = (Own) contentelement; // Searching the requested book in the library Book book = library.getbook(own.getbookname()); if (book == null){ // If not found, i reply with a No AbsPredicate not = new AbsPredicate(SLVocabulary.NOT); not.set(slvocabulary.not_what, BookOntology.INSTANCE.fromObject(own)); reply.setperformative(aclmessage.failure); myagent.getcontentmanager().fillcontent(reply, not); else{ // If found, i reply with the price of the book reply.setperformative(aclmessage.propose); Costs costs = new Costs(book.getBookName(), book.getprice()); myagent.getcontentmanager().fillcontent(reply, costs); myagent.send(reply); catch(exception e){ e.printstacktrace(); myagent.dodelete();

21 2.7 Creare una Ontology e i suoi Componenti Creare una Ontology e i suoi Componenti Come anticipato nelle sezioni precedenti, una Ontology è un insieme di Concetti, Predicati (affermazioni sui concetti che possono avere un valore di verità) e Azioni che hanno senso per una certa categoria di Agenti. Prima di creare la Ontology dobbiamo costruire i singoli componenti, implementando rispettivamente le interfacce Concept, Predicate o AgentAction. Non ci sono metodi dei quali dobbiamo fare l override, tuttavia la classe implementante deve soddisfare i seguenti requisiti: Deve avere il costruttore di default pubblico e accessibile. In particolare ricordiamo che se non specifichiamo nessun costruttore il compilatore in automatico ci fornisce il costruttore senza parametri che non fa nulla. Nel caso che invece abbiamo dichiarato un costruttore che prevede parametri, il compilatore non ci fornisce nulla, quindi dobbiamo dichiarare a mano anche quello senza parametri. Per ogni attributo Attr bisogna fornire i metodi getter (per leggere il contenuto della variabile) e setter (per impostare il contenuto della variabile), pubblici e accessibili, nella forma canonica getattr e setattr. public class Costs implements Predicate{ private static final long serialversionuid = L; private Price price; private BookName bookname; public Costs(){ public Costs(BookName bookname, Price price){ this.bookname = bookname; this.price = price; public Price getprice() { return price; public void setprice(price price) { this.price = price; public BookName getbookname() { return bookname; public void setbookname(bookname bookname) { this.bookname = bookname;

22 2.7 Creare una Ontology e i suoi Componenti 18 Una volta creati tutti i Concept, Predicate e AgentAction implementando l interfaccia adeguata e soddisfando i requisiti richiesti (non ci sono particolari differenze nel codice che si va a scrivere nei 3 casi), possiamo creare la Ontology. Le Ontology di Jade si distinguono tra di loro per il nome che viene assegnato a ciascuna. In generale non è necessario creare più oggetti di un particolare tipo di Ontology, pertanto si sfrutta il design pattern Singleton (rendendo il costruttore privato e fornendo una sola istanza accessibile staticamente). public class BookOntology extends Ontology{ public static final String ONTOLOGY_NAME = "BookOntology"; // The Ontology should always be a singleton public static final BookOntology INSTANCE = new BookOntology(); public static final BookOntology getinstance(){ return INSTANCE;... Per ciascuna classe che implementa Concept, Predicate o AgentAction che desideriamo inserire nella Ontology e per ciascun attributo di quelle classi definiamo una costante di tipo String. Valorizziamo le costanti associate alle classi con il nome delle classi stesse, e le costanti associati agli attributi con lo stesso nome (case-sensitive) con cui sono chiamati gli stessi attributi dentro le rispettive classi. public class BookOntology extends Ontology{... // Class COSTS (Predicate) public static final String COSTS = "Costs"; // Attributes public static final String COSTS_PRICE = "price"; public static final String COSTS_BOOKNAME = "bookname";... Una volta create le costanti di Stringa per ciascuna classe e ciascun attributo andiamo ad implementare il costruttore della BookOntology. Innanzitutto dobbiamo dichiarare qual è la Ontology che stiamo estendendo. Infatti potremmo decidere di sfruttare l ereditarietà creando ad esempio una TradingOntology che definisce i concetti alla base del commercio di beni e servizi, in modo tale da riciclare tali concetti nella BookOntology. Se non si desidera sfruttare questa funzionalità, la Ontology che si deve estendere è quella di base. A questo punto dobbiamo aggiungere alla BookOntology tutti i concetti, i predicati e le azioni creati precedentemente, andando a specificare

23 2.7 Creare una Ontology e i suoi Componenti 19 in quale classe trovarle e qual è il nome che desideriamo associare al nuovo componente (sfruttando le costanti di stringa definite prima). private BookOntology() { super(ontology_name, BasicOntology.getInstance()); try { super.add(new ConceptSchema(PRICE), Price.class); super.add(new ConceptSchema(BOOK), Book.class); super.add(new PredicateSchema(COSTS), Costs.class); super.add(new PredicateSchema(OWN), Own.class); super.add(new AgentActionSchema(BUYACTION), BuyAction.class);... catch (OntologyException e) { e.printstacktrace(); Per concludere il costruttore dobbiamo recuperare uno per uno tutti gli Schemi appena aggiunti alla Ontology, tramite il metodo getschema(string) e descrivere nel dettaglio ciascuno di essi, aggiungendo tutti gli attributi che li compongono. Quando aggiungiamo un attributo dobbiamo descrivere: Che nome assume l attributo all interno dello Schema (utilizzando la corrispondente costante di Stringa definita prima). Che tipo di dato è: è uno Schema che è stato precedentemente aggiunto nella BookOntology o è un tipo di dato primitivo? Questo attributo può anche essere null (ObjectSchema.OPTIONAL) all interno dello Schema senza invalidarlo, oppure no? Se l attributo è una lista di oggetti di un determinato tipo, dobbiamo definire le cardinalità minima e massima. try {... ConceptSchema c = (ConceptSchema) super.getschema(book); c.add( BOOK_PRICE, (ConceptSchema) getschema(price), ObjectSchema.MANDATORY ); c.add( );... BOOK_NUMBEROFPAGES, (PrimitiveSchema) getschema(basicontology.integer), ObjectSchema.MANDATORY catch (OntologyException e) { e.printstacktrace();

24 Capitolo 3 Programmazione su Android Questo capitolo descrive la struttura di un Progetto Android e i concetti alla base della programmazione su tale piattaforma. Viene inoltre illustrato come procedere per arrivare ad eseguire la classica applicazione Hello, world!. La guida completa (che è stata usata come riferimento nel lavoro di tesi) su tutto ciò che riguarda lo sviluppo e la pubblicazione di applicazioni Android è possibile trovarla su developer.android.com. 3.1 Ambiente di Sviluppo: ADT Per poter sviluppare applicazioni Android dobbiamo procurarci un apposito ambiente di sviluppo, una possibile scelta è ADT (Android Developer Tools). Si tratta dell usuale ambiente di sviluppo Java, ovvero Eclipse, munito di un plug-in che consente di generare il codice per applicazioni Android (che, come vedremo, saranno costituite da files.java e da files.xml), e di compilarle producendo files.apk che il dispositivo Android è in grado di installare. Inoltre questo plug-in consente di installare ed aggiornare i pacchetti relativi ad Android (window -> android SDK manager) e di simulare una vasta gamma di dispositivi Android stessi. Ogni volta che eseguiamo un Android Project via ADT possiamo infatti scegliere se fare l upload e l installazione del file.apk in un dispositivo Android reale connesso via USB, oppure se utilizzare l emulatore di ADT stesso. Tuttavia l emulatore non si presta ai nostri scopi, poichè (oltre all intrinseca lentezza) non presenta sensori di alcun tipo. Possiamo procurarci Android Developer Tools su developer.android.com/sdk/index.html. 3.2 Creare ed Eseguire un Android Project Per creare una nuova applicazione nel nostro ambiente di sviluppo ADT andiamo su File -> New -> Android Application Project. Nella prima finestra che ci viene proposta dobbiamo scegliere il nome dell applicazione che

25 3.2 Creare ed Eseguire un Android Project 21 comparirà in Android (quindi è meglio sceglierlo corto in modo tale che non venga tagliato), il nome del progetto (dentro ADT) e il nome del package (composto da almeno due parti, che deve rimanere immutato, quindi è meglio pensarci bene prima di sceglierlo). Nelle finestre successive solitamente non abbiamo la necessità di cambiare nulla. Una volta completata la procedura concentriamo la nostra attenzione sulla struttura di files e directory generate: La directory src contiene il codice Java da noi scritto per la nostra applicazione. Se non abbiamo cambiato nulla nella procedura di creazione del progetto, notiamo che nel package che abbiamo specificato è già presente una Activity, di nome MainActivity, che attualmente è la prima ad essere eseguita quando la applicazione Android viene lanciata. La directory gen contiene altro codice Java che fa parte della nostra applicazione. Questo codice è generato e/o modificato automaticamente dal compilatore ogni volta che creiamo o modifichiamo i file.xml dell applicazione stessa. Nella directory libs possiamo collocare le librerie (gli archivi.jar) della quale l applicazione ha bisogno. Attualmente contiene android-supportv4.jar che consiste in un insieme di utility per le operazioni più comuni in Android. La questione di importazione di librerie e/o progetti Java/Android è molto delicata, perchè è facile sbagliarsi e perdere tempo, pertanto sarà trattata più nello specifico. La directory res (resources) è quella più importante, perchè ci consente di creare e configurare la parte statica della nostra applicazione. In particolare all interno di res troviamo diverse directory drawable, in tali directory andremo a posizionare tutte le immagini, che potranno ad esempio essere utilizzate come sfondo o come icone nella nostra applicazione. Le varie directory dovranno contenere le stesse immagini (ovvero files con gli stessi nomi) con dimensioni diverse (low, medium, high, extra-high, extra-extra-high), in modo tale che se l applicazione deve disegnare una immagine (ad esempio ic_launcher.png che dovremmo già avere all interno di queste directory) può scegliere tra diverse alternative, a seconda dello spazio a disposizione sullo specifico dispositivo Android sulla quale è in esecuzione. E stato definito un insieme di immagini standard per le azioni più comuni, che è bene utilizzare per il principio di familiarità nell ambito dell usabilità del software. Dentro res inoltre troviamo le directory layout, menu e values, che contengono files.xml riguardanti rispettivamente gli oggetti contenuti nelle videate, le scelte presenti nei menu, e le costanti (di stringa, di colore o di dimensione) utilizzate nell ambito dell interfaccia grafica. Ciascuna di queste tre categorie sarà affrontata singolarmente.

26 3.3 Importare Progetti e Librerie 22 Nel file AndroidManifest.xml possiamo configurare l applicazione Android sotto diversi aspetti, che saranno trattati nella sezione apposita. Per lanciare l applicazione andiamo nel menu run, scegliamo Android Application, e successivamente il device sul quale eseguirla (o l emulatore, che per questa semplice applicazione può essere usato). Se il dispositivo Android presenta la schermata di blocco (o lo schermo si è spento), passiamo il dito sullo schermo stesso per sbloccarlo. Solitamente è meglio disattivare l oscuramento dello schermo (e la conseguente schermata di blocco) mentre si sta programmando, andando nel menu Impostazioni del dispositivo Android, nella sezione Opzioni Sviluppatore. Se tutto è andato a buon fine, dovremmo vedere una applicazione con il nome che abbiamo scelto (in quella che si chiama Action Bar), e la scritta hello world! nella videata. Inoltre ora capiamo a cosa è stata utilizzata la ic_launcher che abbiamo trovato nelle directory Drawable. La applicazione che abbiamo appena lanciato è stata inoltre installata sul dispositivo, quindi potrà essere individuata e lanciata anche dal dispositivo Android stesso. 3.3 Importare Progetti e Librerie Per costruire un Android Project possiamo avere bisogno di importare librerie (ovvero file.jar), altri Android Project, oppure normali progetti Java. Le risorse linkate in modo errato non presentano problemi in fase di stesura del codice (ovvero il compilatore inline di Eclipse non notifica alcun errore), tuttavia poi i problemi si presentano quando la applicazione è in esecuzione su Android, al primo uso di una classe non riconosciuta. Per specificare le risorse che uno specifico progetto deve importare lo selezioniamo e scegliamo Properties nel menu Project. Le schede che ci interessano sono due: 1. Nella scheda Android possiamo aggiungere (tramite il pulsante Add) altri Android Project che si trovano dentro lo stesso Workspace di questo. Possiamo aggiungere solo ed esclusivamente gli Android Project che hanno spuntato il flag Is Library, che vediamo nella scheda Android stessa. Gli Android Project settati con Is Library non possono essere installati (e quindi nemmeno eseguiti). I progetti aggiunti in questo modo non devono più essere considerati nel punto successivo. 2. Nella scheda JavaBuild Path possiamo aggiungere i progetti Java (dentro lo stesso workspace) e le librerie (interne o esterne al workspace). E importante ricordarsi di spuntare tutti i progetti e le librerie aggiunte in Order and Export per fare si che tali risorse finiscano del file.apk.

27 3.4 Activity e Intent 23 E importante fare attenzione a non importare più volte Android Support v4.jar, errore che mi è capitato spesso facendo gerarchie complesse di progetti. E sconsigliabile creare i.jar dei propri Android Project mentre si sta programmando (per importarli negli altri progetti al posto di importare gli Android Project stessi), perchè si creano altri problemi (tra cui dover fare il refresh di tutti i progetti ogni volta che viene fatta una modifica, e problemi di dipendenze). In particolare se vogliamo creare un progetto Android che si appoggi sulle funzionalità offerte da Dave (descritte nel relativo capitolo) dobbiamo importare gli Android Library Project Dave Android e GooglePlayServicesLib. Quest ultima libreria consente di utilizzare le Google Maps all interno della propria applicazione. Possiamo ottenerla istallandola con l SDK Manager del nostro ambiente di sviluppo, seguendo le semplici istruzioni che troviamo qui. 3.4 Activity e Intent Una applicazione Android è composta da una o più Activity, ciascuna delle quali fornisce una interfaccia grafica (che, nella maggior parte dei casi, copre tutto lo schermo) con la quale l utente Android può interagire. Una delle Activity deve essere la launch Activity, che è quella di partenza della applicazione. Le Activity che fanno parte di una singola applicazione sono collegate tra di loro, ovvero ciascuna Activity ha la possibilità di iniziarne un altra allo scopo di compiere specifiche operazioni. In questo caso la nuova Activity viene messa in foreground, mentre quella precedente viene messa in stato di pausa (vengono compiute le operazioni di scrittura su memoria persistente rimaste in sospeso, interrotte animazioni e rilasciate risorse). Tutte le Activity, ovvero quella in foreground e quelle in background rimangono memorizzate in una struttura dati a pila, la quale permette di riportare velocemente in foreground (tramite l operazione pop) l Activity più recente. Le Activity presenti nella pila (tranne quella in foreground) possono essere distrutte per necessità di memoria, in tale caso lo stato della istanza della Activity (che viene salvato ogni volta che la Activity va in stato di pausa) deve essere ripristinato qualora l utente ritorni sulla Activity (se l Activity invece è rimasta nella pila l operazione di ripristino non è necessaria). La Activity ha un ciclo di vita composto da diversi stati (lo stato di pausa ne fa parte), ciascuna transizione verso uno stato corrisponde all invocazione del corrispondente metodo (ad esempio onpause), che il programmatore può sovrascrivere per effettuare le proprie operazioni (di cleanup, salvataggio, ripristino...).

28 3.4 Activity e Intent 24 package it.unipr.informatica.prova; import android.os.bundle; import android.app.activity; import android.view.menu; public class MainActivity extends Activity protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); public boolean oncreateoptionsmenu(menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getmenuinflater().inflate(r.menu.main, menu); return true; Quando costruiamo una Activity possiamo sovrascrivere alcuni metodi, per definire i comportamenti che la Activity deve seguire nelle transizioni di stato citate poco fa o al verificarsi di determinati eventi: oncreate: questo metodo viene invocato quando l Activity viene creata (savedinstancestate == null) oppure viene ricreata da un istanza precedentemente salvata. Bundle è una struttura dati che associa a chiavi di tipo String valori di tipo arbitrario. Tramite il metodo setcontentview(int) facciamo in modo che il contenuto della videata sia quello definito nel file xml oppotuno. onpause: questo metodo viene invocato quando l Activity non è più in primo piano (ovvero quando l utente passa ad un altra applicazione/activity lasciando aperta questa). Di solito si fa l override di questo metodo se è possibile rilasciare risorse e/o servizi al fine di ridurre il consumo di batteria. onresume: speculare di onpause, invocato quando l Activity torna in primo piano. ondestroy: speculare di oncreate, invocato quando l Activity sta per essere distrutta. E possibile effettuare operazioni di clean-up aggiuntive (perchè il metodo onpause viene invocato prima di ondestroy). onsaveinstancestate: metodo invocato prima di ondestroy che consente di creare e riempire un oggetto di tipo Bundle con i dati necessari ad una successiva ricreazione della Activity.

29 3.5 Manifest della Applicazione 25 oncreateoptionsmenu: invocato quando il menu sta per essere creato, consentendoci di associare il file.xml che contiene quello desiderato. onoptionsitemselected: metodo invocato quando uno degli oggetti del menu viene selezionato. Ci viene fornito l id dell oggetto che ha innescato l evento, in modo tale che con costrutti if o switch possiamo gestirlo in modo appropriato. Un Intent è un messaggio che viene inviato per richiedere una azione da parte di un altro componente della applicazione. L Intent contiene principalmente: L azione che si desidera che il/i riceventi del messaggio compiano. Le informazioni delle quali necessitano il/i riceventi per compiere l azione. Si tratta di una mappa <chiave, valore>, chiamata Extra dell Intent. Gli intent possono essere usati in particolare per iniziare un altra Activity, o per instaurare una dialogo tra diverse Activity. Per definire i tipi di Intent che ciascuna Activity supporta (ovvero le azioni supportate), si costruisce un IntentFilter, del quale discuteremo più avanti. Questa meccanica del filtro è necessaria, poichè tipicamente gli Intent vengono mandati in Broadcast. 3.5 Manifest della Applicazione Nel file Manifest vengono elencate tutte le caratteristiche della applicazione Android, tra cui: L icona (nome della immagine dentro la directory Drawable), il nome della applicazione (quello che abbiamo specificato nella procedura di creazione dell applicazione stessa) e il package di appartenenza. I dispositivi Android supportati dalla applicazione, stabilendo un range di versioni SDK. Solo i dispositivi che hanno una versione compresa nel range specificato possono eseguire la applicazione. I permessi che la applicazione deve ottenere per poter funzionare correttamente. I permessi elencati nel manifest sono gli stessi che vengono esposti all utente al momento del download di una applicazione da Google Play. Possono riguardare l accesso a Internet, l uso della Rubrica, la necessità di impedire lo Stand-By... I servizi di cui l applicazione ha bisogno. I servizi sono attivi a tempo continuato e lavorano in background rispetto alle Activity, le quali possono contattare (tramite l operazione di bind) il servizio stesso per poterne usufruire.

30 3.5 Manifest della Applicazione 26 L elenco delle varie Activity che compongono la applicazione, le loro caratteristiche (se è la Launch Activity, se è necessaria una specifica orientazione del telefono...) e la loro gerarchia. Se ad esempio vogliamo fare sì che la nostra applicazione possa accedere ad Internet per poter scaricare e visualizzare le Google Maps, e ricevere i dati relativi alla posizione tramite GPS e WiFi, dobbiamo aggiungere i seguenti permessi nel file manifest (prima del tag <application>). <uses-permission android:name="android.permission.internet" /> <uses-permission android:name="android.permission.access_network_state" /> <uses-permission android:name="com.google.android.providers.gsf.permission.read_gservices" /> <uses-permission android:name="android.permission.access_coarse_location" /> <uses-permission android:name="android.permission.access_fine_location" /> Tuttavia per poter usufruire delle Google Maps per Android dobbiamo anche richiedere il servizio a Google. Dopo aver fatto il login su Google andiamo su Dobbiamo creare un nuovo progetto (ci verrà proposto dalla pagina stessa di farlo) con lo stesso nome della applicazione Android che stiamo sviluppando. Il nostro obiettivo è abilitare il servizio Google Maps Android API v2 per il progetto che abbiamo creato, le operazioni da svolgere dipendono dall interfaccia grafica che vi presenterà Google. Una volta abilitato il servizio, dobbiamo associare il progetto creato in remoto con quello locale in ADT, creando una nuova Android Key. Ci verrà richiesto di inserire l impronta SHA1 del nostro progetto dentro ADT e il relativo package che avevamo scelto al momento della creazione (ora disponibile nel manifest). Per ottenere l impronta SHA1 dobbiamo selezionare il progetto nel Package Explorer di ADT, poi andare in Window - > Preferences -> Android -> Build. Una volta inserite queste informazioni (separate da un punto e virgola), Google genererà una Android Key, che dobbiamo aggiungere nel file Manifest (prima del tag <activity>) nel seguente modo: <meta-data /> android:name="com.google.android.maps.v2.api_key" android:value="aizasyatcq0jixahtofu-u89f9xnfiohbckq0lq" Se la nostra applicazione necessita di servizi (ad esempio Jade per Android), anche questi vanno specificati in questo punto del file manifest (ovvero prima del tag <activity>): <service android:name="jade.android.microruntimeservice" />

31 3.6 Costanti di Stringa usate dalla Applicazione Costanti di Stringa usate dalla Applicazione Nel file strings.xml (che troviamo nella directory values) vengono memorizzate tutte le costanti di Stringa che vengono usate dall applicazione. In particolare al suo interno troviamo la costante di stringa app_name, che è valorizzata con il nome della Applicazione. Possiamo utilizzare questa (o un altra) costante ovunque, ovvero: all interno degli altri file.xml (in particolare app_name viene usata nel manifest), nel seguente nei file.java all interno della directory src, nel seguente modo: R.string.app_name // la classe R si trova all interno dei file java generati, ovvero dentro la directory gen Anche dimens e styles seguono lo stesso principio sopradescritto, ma sono di raro utilizzo. 3.7 Descrizione del Menu di una Activity Ad ogni Activity (ad esempio MainActivity) è associato un file xml (ad esempio main.xml) dove viene descritto il suo menu. Il menu è composto da oggetti che possono trovarsi nella Action Bar (ovvero la barra sotto quella delle notifiche, dove è presente anche il nome della Activity), oppure che possono comparire premendo il tasto menu del dispositivo Android. Ogni oggetto del menu possiede i seguenti attributi: id: utilizzato dall applicazione per identificare l oggetto quando deve gestire gli eventi dell interfaccia e le loro sorgenti. title: visualizzato su schermo se l oggetto non si trova nella Action Bar icon: immagine visualizzata su schermo se l oggetto si trova nella Action Bar showasaction: determina se e quando l oggetto deve finire nella Action Bar, possibili scelte sono always, never, o ifroom (se c è spazio)

32 3.8 Descrizione della Videata di una Activity Descrizione della Videata di una Activity Ad ogni Activity (ad esempio MainActivity) è associato un file xml (ad esempio activity_main.xml) dove viene descritto il contenuto della videata. Innanzitutto dobbiamo definire un layout, ovvero come gli oggetti devono essere disposti, i più usati sono: RelativeLayout, in cui per ogni oggetto si può specificare la posizione rispetto ad un altro oggetto (sotto a, a fianco di...), cercando di non fare riferimenti circolari. LinearLayout, che dispone gli oggetti sempre nella stessa direzione (verticale o orizzontale, che possiamo specificare tramite l attributo android:orientation). Tra gli oggetti che possiamo inserire abbiamo pulsanti (ai quali possiamo rispondere all evento onclick), campi di testo, checkbox, radio button, pulsanti on/off, menu a tendina, selezionatori (di data e ora ad esempio). Questi oggetti, insieme alle voci del menu trattate nella sezione precedente, costituiscono la principale modalità di interazione dell utente con la Activity corrente.

33 Capitolo 4 La Library Dave Questo capitolo descrive la libreria Dave (Discover Agents Viewed on Earth) facendo una panoramica sulle principali classi delle quali è composta. Per ciascuna classe verrà spiegato il funzionamento in termini di operazioni effettuate, lo scopo all interno della libreria, ed eventuali esempi di utilizzo. Verranno utilizzati nella spiegazione alcuni concetti quali Agente, Behaviour, Activity, Intent che sono stati trattati nei capitoli precedenti. Come anticipato nell introduzione, la libreria Dave consente di creare una architettura Client-Server basata sul concetto di Agente di Jade. Ciascun Agente Client ricava ad intervalli regolari la propria posizione e direzione corrente, creando un oggetto di classe EarthPartialCircle, che viene inviato al Server se il cambiamento rispetto a quello precedente è significativo (secondo il giudizio dell UpdatePlanner). Il Server ad intervalli regolari fornisce ad un certo numero di Client (in accordo alla QualityOfService che tali Client hanno richiesto) gli altri Agenti che tali Client vedono, qualora questi siano cambiati. Le operazioni svolte da Client e Server saranno trattate nello specifico nel capitolo riguardante gli Agenti di Dave. E stata anche dedicata una sezione apposita per il Server, per parlare del suo carico computazionale, e delle soluzioni adottate per attenuarlo. La parte finale del capitolo è dedicata alle classi specifiche per Android. Il codice sorgente completo di Dave si articola in tre progetti Java: Il Progetto Dave Base include la parte di Dave che è necessaria sia su PC che su Android, contenente i concetti e le azioni base. Il Progetto Dave Pc include le classi specifiche su PC, tra cui gli Agenti dotati di interfaccia grafica Swing. Deve aggiungere come sorgente il Progetto Dave Base. Il Progetto Dave Android include le classi specifiche per Android, che andranno a gestire gli Intent, i sensori e le GoogleMaps. Deve aggiungere come sorgente il progetto Dave Base.

34 4.1 Le Informazioni Geografiche Le Informazioni Geografiche In questa sezione vengono descritte le classi che descrivono le entità geometriche in ambito terrestre, finalizzate alla rappresentazione (e alla trasmissione) della posizione e del punto di vista degli Agenti. Sono contenute nel package dave.onto.concepts.earth La Posizione: EarthPoint Per identificare univocamente un punto sulla superficie 2D della Terra è sufficiente fornire la corrispondente coppia <latitudine, longitudine>. La latitudine indica l angolo formato dalla retta che passa per il centro della terra e il punto rispetto al piano equatoriale. Due punti che hanno la stessa latitudine si trovano sullo stesso parallelo (in particolare l equatore è il parallelo fondamentale, con latitudine 0). Il polo Nord e il polo Sud formano un angolo retto, ovvero hanno rispettivamente la massima (+90) e la minima latitudine (-90). La longitudine è la distanza angolare di un punto rispetto al meridiano fondamentale, quello che passa per l Osservatorio di Greenwich in Inghilterra (che ha quindi longitudine 0). La longitudine varia da +180 a Due punti che hanno la stessa longitudine si trovano sullo stesso meridiano. Il 180-esimo meridiano est (o ovest) è la linea internazionale del cambio di data, situata nell Oceano Pacifico. La classe EarthPoint, che modella questo concetto, è quindi semplicemente una coppia di reali. Come abbiamo visto sopra, sia la latitudine che la longitudine hanno un range di valori accettati, ma la classe EarthPoint accetta qualsiasi valore per entrambe, effettuando l operazione di modulo 90 per la latitudine e di modulo 180 per la longitudine.

35 4.1 Le Informazioni Geografiche Aggiungiamo la Direzione: EarthVector Gli EarthVector sono segmenti orientati (ovvero vettori) sulla superficie 2D della Terra che congiungono due EarthPoint (quello di partenza è il first- Point, quello di arrivo è il SecondPoint). E possibile costruire un EarthVector in due modi: Specificando il punto di partenza e il punto di arrivo. Specificando il punto di partenza, la direzione (comprensiva di verso) e il modulo. Per calcolare la direzione dobbiamo prendere come sistema di riferimento quello costituito dai paralleli e dai meridiani (ad esempio scegliamo come asse x l equatore e come asse y il meridiano di Greenwich). Troviamo l intersezione della retta su cui giace l EarthVector con l asse x e tracciamo un asse y parallela a y e passante per quel punto. Abbiamo così individuato due angoli. Per ottenere univocamente la direzione dobbiamo includere anche il verso. Nell immagine sottostante, la direzione del vettore AB è di 30 gradi se il vettore va da A a B, mentre è di 210 gradi se va da B ad A. Il modulo (o lunghezza) è la distanza in linea d aria tra i due estremi del vettore. Esistono alcune formule trigonometriche che consentono di calcolare la distanza e la direzione tra due EarthPoint, implementate nella classe EarthGeometry. Queste formule (e le relative nozioni) sono state tratte dai siti sunearthtools.com e movable-type.co.uk, che offrono anche una utile prova interattiva.

36 4.1 Le Informazioni Geografiche Il Punto di Vista: EarthPartialCircle Un EarthPartialCircle è un cerchio (parziale), ottenuto facendo ruotare sul piano terrestre di un uguale angolo (che non deve superare i 180 gradi) sia in senso antiorario (leftangle) che in senso orario (rightangle) un Earth- Vector attorno al suo firstpoint (che diventa quindi il centro del cerchio parziale). Conoscendo il totalangle (che è il doppio del rightangle o del leftangle, visto che sono uguali) e l EarthVector è possibile ricavare tutte le altre informazioni, tra cui area e perimetro ad esempio. Questa classe include alcuni metodi di fondamentale importanza per il funzionamento della libreria: contains(earthpoint) è in grado di determinare per ogni EarthPoint se cade all interno della superficie dell EarthPartialCircle oppure no. Questo metodo ci consente di sapere se un Agente è contenuto nel punto di vista di un altro oppure no. getremotenessratio(earthpoint) è in grado di determinare per ogni EarthPoint quante volte il raggio dell EarthPartialCircle è contenuto nella distanza tra il centro e l EarthPoint stesso, fornendoci una informazione sul suo grado di lontananza. getfrontierpoint(double, double, int) restituisce un determinato punto appartenente alla frontiera dell EarthPartialCircle (ovvero sulla circonferenza). Questo metodo (chiamato più volte) ci consentirà di disegnare la circonferenza sulla GoogleMap.

37 4.2 Classe Helper per Jade 33 Ponendo il centro di un EarthPartialCircle nella posizione corrente di un Agente, e la maindirection (ovvero quella dell EarthVector) nella direzione in cui il suo disposivo Android è rivolto, siamo in grado di rappresentare il suo punto di vista. Un agente in Dave è quindi descritto dall EarthPartialCircle corrente, in aggiunta al suo AID, come i normali Agenti di Jade. Le classi che modellano i concetti di descrittore di Agente e di lista di Agenti sono contenute nel package dave.onto.concepts.agent 4.2 Classe Helper per Jade Nel capitolo riguardante Jade abbiamo notato che spesso le istruzioni da utilizzare per le operazioni di creazione di container e agenti sono più di una e cambiano a seconda di trovarci su PC o su Android. Lo scopo è invece avere un unico modo, più compatto ma comunque versatile, per fare queste comuni operazioni. La classe EasyJade definisce le operazioni possibili e la loro struttura, tali operazioni vengono poi implementate in modo diverso dalle classi PcJade e AndroidJade, che estendono EasyJade. Per creare un oggetto PcJade possiamo usare il costruttore con 3 parametri, che sono rispettivamente l Object che intende creare il PcJade (può anche essere null se non serve tenerlo memorizzato dentro a PcJade), l host al quale si vuole connettersi (è possibile specificare indifferentemente l indirizzo Ip oppure il nome), e la porta (è possibile utilizzare la costante EasyJade.DEFAULT_PORT per indicare 1099). Questo costruttore consente di creare un Container Periferico. Notiamo che ci vengono proposti alcuni metodi eventualmente da sovrascrivere: PcJade pcjade = new PcJade(Object caller, String host, int port) { // Invocato quando il servizio di Jade per Android viene disconnesso // Invocato dopo le operazioni di cleanup innescate da public void onfinish() public void oncontainerready() { // Fallimento nella creazione (o nella connessione) al public void oncontainerfailure(throwable throwable) { // Agente creato con public void onagentstartupsuccess() { ; // Fallimento nella creazione di un public void onagentstartupfailure(throwable throwable) {

38 4.3 Gli Agenti di Dave 34 I metodi oncontainerfailure() e onagentstartupfailure() potranno eventualmente essere utilizzati per stampare l eccezione nella console e presentare un appropriato messaggio di errore all utente. Il metodo onagentstartupsuccess può essere utilizzato solo a scopo di debug, visto che non è presente il nome dell Agente creato. Infatti per interagire con il nuovo Agente, si usa invece il Communicator. Il metodo più importante è oncontainerready, invocato (come dice il nome) quando il container (main o periferico) è pronto per creare Agenti. Per creare un Agente (sia usando PcJade che AndroidJade), usiamo uno di questi metodi di EasyJade: createnewagent(string agentname, String classname, Object args); createnewagent(string agentname, String classname, Object[] args); createnewagent(string agentname, String classname); // usiamo questo se l Agente non necessita di argomenti per il setup Per costruire un AndroidJade, abbiamo lo stesso identico costruttore, e gli stessi metodi eventualmente da sovrascrivere. L unica differenza è che l Object caller deve essere non null e instanceof Activity, perchè necessaria per fare il bind e l unbind del servizio di Jade per Android. Infine per quanto riguarda PcJade abbiamo ovviamente anche il diritto di creare Main Container locali ( localhost, sulla porta 1099), usufruendo del costruttore con 1 parametro (anche qui è opzionale, quindi si può usare null): PcJade pcjade = new PcJade(Object caller){ Gli Agenti di Dave DaveClientAgent E la classe base astratta che consente di definire tutti gli Agenti lato client. E astratta perchè i metodi che restituiscono la posizione corrente (getcurrentposition) e la direzione corrente (getcurrentdirection) sono astratti, in modo tale che le classi che estendono DaveClientAgent siano tenute a restituire ad ogni loro chiamata un valore numerico valido, ottenuto in modo diverso per ciascuna. Questo fa sì che si possano creare Client non dipendenti dai sensori di Android. Un DaveClientAgent dopo essere nato (ovvero quando comincia la sua esecuzione nel metodo setup) si aspetta di trovare un oggetto che sia in-

39 4.3 Gli Agenti di Dave 35 stanceof DAVEClientArguments nei suoi argomenti. Un oggetto di classe DAVEClientArguments contiene 4 informazioni: La distanza massima alla quale l Agente potrà vedere. Sarà utilizzato come raggio degli EarthPartialCircle. L ampiezza angolare del suo punto di vista. Sarà utilizzato come totalangle degli EarthPartialCircle. Questo vincolo e quello soprastante sono necessari, perchè erano gradi di libertà nella costruzione dell EarthPartialCircle, ovvero non era univocamente determinato solo dalla posizione e direzione corrente. Un UpdatePlanner, che è un oggetto (che sarà descritto più avanti) che può essere usato per definire quando un cambiamento della direzione o posizione dell Agente è significativo, e che quindi deve essere comunicato al Server. Una QualityOfService (anch essa descritta più avanti), che serve per definire la qualità del servizio che il Server ci deve offrire. Un Communicator (contenuto nel package dave) svolge il ruolo di mediatore tra l Agente e il suo creatore, consentendo a ciascuno di dialogare con l altro. In altre parole un Communicator possiede (e può restituire su richiesta) sia il puntatore all Object che il puntatore all Agente. Communicator può anche essere null, se questa funzionalità non è necessaria. Quando il metodo setup() termina, il DaveClientAgent si mette a cercare un Agente che offra il servizio di Server, tramite un Behaviour (SearchServerBehaviour) eseguito periodicamente ogni secondo. Quando il Server verrà trovato, tale Behaviour verrà sostituito dai seguenti: PresentationBehaviour: il Client deve informare il Server della sua presenza. Le informazioni che deve fornire includono la QualityOf- Service richiesta (che è disponibile, visto che era un argomento), e la sua identità, composta da AID e dall EarthPartialCircle corrente. Per l AID non ci sono problemi, visto che il Server può ricavare il mittente del messaggio, mentre l EarthPartialCircle deve essere costruito con il raggio e il totalangle (che sono costanti che abbiamo specificato negli argomenti d ingresso), e con getcurrentposition() e getcurrentdirection(). Questi ultimi metodi possono anche non essere ancora pronti a fornire tale informazione, magari perchè fanno uso di sensori che sono ancora in fase di inizializzazione. In questo caso la presentazione deve essere rimandata fintanto che tali informazioni non sono disponibili (ovvero anche PresentationBehaviour è eseguita periodicamente fino al suo successo). Se tutte le informazioni

40 4.3 Gli Agenti di Dave 36 sono pronte, viene mandato un messaggio al Server (il cui contenuto include tali informazioni, è una AgentAction definita nella classe dave.onto.concepts.actions.clientsubmission), e viene comunicato all UpdatePlanner che l EarthPartialCircle iniziale è quello usato nella presentazione. ServerMessagesHandlerBehaviour: è sempre in coda o in esecuzione (CyclicBehaviour) quando si conosce il Server o ci si è presentati con esso. Il suo compito è ricevere i messaggi provenienti dal Server, e smistarli nei vari handler a seconda della AgentAction presente nel contenuto. Le possibilità includono ServerUpdate, ServerExit, FollowedUpdate e FollowedExit (che si trovano tutte nello stesso package dave.onto.concepts.actions). Il meccanismo di Following verrà descritto più avanti, vediamo le altre due AgentAction. ServerUpdate contiene le identità (AID + EarthPartialCircle) di tutti gli altri Agenti che si trovano dentro il nostro punto di vista (il centro del loro EarthPartialCircle è contenuto nella superficie del nostro), lo riceviamo quando: La nostra presentazione ha avuto successo, e quindi il Server ci fornisce come risposta la lista iniziale di Agenti che vediamo. Il Server ci ha mandato una nuova lista poichè è cambiata (in accordo alla QualityOfService che abbiamo richiesto al Server) rispetto a quella precedente. Quando riceviamo la AgentAction ServerExit (invocato dal Server quando desidera terminare la sua esecuzione) il comportamento di default è invocare la dodelete() e quindi terminare anche il Client (si potrebbe invece decidere che, invece di morire, il DaveClientAgent vada in stato di sleep e poi provi a cercare un nuovo Server). Il metodo takedown(), invocato durante il processo innescato da dodelete(), consiste nel mandare una AgentAction (ClientExitRequest) al Server, con lo scopo di far dimenticare il Server della nostra presenza (ciò significa che non siamo più visti, non vediamo più nessuno, e tutti i meccanismi di Following che ci riguardano terminano). L ultimo Behaviour del quale è provvisto il DaveClientAgent è il MovingBehaviour, che sostituisce il PresentationBehaviour dopo che la presentazione ha avuto successo. Il suo semplice compito è quello di invocare periodicamente getcurrentposition() e getcurrentdirection() e fornire tali valori all UpdatePlanner, che decide se è il caso di informare il Server. In caso affermativo viene creato e spedito un messaggio che come contenuto ha la AgentAction ClientUpdate (che contiene la nuova identità dell Agente).

41 4.3 Gli Agenti di Dave FixedAgent E un DaveClientAgent che fornisce sempre lo stesso EarthPoint ogni volta che viene invocato il metodo getcurrentposition(). Per quanto riguarda il metodo getcurrentdirection(), possiamo decidere invece: di fargli restituire sempre la stessa direzione (DO_NOT_ROTATE) di fargli restituire una direzione che varia ogni volta con passo costante in senso orario o antiorario. Questi parametri aggiuntivi (EarthPoint fisso, direzione iniziale, e rotazione) si devono specificare fornendo come argomento al FixedAgent i FixedAgentArguments, che estendono i DaveClientArguments. E disponibile anche la versione FixedAgentWithGUI, che estende FixedAgent e fornisce una interfaccia grafica usufruendo della libreria swing (quindi FixedAgentWithGUI è specifico per PC e pertanto non si può creare su Android) RandomAgent E un DaveClientAgent che restituisce valori random (ma comunque validi) ad ogni chiamata di getcurrentposition() o getcurrentdirection(). Non ha bisogno di parametri aggiuntivi, quindi lo si può creare usando i DaveClientArguments. Come per il FixedAgent, esiste la versione specifica per pc (RandomAgentWithGUI) con interfaccia grafica swing AndroidRealAgent E un DaveClientAgent specifico per Android. In questo Agente i metodi getcurrentposition() e getcurrentdirection() interrogano rispettivamente il provider di localizzazione (GPS o Wi-Fi) e il Giroscopio. Questo Agente si aspetta di trovare come argomento un oggetto di classe RealAgentArguments, la quale estende DaveClientArguments, e impone come vincolo aggiuntivo che il Communicator non sia null e sia instanceof AACommunicator. L AACommunicator (Activity-to-Agent Communicator) estende il Communicator e impone che l oggetto chiamante sia una Activity. Inoltre fornisce ad entrambi un rapido accesso al Giroscopio e al Network Provider (preferibile rispetto al GPS provider che funziona bene solo all aperto), permettendo di leggere i valori forniti da questi strumenti (a questo sarà interessato l Agente) o metterli in pausa al fine di risparmiare energia (a questo sarà interessata la Activity).

42 4.4 UpdatePlanner DaveServerAgent La struttura interna di questo Agente è più semplice rispetto a quella del Client. Infatti non necessita di argomenti in ingresso e ha solo due Behaviour: ClientMessageHandlerBehaviour è sempre in esecuzione o in coda (CyclicBehaviour) e ha il compito di ricevere i messaggi provenienti dai Client, e smistarli nei vari handler a seconda della AgentAction presente nel contenuto. Le possibilità includono ClientSubmission, ClientUpdate, ClientExitRequest, StartFollow e StopFollow. Il meccanismo di Following sarà trattato più avanti, vediamo ora la gestione degli altri tipi di AgentAction: ClientSubmission è la AgentAction usata da un nuovo Client quando si presenta al Server, come abbiamo visto nella sottosezione dedicata al DaveClientAgent. Quando viene ricevuta il Server deve aggiungere nella propria struttura dati (che approfondiremo in seguito) le informazioni riguardanti il nuovo Client, e rispondere con un ServerUpdate indicando gli Agent inizialmente visti da quello nuovo (dopo averli trovati). ClientUpdate viene ricevuto quando uno dei Client ha cambiato in modo significativo (rispetto al proprio UpdatePlanner) il proprio EarthPartialCircle. Il Server deve semplicemente riconoscere il Client (in tempo O(1), in seguito vedremo come) e aggiornare questo dato. ClientExitRequest viene ricevuto quando uno dei Client ha intenzione di terminare la propria esecuzione. Il Server, dopo averlo riconosciuto, deve rimuovere tale Client dalla propria struttura dati. UpdateBehaviour è una procedura che il Server esegue ogni secondo. Per ciascuno dei Client, l obiettivo è aggiornare gli Agenti che questo Client vede, e, se sono cambiati rispetto alla precedente esecuzione di UpdateBehaviour, mandare un messaggio al Client con la lista aggiornata. I cambiamenti sono ovviamente dovuti allo spostamento del Client stesso o allo spostamento di uno o più altri Agenti, che sono entrati (o usciti) dal suo punto di vista. Questa procedura viene fatta in accordo alla QualityOfService che ciascun Client ha richiesto. 4.4 UpdatePlanner L UpdatePlanner (contenuto nel package dave.update) si occupa di stabilire quando un cambiamento nell EarthPartialCircle di un Client (in seguito ad una nuova lettura di posizione e direzione) è significativo (e in quanto tale, il Server deve venirne a conoscenza). I criteri sono i seguenti:

43 4.5 Riduzione del Carico Computazionale Deve essere passato abbastanza tempo (maggiore del parametro UpdatePeriod, che possiamo specificare nel costruttore) dalla precedente lettura. In caso contrario, la lettura viene considerata non significativa. UpdatePeriod, per questo motivo, viene quindi anche utilizzato per temporizzare il MovingBehaviour del Client. 2. La distanza tra i centri dei due EarthPartialCircle (ovvero la differenza di posizione) deve essere superiore di un altro parametro (minimum_delta_position) che possiamo impostare nel costruttore. 3. La differenza di direzione deve essere superiore di un terzo parametro (minimum_delta_direction), anche questo impostabile a nostro piacimento. L UpdatePlanner non si limita a memorizzare i criteri, è anche in grado di memorizzare le letture e fornire le risposte, infatti: Il metodo start(earthpartialcircle) memorizza dentro l Update- Planner l EarthPartialCircle iniziale e il currenttimemillis. Il metodo needtoupdate(earthpartialcircle) analizza l EarthPartialCircle passato come parametro e il currenttimemillis confrontando questi dati con quelli precedentemente memorizzati. Secondo i criteri che abbiamo stabilito, il metodo restituisce una risposta booleana in merito alla significatività del cambiamento. Che il cambiamento sia significativo o meno, i dati precedentemente memorizzati vengono sostituiti da quelli nuovi, in modo tale da essere pronto per la successiva chiamata NeverUpdatePlanner Il NeverUpdatePlanner (contenuto nel package dave.update) è un Update- Planner che risponde sempre di no, ovvero il suo metodo needtoupdate restituisce sempre false. I criteri non vengono quindi utilizzati, e le letture non vengono memorizzate. Può essere utile se usato dai FixedAgent che non ruotano o da Agenti che non vogliono informare il Server dei propri spostamenti, facendogli credere di trovarsi sempre nella posizione iniziale. 4.5 Riduzione del Carico Computazionale Sebbene la struttura interna del DaveServerAgent sia molto semplice, il lavoro che questo Agente deve svolgere, se non si adottano strategie per ridurlo, è molto costoso in termini di operazioni. Infatti ogni volta che UpdateBehaviour è in esecuzione (ogni secondo) dovrebbe controllare per ciascuno degli N Client connessi se vede o meno ciascuno degli N - 1 altri Client, con un

44 4.5 Riduzione del Carico Computazionale 40 costo quadratico. Le semplificazioni che adottiamo per ridurre questo costo sono le seguenti: Alcuni Client possono accontentarsi di ricevere aggiornamenti meno frequentemente. Se un Client è interessato agli update ogni 5 secondi, allora UpdateBehaviour (che viene eseguito ogni secondo) dopo averlo servito 1 volta lo ignorerà per le 4 volte successive. Non è necessario ogni volta ricontrollare tutti gli altri N - 1 Client. Se ad esempio un Agente X è a Milano, e il raggio del suo Earth- PartialCircle è di 1 Km, che bisogno c è di controllare se ora vede l Agente Y che si trovava a Roma quando è stato fatto l ultimo aggiornamento? Al contrario un Agente Z che si trovava a 2 Km da X o un Agente W che si trovava a 500m da X ma alle sue spalle avranno bisogno di essere controllati più spesso. Qui entra in gioco il concetto di RemotenessRatio che è stato introdotto nella sezione dedicata agli EarthPartialCircle. L idea è definire una serie di Regole che associano alla RemotenessRatio una frequenza di aggiornamento. Le Regole saranno utilizzate dal Server per creare dei Livelli nei quali posizionare gli N - 1 altri Agenti. Gli Agenti facenti parti di un Livello vengono controllati tutti insieme (in rispetto alla Regola associata al Livello) ed eventualmente spostati in altri Livelli a seconda della loro variazione di RemotenessRatio. Per quanto riguarda il ClientMessagesHandlerBehaviour, il suo compito prevalente è riconoscere ciascun Client che ha inviato un messaggio per poter accedere alla struttura dati del Server nel punto opportuno. Se il riconoscimento del Client fosse solo tramite AID, il Server dovrebbe confrontarlo uno per uno con tutti gli N AID dei Client connessi, quindi con un costo di N confronti nel caso pessimo. Per ridurre questo costo viene introdotto un numero intero (Cookie) che identifica univocamente ciascun Client. Ogni volta che un nuovo Client X si connette viene posto in fondo alla lista del Server e gli viene associato il Cookie CX, dove CX è il numero di Client precedentemente presenti nella lista (quindi X escluso). Tale Cookie corrisponde esattamente all indice della lista in cui si trovano i dati di quel Client. Ogni volta che X manda un messaggio al Server deve presentare il proprio Cookie CX, in modo tale che l accesso ai suoi dati avvenga in tempo O(1) utilizzando il Cookie come indice nella lista. Che cosa succede quando un Client Y con Cookie CY manda una ClientExitRequest al Server? In questo caso il Client Y viene eliminato dalla lista e tutti i client che avevano Cookies (ovvero posizione all interno della lista) maggiori di CY vengono shiftati di una posizione verso sinistra, mentre tutti i Client che avevano Cookies minori di CY rimangono nella posizione in cui erano (quindi i loro Cookies rimangono funzionanti). Se un client X è stato

45 4.5 Riduzione del Carico Computazionale 41 shiftato il suo cookie CX non è più valido, però i suoi dati si trovano nella lista in una posizione sicuramente minore di CX (in particolare in quella precedente se è stato eliminato solo un Client con cookie < CX dall ultima volta in cui CX ha mandato un messaggio al Server). Tuttavia questo non è un grosso problema, poichè: Non tutti i Cookies perdono di validità Le operazioni di eliminazione sono sicuramente meno frequenti rispetto alle operazioni di accesso e modifica ai propri dati Qualora un Cookie CX diventasse invalido, il riconoscimento del Client X viene fatto tramite il suo AID, andando a ritroso nella lista a partire dalla posizione CX (quindi al più CX confronti vengono fatti). Una volta trovati i dati, il Cookie viene corretto e rimandato al Client, così le successive operazioni torneranno ad essere servite in tempo O(1) LevelAccessRule La classe LevelAccessRule implementa il concetto di Regola che abbiamo introdotto parlando di riduzione del carico di lavoro del Server. E ciascun Client che decide quante e quali Regole creare, a seconda delle proprie esigenze (o meglio di quelle dell applicazione). Per creare una Regola dobbiamo semplicemente specificare una coppia di valori interi: Limite: solo gli Agenti che hanno RemotenessRatio < Limite vengono considerati da questa regola. E possibile fornire anche il valore speciale NO_LIMIT per indicare che la RemotenessRatio può essere qualsiasi. UpdatePeriod: ogni quanti secondi gli Agenti considerati da questa regola vengono controllati per verificare gli eventuali cambiamenti AccessRules Questa classe modella il concetto di insieme di regole. Possiamo aggiungere tutte le LevelAccessRule che vogliamo, in un qualsiasi ordine, e quando siamo soddisfatti, invocare il metodo checkandnormalize() che ordina le regole e controlla che non ci siano regole discordanti, di troppo o mancanti: Le Regole non possono essere zero (viene lanciata una EmptyRulesException). Deve esistere una regola con UpdatePeriod = 1. Non ci possono essere due regole uguali (viene lanciata una EqualRulesException). Due regole sono uguali quando hanno lo stesso Limite o lo stesso UpdatePeriod. Come conseguenza può esistere al più una sola regola con NO_LIMIT.

46 4.5 Riduzione del Carico Computazionale 42 Non ci possono essere due regole discordanti. Se il Limite di R 1 è maggiore del Limite di R 2 (quindi la regola R 1 prende in considerazione Agenti più distanti) allora deve valere che anche l UpdatePeriod di R 1 è maggiore di quello di R 2 (ovvero che la regola R 1 triggera meno frequentemente della regola R 2 ). In caso contrario R 1 e R 2 sono discordanti (e viene lanciata una DiscordantRulesException). Le regole sono quindi ordinate per UpdatePeriod (o equivalentemente per limite, visti i vincoli soprastanti). In questo modo sappiamo che se i > k allora il Limite e l UpdatePeriod di R i sono maggiori rispettivamente del Limite e dell UpdatePeriod di R k. Un Client A risponde alla regola R k del Client B (si parla delle regole ordinate come descritto sopra) se e solo se: 1. la RemotenessRatio di A rispetto a B è minore del limite specificato nella regola R k 2. tra tutte le regole di B che soddisfano il punto precedente, R k è quella con il Limite minore. Se nelle AccessRules di B è presente una regola con NO_LIMIT, allora tutti i Client A diversi da B rispondono a una e una sola delle regole. Nel caso non sia presente, invece, qualora la RemotenessRatio di un client A rispetto a B diventasse maggiore di tutti i Limiti di tutte le Regole, A non sarà mai più considerato da B QualityOfService Con questa classe ciascun Client può indicare al Server le AccessRules di cui necessita, e un ulteriore parametro intero, updatefrequency, che indica ogni quanti secondi il Server deve aggiornare gli Agenti che tale Client vede. Se un Client desidera aggiornamenti ogni N secondi, allora il Server manterrà un contatore inizializzato ad N. UpdateBehaviour viene eseguito nel Server ogni secondo, e decrementa in ciascuna esecuzione tutti i contatori dei Client. Se un contatore arriva a zero, allora UpdateBehaviour deve controllare (seguendo ora le AccessRules) gli Agenti visti dal Client associato a quel contatore, e poi ripristinare il contatore al valore iniziale NoService Se un Client invia NoService (invece di QualityOfService) al Server, significa che non desidera ricevere aggiornamenti di Agenti visti. In questo caso tale Client riceverà solamente un ServerUpdate, quello di risposta alla ClientSubmission, contenente gli Agenti visti inizialmente. Non ricevendo altri aggiornamenti, il Client non saprà se tali Agenti sono usciti dal suo punto di vista, o se ne sono entrati altri.

47 4.6 Esempio di Creazione e Configurazione Client Esempio di Creazione e Configurazione Client new AndroidJade(activity, " ", public void oncontainerready() { AACommunicator communicator = new AACommunicator(activity) { public void onagentlinked() { doresume(); QualityOfService qualityofservice = new QualityOfService( AccessRules.DEFAULT_ACCESS_RULES, 5 );... AndroidRealAgentArguments arguments = new AndroidRealAgentArguments( 3.0, // Raggio 90.0, // TotalAngle new UpdatePlanner(), qualityofservice, communicator ); createnewagent( "Luca", "dave.android.agent.androidrealagent", arguments ); In questo esempio viene creato un Agente di classe AndroidRealAgent, di nome Luca, i cui EarthPartialCircle avranno un raggio di 3 Km e un ampiezza angolare totale di 90 gradi. Luca usa l UpdatePlanner di Default, cioè quello fornito dal costruttore di default di UpdatePlanner, che in particolare ha: Mininum_Delta_Direction = 10, ovvero vengono considerate significative solo le rotazioni di almeno 10 gradi. Mininum_Distance = 0.01, ovvero vengono considerati significativi solo gli spostamenti di almeno 10 metri. Update_Period = 2000, ovvero devono passare 2 secondi tra una lettura dell EarthPartialCircle e la successiva. La QualityOfService specificata da Luca impone che Luca deve essere aggiornato (degli Agenti che vede) dall UpdateBehaviour del Server ogni 5 secondi, con le AccessRules di default, che sono queste:

48 4.7 Struttura Dati del Server 44 public static final AccessRules DEFAULT_ACCESS_RULES = new AccessRules().addRule(new LevelAccessRule(1, 1)).addRule(new LevelAccessRule(20, 2)).addRule(new LevelAccessRule(40, 4)).addRule(new LevelAccessRule(80, 8)).addRule(new LevelAccessRule(100, LevelAccessRule.NO_LIMIT)); Tutto ciò significa: Ogni 5 secondi (5 * 1) vengono controllati gli Agenti che, al momento dell ultimo aggiornamento, distavano al più 3 * 1 = 3 Km da Luca. Ogni 100 secondi (5 * 20) vengono controllati gli Agenti che, al momento dell ultimo aggiornamento, distavano al più 3 * 2 = 6 Km. Ogni 200 secondi (5 * 40) vengono controllati gli Agenti che, al momento dell ultimo aggiornamento, distavano al più 3 * 4 = 12 Km. Ogni 400 secondi (5 * 80) vengono controllati gli Agenti che, al momento dell ultimo aggiornamento, distavano al più 3 * 8 = 24 Km. Gli agenti che, al momento dell ultimo aggiornamento, distavano più di 24 Km da Luca vengono controllati ogni 5 * 100 = 500 secondi. Se eliminassimo l ultima regola, otterremmo che se un Agente in un qualsiasi momento viene a distare più di 24 Km da Luca, allora tale Agente non sarà mai più considerato da Luca, nemmeno se la loro distanza dovesse successivamente ridursi a meno di 24 Km. Infine, viene fornito un AACommunicator per far comunicare Luca con la Activity che l ha creato. In particolare, quando Luca avrà fatto sapere all AACommunicator che la sua creazione ha avuto successo, verrà invocato il metodo doresume() dell AACommunicator, che ha l effetto di iniziare la lettura del giroscopio e del Network Provider. 4.7 Struttura Dati del Server ClientMatrix ClientMatrix è la struttura dati dove il Server contiene tutte le informazioni riguardanti gli Agenti che gli hanno inviato ClientSubmission. E semplicemente una lista di oggetti di tipo ClientRow, che gestiscono le informazioni di un singolo Client. Le operazioni che il Server deve svolgere sulla ClientMatrix sono: Aggiungere una ClientRow ogni volta che riceve una ClientSubmission da parte di un agente B. Per ciascuno dei Client X già presenti nella ClientMatrix deve confrontare l EarthPartialCircle di X con quello di

49 4.7 Struttura Dati del Server 45 B, e viceversa, calcolando così le rispettive RemotenessRatio per poter quindi posizionare nel Level corretto B nei confronti dei vari Client X, e i vari Client X nei confronti di B. In particolare così il Server ha ottenuto gli Agenti che B vede, e li può mandare a B come risposta alla ClientSubmission. Rimuovere una ClientRow ogni volta che riceve una ClientExitRequest da parte di un agente B. Per ciascuno dei Client X rimanenti, deve rimuovere B dal Level di X dove si trovava. Inoltre deve terminare tutte le operazioni di Following da e verso B. Riconoscere un Client attraverso AID o attraverso AID e Cookie, e verificarne l esistenza nella ClientMatrix, restituendo la corrispondente ClientRow. Nel caso venga fornito un Cookie non più valido, deve correggerlo e restituirlo corretto al Client ClientRow ClientRow contiene tutte le informazioni riguardanti un singolo Client B all interno della ClientMatrix. Le informazioni che vengono memorizzate sono: Il descrittore (DaveAgent) di B. L EarthPartialCircle contenuto nel descrittore viene modificato ogni volta che B manda un ClientUpdate. I Levels costruiti e governati dalle AccessRules che B ha richiesto. In particolare l oggetto di classe Levels conterrà tanti oggetti di classe Level pari al numero di regole (size di AccessRules), e assegnerà a ciascun Level una di queste. Un contatore (Counter) che serve all UpdateBehaviour per sapere se B deve essere servito (qualora il Counter dopo essere stato decrementato diventa zero) o ignorato (dopo il decremento rimane positivo) nella esecuzione corrente. Il Counter viene resettato al valore iniziale ogni volta che UpdateBehaviour serve B L UpdatePeriod, quello della QualityOfService che B ha richiesto, che serve per inizializzare e resettare il Counter. Gli Agenti che B vede, ricalcolati ogni volta che UpdateBehaviour controlla i Livelli di B. I Followers di B (descritti più avanti), con la possibilità di aggiungerli, rimuoverli e ottenerne la lista.

50 4.7 Struttura Dati del Server OtherClient OtherClient è una piccola struttura dati di appoggio riferita ad una coppia di Client <A, B> presenti nella ClientMatrix. Il primo Client (A) assume il ruolo di straniero, mentre il secondo Client (B) il ruolo di locale. Dentro questa struttura dati viene memorizzato l ultimo (nel senso l ultimo che è stato calcolato, visto che può cambiare con il tempo) rango assegnato al Client straniero da parte del Client locale. Se A risponde alla regola R k di B, allora il rango di A è k (che corrisponde all indice dell oggetto Level in cui trovare A). Se A non risponde a nessuna delle regole di B, allora il rango assume il valore speciale IGNORED. Inizialmente (quando Other- Client viene costruito) il rango memorizzato dentro OtherClient assume il valore speciale NO_PREVIOUS_RANK. Gli oggetti di tipo OtherClient vengono creati ogni volta che un nuovo Client C si presenta al Server tramite ClientSubmission, in particolare per ogni Client X già presente viene creato un OtherClient per la coppia <C, X> e un altro per la coppia <X, C> Levels I Levels di B sono una lista ordinata di oggetti di tipo Level, ciascuno dei quali è associato ad una delle regole specificate dal Client B con AccessRules (l ordinamento dei Level corrisponde all ordinamento dei LevelAccessRule). I vari Level di B contengono tutti gli OtherClient riferiti alle coppie <X, B> tali che: 1. X è un Agente diverso da B 2. Il rango contenuto nell oggetto OtherClient è diverso da IGNORED Ogni volta che l Agente X (o meglio l oggetto OtherClient riferito alla coppia <X, B>) deve essere posizionato in uno dei Livelli di B (questo accade quando X e B si conoscono oppure quando UpdateBehaviour agisce sul Livello di B in cui si trova attualmente X), bisogna calcolare il rango di X rispetto a B e confrontarlo con quello precedentemente salvato dentro l oggetto OtherClient: Se sono uguali, vuol dire l Agente X non deve essere spostato dal Level in cui si trova. Se il rango precedente era NO_PREVIOUS_RANK, allora X deve essere posizionato nel Level di indice corrispondente al nuovo rango. Se il nuovo rango è IGNORED, allora X deve essere rimosso dal Level in cui si trova (dato dal rango precedente). In questo modo l oggetto OtherClient riferito alla coppia <X, B> non sarà più puntato da nessuno dei Level, e verrà automaticamente eliminato dalla memoria. X non sarà mai più inserito in uno dei Level di B.

51 4.8 Following 47 Altrimenti il rango precedente e quello nuovo sono diversi e non sono i valori speciali sopra elencati. L oggetto OtherClient dovrà essere eliminato dal Level dato dal rango precedente, e inserito nel Level dato dal nuovo rango. Dopo avere compiuto l eventuale spostamento, il rango precedente dentro l oggetto OtherClient viene sostituito con quello nuovo. Ciascun Level ha inoltre un proprio contatore (inizializzato al valore di UpdatePeriod della regola a cui il Livello si riferisce), che viene usato per determinare (con lo stesso funzionamento del Counter di ClientRow) se gli OtherClient presenti nel Livello devono essere analizzati nella corrente esecuzione di UpdateBehaviour oppure no. Ovviamente questo controllo viene fatto per ciascun Livello solo nel caso in cui UpdateBehaviour stia servendo il Client. 4.8 Following E un meccanismo che consente ad un Agente A (il follower ) di ricevere dal Server le notifiche riguardanti gli spostamenti di un Agente B (il followed ). Non ci sono limiti riguardanti il numero di Agenti che si può seguire o il numero di Agenti dal quale si può essere seguiti. Questo meccanismo è del tutto slegato dall aggiornamento degli Agenti che A vede, infatti anche se A sta seguendo B, continuerà a ricevere gli usuali messaggi contenenti la AgentAction ServerUpdate, nei quali potrà essere presente anche B. 1. L Agente A decide di voler seguire l Agente B, quello che deve fare è mandare un messaggio al Server contenente la AgentAction StartFollow, dove può specificare l AID di B. 2. Il Server ricava A come mittente del messaggio, e B all interno della StartFollow contenuta nel messaggio, e fa alcuni controlli (di conoscere sia A che B, che A sia diverso da B, che A non stia già seguendo B). Se tutti i controlli vengono superati, l Agente A viene aggiunto alla lista dei Followers dentro la ClientRow di B. Infine il Server manda un messaggio di risposta ad A comunicandogli l EarthPartialCircle iniziale di B (e il suo AID, visto che A potrebbe stare seguendo più Agenti contemporaneamente) tramite una AgentAction FollowedUpdate. 3. Ogni volta che B manda un ClientUpdate al Server, oltre ad aggiornare l EarthPartialCircle contenuto nella ClientRow di B, il Server deve anche mandare un messaggio (contenente la AgentAction FollowedUpdate) a tutti gli Agenti che fanno parte della lista dei Followers di B (A è uno di questi). 4. Se B decide di mandare una ClientExitRequest al Server, quest ultimo deve mandare un messaggio a tutti i Followers, contenente la Agen-

52 4.9 Visualizzazione Agenti sulle GoogleMaps 48 taction FollowedExit. Dalla ricezione di questo messaggio, A non riceverà più FollowedUpdate riguardanti B (in particolare neanche le ServerUpdate conterranno B, visto che B non c è più). 5. Anche l Agente A può far terminare l operazione di Following, qualora decidesse di inviare a sua volta una ClientExitRequest, oppure la AgentAction StopFollow, che ha l effetto di terminare solamente l invio delle FollowedUpdate riguardanti B senza causare la terminazione di A. 4.9 Visualizzazione Agenti sulle GoogleMaps Le mappe di Google sono uno strumento molto comodo e versatile, poichè: Possiamo visualizzare ciascun luogo con tre modalità diverse: stradale, terreno, oppure ibrida. Possiamo visualizzare ciascun luogo a diversi livelli di zoom (fornendo un parametro tra 1 e 20) E possibile spostare la telecamera in una qualsiasi posizione e con una qualsiasi angolazione (e possiamo animare o meno gli spostamenti) E possibile posizionare marcatori nei punti di interesse, e associare a ciascuno un nome e un colore E possibile gestire tramite handler personalizzati gli eventi touch o drag-and-drop sui marcatori DaveMap è una sovrastruttura della GoogleMap che le consente di interagire con gli Agenti di Dave. Funziona in modo simile a quanto previsto dal Design Pattern Adapter, ovvero i metodi di DaveMap internamente si appoggiano ai metodi della GoogleMap. I Marcatori (Marker) che la GoogleMap è in grado di posizionare (in un punto qualsiasi) e visualizzare su se stessa verranno utilizzati per rappresentare gli Agenti. Anche i Marcatori dovranno avere una opportuna sovrastruttura (DaveMarker), che consentirà loro di contenere più informazioni. In particolare, per ciascun DaveMarker abbiamo bisogno di memorizzare: L AID dell Agente a cui il marcatore si riferisce. In questo modo si stabilisce una corrispondenza biunivoca tra l Agente e il suo DaveMarker. Vogliamo sapere se l Agente a cui questo marcatore si riferisce è quello locale (quello che vive nel dispositivo Android che sta visualizzando la mappa), oppure se è visto e/o seguito da quello locale. Questa informazione sarà utilizzata per scegliere il colore con cui disegnare il marcatore (se non specificato esplicitamente dal programmatore nel

53 4.9 Visualizzazione Agenti sulle GoogleMaps 49 costruttore), e se disegnare o meno l EarthPartialCircle associato all Agente. Un EarthPartialCircle può essere disegnato (con una certa precisione che influenzerà le prestazioni) con una poligonale (data una lista di N+1 punti, la poligonale consiste negli N segmenti ciascuno dei quali ha come estremi due punti consecutivi nella lista). Di seguito un esempio di codice che consente di creare una DaveMap a partire da una GoogleMap: MapFragment m = (MapFragment) getfragmentmanager().findfragmentbyid(r.id.map); GoogleMap g = m.getmap(); g.setmaptype(googlemap.map_type_hybrid); DaveMap davemap = new DaveMap(g) public void onagentselected(davemarker davemarker) { public boolean accepttoviewagent(daveagent daveagent) { return public Float onagentcolorrequested(daveagent daveagent) { Agent a = androidjade.getcommunicator().getagent(); AndroidPirateAgent p = (AndroidPirateAgent) a; TreasureList treasures = p.getgamestorage().gettreasurelist(); ; if (treasures.contains(daveagent.getaid())){ return DaveMarker.getHue(Color.YELLOW); return null; Il codice soprastante fa parte della PirateActivity del gioco DaveTreasureHunt, trattato nel capitolo 5. Le prime due istruzioni consentono di recuperare (tramite identificatore) dal file xml contenente la descrizione della videata della PirateActivity (ovvero pirate.xml) il Fragment contentente la GoogleMap, e estrarre quest ultima. Nel file pirate.xml troviamo infatti: <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.mapfragment" /> Il FragmentManager è così in grado di riconoscere la GoogleMap corretta e restituirla. Dopo aver impostato il tipo di mappa nella linea successiva, notiamo che quando creiamo la DaveMap ci viene chiesto di implementare tre metodi:

54 4.9 Visualizzazione Agenti sulle GoogleMaps 50 onagentselected viene invocato quando l Utente tocca un Marcatore sulla GoogleMap. L argomento del metodo è il DaveMarker che l utente ha toccato. In questo modo possiamo estrarre l Agente a cui il marcatore si riferisce e compiere le azioni appropriate a seconda della sua identità. accepttoviewagent viene invocato quando l Agente che troviamo come argomento è visto dall Agente locale. Dobbiamo restituire true se desideriamo che tale Agente venga visualizzato sulla mappa, o false se vogliamo nasconderlo. Anche qui possiamo fare azioni diverse a seconda dell identità dell Agente stesso. Da notare che gli Agenti che nascondiamo rimangono comunque nella memoria della DaveMap, quindi è possibile decidere di disegnarli in un secondo momento. Gli Agent che possiamo nascondere sono solo quelli visti, infatti questo metodo non viene invocato per l Agenti locale e quelli seguiti. onagentcolorrequested viene invocato quando l Agente che troviamo come argomento ha superato il test dato da accepttoviewagent e sta per essere disegnato. Dobbiamo scegliere il colore da associare a tale Agente. Nell esempio esposto sopra viene controllato che l Agente sia un Tesoro, in tale caso viene colorato in giallo, altrimenti vengono usati i colori di default (blu per quello locale, verde per quelli seguiti, rosso per quelli visti). Le aggiunte apportate alla GoogleMap grazie alla DaveMap riguardano principalmente un maggior supporto ai Marcatori: I DaveMarker rimangono memorizzati in due liste (una per quelli visualizzati sulla mappa, una per quelli nascosti) all interno della Dave- Map stessa. In un qualsiasi momento è possibile usare il metodo refresh() che riunisce le due liste in una sola, e innesca nuovamente accepttoviewagent e onagentcolorrequested su ciascuno dei DaveMarker, per dividerli nuovamente nelle due liste (eventualmente in modo diverso da prima). Ogni volta che un nuovo DaveMarker viene aggiunto alla mappa, prima ancora di invocare i metodi accepttoviewagent e onagentcolor- Requested, viene verificato che non esista già in una delle due liste un altro DaveMarker associato allo stesso Agente. In caso esista viene deciso quale dei due DaveMarker cancellare, così da mantenere la corrispondenza biunivoca tra Agente e DaveMarker. E possibile ottenere uno specifico DaveMarker all interno di una delle due liste con il metodo getmarker(aid). E possibile ottenere anche quello locale, con getmymarker().

55 4.10 DaveReceiver 51 E possibile cancellare i DaveMarker, in modo selettivo (sempre per AID), tutti quelli presenti (con il metodo clear), o solo quelli visti DaveReceiver Il compito di DaveReceiver è ricevere gli Intent che vengono inviati dagli Agenti di classe AndroidRealAgent (o sottoclassi). In particolare ogni volta che riceve un Intent deve ricavarne l azione (tra tutte quelle che il DaveReceiver può gestire), estrarne gli eventuali Extra, per poter così compiere l azione appropriata sulla DaveMap e/o sulla Activity (tipicamente visualizzare delle notifiche) IntentFilter Per definire le azioni che il DaveReceiver è in grado di gestire è stato costruito un IntentFilter (memorizzato all interno del DaveReceiver stesso): IntentFilter intentfilter = new IntentFilter(); intentfilter.addaction(display_my_position); intentfilter.addaction(display_near_agents); intentfilter.addaction(go_to_my_position); intentfilter.addaction(agent_dead); intentfilter.addaction(followed_add); intentfilter.addaction(followed_changed); intentfilter.addaction(followed_removed); intentfilter.addaction(presentated); intentfilter.addaction(server_exit); Questo intentfilter deve essere utilizzato per registrare il DaveReceiver alla Activity (una Activity può avere uno o più BroadcastReceiver che catturano gli Intent diretti a quest ultima). Pertanto, dopo aver creato un oggetto (this.receiver) di classe DaveReceiver nel metodo onstart della Activity, dovremo anche effettuare l operazione di registrazione del corrispondente IntentFilter in questo protected void onresume() { super.onresume();... super.registerreceiver(this.receiver, this.receiver.getintentfilter()); ; La speculare operazione di de-registrazione serve per consumare meno batteria quando non ci si aspetta di ricevere Intent su quella public void onpause(){ super.onpause();... super.unregisterreceiver(this.receiver);

56 4.10 DaveReceiver Azioni compiute Visto che abbiamo utilizzato l IntentFilter sappiamo che tutti gli Intent catturati dal DaveReceiver (viene invocato il metodo onreceive quando ne arriva uno nuovo) hanno come action una di quelle sopra elencate. Gli Extra sono invece un insieme di coppie <chiave, valore> che l Intent può portare con sè. A seconda della action dell Intent sappiamo se aspettarci degli Extra oppure no. Di seguito elenco le operazioni compiute a seconda della action dell Intent. Tali operazioni sono contenute in metodi handler (ad esempio followedadd). Al termine di ciascuno di questi metodi (ad esempio followedadd), viene invocato un ulteriore metodo astratto (ad esempio on- FollowedAdd), del quale possiamo fornire una implementazione per compiere azioni aggiuntive. DISPLAY_MY_POSITION: L AndroidRealAgent avvisa la Activity che ha calcolato un (nuovo) EarthPartialCircle riferito a se stesso. Il DaveReceiver accede all Agente (tramite il suo puntatore), recupera il nuovo valore dell EarthPartialCircle, e fà si che la DaveMap aggiorni il DaveMarker locale. DISPLAY_NEAR_AGENTS: L AndroidRealAgent avvisa la Activity della ricezione di un ServerUpdate. Come nel caso precedente, il DaveReceiver accede all Agente per recuperare le informazioni sugli Agenti visti. Dopodichè tutti i DaveMarker che si riferivano ad Agenti visti vengono cancellati dalla DaveMap e sostituiti con quelli nuovi. GO_TO_MY_POSITION: L AndroidRealAgent chiede che la Dave- Map della Activity venga centrata nella propria posizione. Per fare questo il DaveReceiver accede all Agente per ricavare l EarthVector dal suo EarthPartialCircle corrente. L EarthVector viene utilizzato per calcolare lo zoom (lunghezza dell EarthVector), il bearing (direzione dell EarthVector) e la posizione (firstpoint dell EarthVector) della telecamera della GoogleMap. FOLLOWED_ADD: L AndroidRealAgent avvisa la Activity del fatto che ha richiesto al Server di seguire un Agente. Non vengono compiute operazioni, visto che non abbiamo ancora la posizione dell Agente seguito. Tuttavia viene ricavato dagli Extra il nome dell Agente seguito, in modo tale che sovrascrivendo onfollowedadd potremmo eventualmente visualizzare una notifica a schermo. FOLLOWED_CHANGED: L AndroidRealAgent ci avvisa di aver ricevuto una FollowedUpdate dal Server. Dopo aver ricavato (dagli Extra) il nome dell Agente a cui si riferisce l aggiornamento, il Dave- Receiver deve sostituire nella DaveMap il DaveMarker relativo a tale Agente.

57 4.10 DaveReceiver 53 FOLLOWED_REMOVED: L AndroidRealAgent ci avvisa di aver ricevuto una FollowedExit dal Server. Dopo aver ricavato (dagli Extra) il nome dell Agente del quale la FollowedExit si riferisce, il DaveReceiver deve rimuoverlo dalla DaveMap. Dopo averlo rimosso controlla se l Agente (non più seguito) è però visto da quello locale, in tal caso deve ri-aggiungerlo (verrà colorato diversamente). I metodi che gestiscono tutte le altre action definite nell intentfilter invocano semplicemente il metodo astratto corrispondente. Con AGENT_DEAD l AndroidRealAgent comunica all Activity che sta per terminare la sua esecuzione (ad esempio in seguito ad una eccezione), quindi potremmo decidere di far terminare anche la Activity. Con PRESENTATED l AndroidRealAgent comunica alla Activity che ha mandato il messaggio di presentazione al Server. Infine con SERVER_EXIT l AndroidRealAgent comunica alla Activity di avere ricevuto l ononimo messaggio dal Server.

58 Capitolo 5 Esempio Applicazione Dave Questo capitolo descrive il primo gioco tratto dalla libreria Dave, ovvero DaveTreasureHunt. Si tratta di una caccia al tesoro, nella quale gli Esploratori devono trovare tutti gli oggetti nascosti dal Pirata in una certa area di gioco, prima dello scadere del tempo fissato dal Pirata stesso. Il gioco può essere fruito in diverse modalità a seconda del numero dei giocatori: cooperativo: una squadra di persone collabora per trovare i tesori e sconfiggere così il Pirata (uno solo di questi è l Esploratore, e ha il gioco attivo sul telefono, gli altri lo aiutano) competitivo: gli Esploratori sono persone che cercano individualmente i tesori, cercando di trovarli prima degli altri (e prima dello scadere del tempo) competitivo a squadre: come competitivo, ma ciascun Esploratore ha i propri collaboratori. Verranno in seguito descritte le regole e lo svolgimento del gioco, e come il gioco stesso è stato costruito. 5.1 Le Fasi del gioco Fase di Posizionamento dei Tesori Il giocatore che assumerà il ruolo di Pirata avvierà l Applicazione Dave Treasure Hunt Pirate sul proprio dispositivo Android, immettendo il proprio nome e l indirizzo Ip (pubblico) del PC dove il Main Container di Jade è in esecuzione. A questo punto, mantenendo la connessione 3G attiva, si muoverà nella zona prestabilita per il gioco (una città, un bosco...). Ogni volta che giunge in una posizione nella quale desidera nascondere un tesoro, deve:

59 5.1 Le Fasi del gioco Scrivere su un foglio di carta o un cartoncino un codice alfanumerico da associare all oggetto che si vuole nascondere, e incollarlo all oggetto stesso. 2. Collocare l oggetto nella posizione nascosta scelta. 3. Posizionandosi il più vicino possibile all oggetto appena nascosto, toccare l icona del GamePad nella ActionBar dell applicazione, e scegliere l opzione Place Treasure, fornendo i dati richiesti, ovvero: nome del tesoro (univoco all interno del Container Jade), codice di sblocco (il codice alfanumerico che abbiamo associato all oggetto), e indizio per trovarlo. Lo scopo dell indizio è quello di far giungere gli Esploratori in prossimità di questo tesoro (e non nel punto esatto nel quale è nascosto), e può essere (a discrezione del Pirata, per rendere più o meno difficile il gioco) scritto in forma enigmatica, può essere un indovinello, può essere correlato al ritrovamento di tesori precedenti Una volta inserite queste 3 informazioni, il Pirata può allontanarsi dal tesoro, e verificare che nella mappa è comparso un marcatore di colore giallo nella posizione in cui l ha collocato. Il Pirata procede così fino a mettere un numero adeguato di Tesori sulla mappa. Quando è soddisfatto, torna alla Base, cioè dove si trovano gli altri giocatori, e li avvisa verbalmente che il gioco sta per iniziare. A questo punto il Pirata deve scegliere l opzione Start Game, e impostare la data e l ora di fine del gioco (se nessuno trova tutti i tesori entro quel limite, il Pirata vince) Fase di Ricerca dei Tesori Gli Esploratori che concorrono (o i capitani delle loro squadra/e) avviano l applicazione Dave Treasure Hunt Explorer sul proprio dispositivo Android, e immettono il loro nome (o quello della squadra) e lo stesso indirizzo Ip e Porta immessi precedentemente dal Pirata. A questo punto possono toccare l icona del GamePad, che ha l effetto di ricercare il Pirata. Se il Pirata non ha ancora fatto Start Game, questa operazione fallirà, e verranno fatti nuovi tentativi periodicamente. Non appena il Pirata farà Start Game, l operazione avrà successo, e l Esploratore entrerà nel gioco. Gli Esploratori possono entrare nel gioco in momenti arbitrari, purchè nessuno degli altri Esploratori abbia già vinto e il tempo limite non sia già stato superato (ovviamente arrivando in ritardo si è comunque svantaggiati). Quando un Esploratore è in partita ha a disposizione la lista dei Tesori nascosti dal pirata (la trova nel menu accessibile toccando l icona del GamePad), e per ciascuno può accedere all indizio che gli consente di avvicinarsi ad esso. Una volta giunto in prossimità del tesoro (ovvero nel luogo in cui l indizio porta, se interpretato correttamente), l Esploratore dovrebbe vedere il marcatore

60 5.2 Gli Agenti di DaveTreasureHunt 56 giallo del tesoro sulla mappa della propria applicazione. Una volta giunto sul posto indicato dal marcatore, l Esploratore cerca il tesoro guardando nei possibili nascondigli locali. Quando l avrà trovato, l Esploratore dovrà leggere il codice di sblocco sul tesoro stesso, e selezionare l opzione UNBLOCK dal menu contestuale del tesoro. Se il codice inserito è quello corretto, arriverà una notifica di successo, e il tesoro stesso scomparirà dalla mappa. Nel caso il gioco sia cooperativo, il tesoro trovato può essere raccolto e portato con sè nelle successive ricerche, in caso invece che ci siano altri Esploratori (o altre Squadre), il tesoro va rimesso esattamente dove lo si ha trovato, nascosto nello stesso modo (è il Pirata che alla fine del gioco raccoglie tutti i tesori e controlla che nessuno abbia barato) Fine del Gioco Il gioco può terminare per uno dei seguenti motivi: Il Pirata annulla il gioco dalla propria applicazione. Gli esploratori possono attendere la creazione di una nuova partita Il tempo limite fissato all inizio del gioco viene superato, in questo caso il Pirata vince. Gli esploratori possono comunque continuare le proprie ricerche fino a quando il Pirata non annulla il gioco. Uno degli Esploratori ha trovato tutti i tesori nascosti dal Pirata. In questo caso il Pirata e tutti gli altri Esploratori perdono. Gli Esploratori che hanno perso possono comunque continuare le proprie ricerche, fino a quando il Pirata non annulla il gioco. Il fatto che un Esploratore, o tutti quelli presenti, decidano di abbandonare il gioco, non comporta il termine dello stesso. Infatti finchè il tempo limite non viene superato, altri Esploratori possono entrare in partita. 5.2 Gli Agenti di DaveTreasureHunt TreasureAgent Questo Agente rappresenta 1 singolo Tesoro di quelli nascosti dal Pirata, ed è un FixedAgent, visto che il Tesoro rimane fermo nella posizione in cui era il Pirata quando l ha creato, per tutta la durata del gioco. Si aspetta di ricevere come arguments[0] un oggetto che sia instanceof TreasureAgentArguments, nel quale vengono specificati, tra le altre cose, l indizio e l unblock code associati al Tesoro, e l AID del Pirata. La sua struttura interna è molto semplice, visto che consiste in un unico Behaviour che ha il compito di ricevere e gestire messaggi contenenti una di queste AgentAction:

61 5.2 Gli Agenti di DaveTreasureHunt 57 HintRequest: Uno degli Esploratori ha richiesto l indizio associato al Tesoro. La risposta viene fornita al mittente tramite la AgentAction HintResponse. Unblock: Uno degli Esploratori ha inviato un codice di sblocco. Tale codice deve essere confrontato con quello esatto. Il TreasureAgent deve mandare una AgentAction UnblockDone al Pirata in caso di successo, oppure una UnblockFailed all Esploratore in caso di fallimento. GameCanceled: il Pirata ha deciso di annullare il gioco (questo può succedere sia prima dell inizio, sia durante il gioco, sia dopo la fine dello stesso), comportando il dodelete() di tutti i Tesori ExplorerAgent Questo Agente ha una struttura più complessa rispetto al TreasureAgent, poichè deve interagire sia con il Pirata, sia con i Tesori, sia con la Activity (e quindi con l Utente Android Stesso). Non ha bisogno di argomenti in ingresso aggiuntivi, vengono utilizzati quelli della superclasse (estende AndroidRealAgent). Di seguito entro nel merito di ciascuna di queste interazioni: L ExplorerAgent possiede alcuni metodi pubblici (startgame, unblock, askhint e askremainingtime) che la Activity può invocare e rendere disponibili all Utente Android attraverso la propria interfaccia grafica (in particolare sono tutte le azioni che si possono compiere dal menu identificato dall icona GamePad e dai suoi sottomenu). Per quanto riguarda la comunicazione nel senso opposto, l Agente può visualizzare o cambiare informazioni sull interfaccia grafica mandando all Activity degli Intent con un determinato tipo e i corrispondenti Extra. L ExplorerAgent conosce l AID di tutti i tesori che deve cercare (la lista dei tesori è fornita dal Pirata). Ogni volta che la Activity invoca askhint(aid), questo Agente manda un messaggio al tesoro corrispondente, contenente la AgentAction HintRequest. I messaggi in arrivo (dai Tesori o dal Pirata) vengono catturati e gestiti, come per gli altri Agenti finora visti, tramite un apposito Behaviour (quindi in particolare viene catturato il messaggio contenente la HintResponse). L altro tipo di interazione con i Tesori è tentare di sbloccarli mandando una Unblock, in questo caso l ExplorerAgent non si aspetta una risposta da parte del Tesoro (a meno che lo sbloccaggio fallisca), ma dal Pirata. Quando la Activity invoca il metodo startgame, l ExplorerAgent aggiunge a se stesso un Behaviour (PirateFinderBehaviour), che ha lo scopo di effettuare una ricerca periodica di un Agente che fornisca il

62 5.2 Gli Agenti di DaveTreasureHunt 58 servizio di Pirata e che abbia già avviato la partita (tutti i tesori siano già stati collocati, e il tempo limite sia già stato impostato). Il Behaviour terminerà la propria esecuzione quando la ricerca avrà successo, dopo aver mandato una JoinGameRequest al Pirata, così da entrare nella partita e ricevere dal Pirata la lista dei tesori da cercare (JoinGameResponse). L ExplorerAgent può interagire direttamente con il Pirata chiedendogli il tempo mancante alla fine del gioco (Time- Request), che viene mantenuto e restituito (TimeResponse) dal Pirata, per evitare eventuali differenze tra gli orologi dei vari ExplorerAgent. Gli ExplorerAgent possono ricevere dal Pirata messaggi relativi ai loro successi nello sbloccaggio dei Tesori, e un ulteriore messaggio alla fine della partita, il cui contenuto dipende dall esito della stessa (GameWin, GameLost, GameCanceled) PirateAgent Questo Agente svolge sia il ruolo di Pirata (nasconde i tesori), sia il ruolo di Server (accoglie e mantiene informazioni dei vari ExplorerAgent durante la partita). Il Servizio che questo Agente offre, PirateService, viene registrato al DF per permettere ai vari ExplorerAgent di trovarlo. Di questo Agente è stata fatta sia una versione per Android, sia per PC. Siccome Java non permette l ereditarietà multipla (AndroidPirateAgent estende già AndroidRealAgent, quindi non posso costruire un altra classe base con le operazioni comuni), il codice di questi due Agenti (Pirata per PC e Pirata per Android) si riduce ad un copia-incolla. Per ridurre il problema della doppia manutenzione, alcune parti imporanti, tra cui GameBehaviour (il Behaviour principale di AndroidPirateAgent e PcPirateAgent) sono stati isolati in classi a sè stanti. GameBehaviour riceve i messaggi da parte degli Explorer e dei Treasure e li gestisce in modo appropriato: JoinGameRequest: è inviato da un Explorer, quando vuole unirsi alla partita. Viene controllato che realmente sia un Explorer (e non un Treasure), che non stia già partecipando alla partita, e che quest ultima sia già iniziata ma non ancora finita. Se uno di questi controlli fallisce, viene mandata una JoinGameRefuse al mittente del messaggio. Altrimenti la struttura dati del Pirata (GameStorage) viene aggiornata con i dati del nuovo Explorer, e viene risposto all Explorer con una Join- GameResponse, nella quale è presente la lista dei tesori (che il Pirata conserva all interno del GameStorage). UnblockDone: viene inviato da un Treasure quando un Explorer è riuscito a sbloccarlo. L AID del Tesoro è il mittente del messaggio, mentre l AID dell Explorer è contenuto all interno dell UnblockDone. Anche in questo caso vengono fatti alcuni controlli di validità, che se non superati fanno sì che il messaggio venga ignorato. Il GameStorage viene

63 5.3 GameStorage 59 aggiornato (in seguito vedremo come), e l Explorer viene avvisato con un UnblockConfirm del successo dell operazione. Inoltre se quel tesoro era l ultimo che mancava a tale Explorer (ovvero con quello li ha sbloccati tutti), allora è il vincitore. In questo caso il Pirata manda un GameWin a costui, e un GameLost a tutti gli altri Explorer. Anche il Pirata stesso ha perso in questo caso, quindi deve mandare un Intent appropriato alla propria Activity. TimeRequest: uno degli Explorer ha richiesto il tempo rimanente alla fine del gioco. Viene calcolata la differenza tra il tempo limite del gioco e il currenttimemillis, e inclusa in un messaggio TimeResponse, spedito come risposta al mittente. ExplorerExit: uno degli Explorer vuole abbandonare il gioco. Tale Explorer e tutti i dati riferiti a quest ultimo vengono rimossi dal Game- Storage. L altro Behaviour di cui dispone il Pirata è il TimerBehaviour, che viene innescato solo una volta, al raggiungimento del tempo limite fissato all inizio del gioco. Il suo compito è sancire la vittoria del Pirata, ovvero mandare un GameLost a tutti gli Explorer, e un Intent alla activity del Pirata così da visualizzare la notifica della propria vittoria. 5.3 GameStorage Questa struttura dati è mantenuta dal Pirata, e contiene tutte le informazioni relative: allo stato del gioco, ovvero se è iniziato e/o è finito (informazioni booleane), qual è il tempo limite (in millisecondi), e se è finito chi è l eventuale vincitore (l Explorer che ha trovato tutti i tesori). Come informazione aggiuntiva abbiamo il tempo mancante alla fine della partita, ricavabile dal tempo limite e da quello corrente. Quando GameStorage viene creato il gioco non è iniziato e neanche finito. Per iniziare il gioco si deve invocare il metodo startgame(long endtime), che imposta gamestarted a true dopo aver controllato che non lo era già, e che l endtime fornito sia nel futuro. Per terminare il gioco si deve invocare stopgame(aid winneraid), dove si può fornire l AID dell Explorer che ha trovato tutti i tesori, oppure null per indicare che è il Pirata ad aver vinto. Lo stesso oggetto GameStorage si può riutilizzare per un altra partita, usufruendo del metodo reset() che ripristina l oggetto così com era dopo essere stato costruito. ai tesori, ovvero viene mantenuta la lista degli AID dei TreasureAgent che il Pirata ha creato. Con questa lista possiamo:

64 5.4 Screenshot del Gioco 60 aggiungere nuovi tesori (nella prima fase del gioco) copiarla dentro un ACLMessage e spedirla agli Explorer (nella seconda fase del gioco) spedire GameCanceled ai TreasureAgent stabilire se un determinato AID corrisponde ad uno dei Tesori oppure no, con il metodo istreasure(aid) usare il puntatore alla lista all interno di ExplorerMatrix, per mantenere i punteggi. agli esploratori, all interno di una ulteriore struttura dati (ExplorerMatrix) contenuta dentro GameStorage stesso. GameStorage può interrogare ExplorerMatrix per sapere se un determinato AID corrisponde ad uno degli Explorer che stanno attualmente partecipando alla partita, con il metodo isplayer(aid) ExplorerMatrix L ExplorerMatrix ha una struttura molto simile alla ClientMatrix, ovvero possiede un oggetto di classe ExplorerRecord per ciascuno dei partecipanti alla partita. Questi ExplorerRecord possono essere aggiunti, rimossi o selezionati dalla lista (con i relativi metodi di ExplorerMatrix), rispettivamente quando un Explorer entra nel gioco, esce dal gioco o trova un Tesoro ExplorerRecord In questa classe vengono mantenute tutte le informazioni riguardanti un singolo Explorer B che sta partecipando al gioco, ovvero il suo AID, e i punteggi (incapsulati in un oggetto di classe Scores) ottenuti durante la partita stessa. Dentro Scores viene memorizzata una informazione booleana trovato per ciascuno dei Tesori nascosti dal Pirata, in questo modo è possibile: verificare se B ha trovato tutti i tesori (ovvero se tutti i flag sono true). verificare, dato un tesoro T, se B ha già trovato T oppure no. gestire l operazione B ora ha trovato T, impostando a true l opportuno flag trovato. 5.4 Screenshot del Gioco Nelle pagine successive verranno esposte alcune delle schemate facenti parte delle applicazioni Pirate ed Explorer che costituiscono il gioco.

65 5.4 Screenshot del Gioco 61 (a) Dati per Creazione Agente. (b) Schermata di Attesa Iniziale. (c) Azioni Pirata. (d) Inserimento Nome del Nuovo Tesoro. Figura 5.1: Alcuni Screenshot della Applicazione Pirate

66 5.4 Screenshot del Gioco 62 (a) Indizio per trovare il Tesoro. (b) Tesoro Posizionato Correttamente. (c) Inserimento Data Fine Gioco. (d) Inserimento Ora Fine Gioco. Figura 5.2: Alcuni Screenshot della Applicazione Pirate

67 5.4 Screenshot del Gioco 63 (a) Messaggio di Inizio Ricerca Pirata. (b) Messaggio di Benvenuto in Partita. (c) Azioni Esploratore. (d) Menu Tesori. Figura 5.3: Alcuni Screenshot della Applicazione Explorer

NOTE OPERATIVE. Prodotto Inaz Download Manager. Release 1.3.0

NOTE OPERATIVE. Prodotto Inaz Download Manager. Release 1.3.0 Prodotto Inaz Download Manager Release 1.3.0 Tipo release COMPLETA RIEPILOGO ARGOMENTI 1. Introduzione... 2 2. Architettura... 3 3. Configurazione... 4 3.1 Parametri di connessione a Internet... 4 3.2

Dettagli

Tale attività non è descritta in questa dispensa

Tale attività non è descritta in questa dispensa Fondamenti di informatica Oggetti e Java ottobre 2014 1 Nota preliminare L installazione e l uso di Eclipse richiede di aver preliminarmente installato Java SE SDK Tale attività non è descritta in questa

Dettagli

Registratori di Cassa

Registratori di Cassa modulo Registratori di Cassa Interfacciamento con Registratore di Cassa RCH Nucleo@light GDO BREVE GUIDA ( su logiche di funzionamento e modalità d uso ) www.impresa24.ilsole24ore.com 1 Sommario Introduzione...

Dettagli

Direzione Centrale per le Politiche dell Immigrazione e dell Asilo

Direzione Centrale per le Politiche dell Immigrazione e dell Asilo Direzione Centrale per le Politiche dell Immigrazione e dell Asilo Sistema inoltro telematico domande di nulla osta, ricongiungimento e conversioni Manuale utente Versione 2 Data creazione 02/11/2007 12.14.00

Dettagli

La geolocalizzazione

La geolocalizzazione La geolocalizzazione La maggior parte dei dispositivi mobili di ultima generazione è dotata di un antenna GPS che permette di conoscere, in breve tempo e con la precisione di qualche metro, la propria

Dettagli

Modulo 4: Ereditarietà, interfacce e clonazione

Modulo 4: Ereditarietà, interfacce e clonazione Modulo 4: Ereditarietà, interfacce e clonazione Argomenti Trattati: Classi, Superclassi e Sottoclassi Ereditarietà Ereditarietà ed Attributi Privati Override super Ereditarietà e Costruttori Polimorfismo

Dettagli

BMSO1001. Virtual Configurator. Istruzioni d uso 02/10-01 PC

BMSO1001. Virtual Configurator. Istruzioni d uso 02/10-01 PC BMSO1001 Virtual Configurator Istruzioni d uso 02/10-01 PC 2 Virtual Configurator Istruzioni d uso Indice 1. Requisiti Hardware e Software 4 1.1 Requisiti Hardware 4 1.2 Requisiti Software 4 2. Concetti

Dettagli

COMUNICAZIONE UTENTI SISTEMI-PROFIS INSTALLAZIONE GE.RI.CO. 2015 e PARAMETRI2015

COMUNICAZIONE UTENTI SISTEMI-PROFIS INSTALLAZIONE GE.RI.CO. 2015 e PARAMETRI2015 COMUNICAZIONE UTENTI SISTEMI-PROFIS INSTALLAZIONE GE.RI.CO. 2015 e PARAMETRI2015 Vicenza, 3 giugno 2015 Gentile cliente, si ricorda che a partire dall aggiornamento PROFIS 2011.1 è stato automatizzato

Dettagli

MANUALE D'USO DEL PROGRAMMA IMMOBIPHONE

MANUALE D'USO DEL PROGRAMMA IMMOBIPHONE 1/6 MANUALE D'USO DEL PROGRAMMA IMMOBIPHONE Per prima cosa si ringrazia per aver scelto ImmobiPhone e per aver dato fiducia al suo autore. Il presente documento istruisce l'utilizzatore sull'uso del programma

Dettagli

Invio SMS. DM Board ICS Invio SMS

Invio SMS. DM Board ICS Invio SMS Invio SMS In questo programma proveremo ad inviare un SMS ad ogni pressione di uno dei 2 tasti della DM Board ICS. Per prima cosa creiamo un nuovo progetto premendo sul pulsante (Create new project): dove

Dettagli

Gestione Risorse Umane Web

Gestione Risorse Umane Web La gestione delle risorse umane Gestione Risorse Umane Web Generazione attestati di partecipazione ai corsi di formazione (Versione V03) Premessa... 2 Configurazione del sistema... 3 Estrattore dati...

Dettagli

Guida alla registrazione on-line di un DataLogger

Guida alla registrazione on-line di un DataLogger NovaProject s.r.l. Guida alla registrazione on-line di un DataLogger Revisione 3.0 3/08/2010 Partita IVA / Codice Fiscale: 03034090542 pag. 1 di 17 Contenuti Il presente documento è una guida all accesso

Dettagli

Regione Toscana. ARPA Fonte Dati. Manuale Amministratore. L. Folchi (TAI) Redatto da

Regione Toscana. ARPA Fonte Dati. Manuale Amministratore. L. Folchi (TAI) Redatto da ARPA Fonte Dati Regione Toscana Redatto da L. Folchi (TAI) Rivisto da Approvato da Versione 1.0 Data emissione 06/08/13 Stato DRAFT 1 Versione Data Descrizione 1,0 06/08/13 Versione Iniziale 2 Sommario

Dettagli

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise Manuale Amministratore Legalmail Enterprise Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise Pagina 2 di 16 Manuale Amministratore Legalmail Enterprise Introduzione a Legalmail Enterprise...3

Dettagli

La VPN con il FRITZ!Box Parte II. La VPN con il FRITZ!Box Parte II

La VPN con il FRITZ!Box Parte II. La VPN con il FRITZ!Box Parte II La VPN con il FRITZ!Box Parte II 1 Introduzione In questa mini-guida mostreremo com è possibile creare un collegamento su Internet tramite VPN(Virtual Private Network) tra il FRITZ!Box di casa o dell ufficio

Dettagli

Il calendario di Windows Vista

Il calendario di Windows Vista Il calendario di Windows Vista Una delle novità introdotte in Windows Vista è il Calendario di Windows, un programma utilissimo per la gestione degli appuntamenti, delle ricorrenze e delle attività lavorative

Dettagli

LA GESTIONE DELLE VISITE CLIENTI VIA WEB

LA GESTIONE DELLE VISITE CLIENTI VIA WEB LA GESTIONE DELLE VISITE CLIENTI VIA WEB L applicazione realizzata ha lo scopo di consentire agli agenti l inserimento via web dei dati relativi alle visite effettuate alla clientela. I requisiti informatici

Dettagli

Airone Gestione Rifiuti Funzioni di Esportazione e Importazione

Airone Gestione Rifiuti Funzioni di Esportazione e Importazione Airone Gestione Rifiuti Funzioni di Esportazione e Importazione Airone Funzioni di Esportazione Importazione 1 Indice AIRONE GESTIONE RIFIUTI... 1 FUNZIONI DI ESPORTAZIONE E IMPORTAZIONE... 1 INDICE...

Dettagli

PRODUZIONE PAGELLE IN FORMATO PDF

PRODUZIONE PAGELLE IN FORMATO PDF Requisiti minimi: PRODUZIONE, FIRMA E PUBBLICAZIONE DELLA PAGELLA ELETTRONICA CON ALUNNI WINDOWS PRODUZIONE PAGELLE IN FORMATO PDF Argo Alunni Windows aggiornato alla versione più recente. Adobe PDF CREATOR,

Dettagli

Tecniche di progettazione e sviluppo di applicazioni mobile

Tecniche di progettazione e sviluppo di applicazioni mobile Slide del corso FSE Tecniche di progettazione e sviluppo di applicazioni mobile svolto presso AREA Science Park Padriciano - Trieste - Italy diegozabot@yahoo.it Android Introduzione diegozabot@yahoo.it

Dettagli

L ambiente di sviluppo Android Studio

L ambiente di sviluppo Android Studio L ambiente di sviluppo Android Studio Android Studio è un ambiente di sviluppo integrato (IDE, Integrated Development Environment) per la programmazione di app con Android. È un alternativa all utilizzo

Dettagli

GUIDA UTENTE PRIMA NOTA SEMPLICE

GUIDA UTENTE PRIMA NOTA SEMPLICE GUIDA UTENTE PRIMA NOTA SEMPLICE (Vers. 2.0.0) Installazione... 2 Prima esecuzione... 5 Login... 6 Funzionalità... 7 Prima Nota... 8 Registrazione nuovo movimento... 10 Associazione di file all operazione...

Dettagli

filrbox Guida all uso dell interfaccia WEB Pag. 1 di 44

filrbox Guida all uso dell interfaccia WEB Pag. 1 di 44 filrbox Guida all uso dell interfaccia WEB Pag. 1 di 44 Sommario Introduzione... 4 Caratteristiche del filrbox... 5 La barra principale del filrbox... 7 Elenco degli utenti... 8 Il profilo... 9 Le novità...

Dettagli

11/02/2015 MANUALE DI INSTALLAZIONE DELL APPLICAZIONE DESKTOP TELEMATICO VERSIONE 1.0

11/02/2015 MANUALE DI INSTALLAZIONE DELL APPLICAZIONE DESKTOP TELEMATICO VERSIONE 1.0 11/02/2015 MANUALE DI INSTALLAZIONE DELL APPLICAZIONE DESKTOP TELEMATICO VERSIONE 1.0 PAG. 2 DI 38 INDICE 1. PREMESSA 3 2. SCARICO DEL SOFTWARE 4 2.1 AMBIENTE WINDOWS 5 2.2 AMBIENTE MACINTOSH 6 2.3 AMBIENTE

Dettagli

Integrazione InfiniteCRM - MailUp

Integrazione InfiniteCRM - MailUp Integrazione InfiniteCRM - MailUp La funzionalità della gestione delle campagne marketing di icrm è stata arricchita con la spedizione di email attraverso l integrazione con la piattaforma MailUp. Creando

Dettagli

Manuale Servizio NEWSLETTER

Manuale Servizio NEWSLETTER Manuale Servizio NEWSLETTER Manuale Utente Newsletter MMU-05 REDAZIONE Revisione Redatto da Funzione Data Approvato da Funzione Data 00 Silvia Governatori Analista funzionale 28/01/2011 Lorenzo Bonelli

Dettagli

Libero Emergency PC. Sommario

Libero Emergency PC. Sommario Emergenza PC (Garantisce le funzionalità di base delle operazioni di prestito e restituzione in caso di problemi tecnici sulla linea o di collegamento con il server) Sommario 1. Emergency PC...2 2. Iniziare

Dettagli

NAVIGAORA HOTSPOT. Manuale utente per la configurazione

NAVIGAORA HOTSPOT. Manuale utente per la configurazione NAVIGAORA HOTSPOT Manuale utente per la configurazione NAVIGAORA Hotspot è l innovativo servizio che offre ai suoi clienti accesso ad Internet gratuito, in modo semplice e veloce, grazie al collegamento

Dettagli

Banca dati Professioniste in rete per le P.A. Guida all uso per le Professioniste

Banca dati Professioniste in rete per le P.A. Guida all uso per le Professioniste Banca dati Professioniste in rete per le P.A. Guida all uso per le Professioniste versione 2.1 24/09/2015 aggiornamenti: 23-set-2015; 24-set-2015 Autore: Francesco Brunetta (http://www.francescobrunetta.it/)

Dettagli

L amministratore di dominio

L amministratore di dominio L amministratore di dominio Netbuilder consente ai suoi clienti di gestire autonomamente le caselle del proprio dominio nel rispetto dei vincoli contrattuali. Ciò è reso possibile dall esistenza di un

Dettagli

GUIDA UTENTE MONEY TRANSFER MANAGER

GUIDA UTENTE MONEY TRANSFER MANAGER GUIDA UTENTE MONEY TRANSFER MANAGER (vers. 1.0.2) GUIDA UTENTE MONEY TRANSFER MANAGER (vers. 1.0.2)... 1 Installazione... 2 Prima esecuzione... 5 Login... 7 Funzionalità... 8 Anagrafica... 9 Registrazione

Dettagli

Capitolo 4 Pianificazione e Sviluppo di Web Part

Capitolo 4 Pianificazione e Sviluppo di Web Part Capitolo 4 Pianificazione e Sviluppo di Web Part Questo capitolo mostra come usare Microsoft Office XP Developer per personalizzare Microsoft SharePoint Portal Server 2001. Spiega come creare, aggiungere,

Dettagli

ATOLLO BACKUP GUIDA INSTALLAZIONE E CONFIGURAZIONE

ATOLLO BACKUP GUIDA INSTALLAZIONE E CONFIGURAZIONE ATOLLO BACKUP GUIDA INSTALLAZIONE E CONFIGURAZIONE PREMESSA La presente guida è da considerarsi come aiuto per l utente per l installazione e configurazione di Atollo Backup. La guida non vuole approfondire

Dettagli

Manuale Terminal Manager 2.0

Manuale Terminal Manager 2.0 Manuale Terminal Manager 2.0 CREAZIONE / MODIFICA / CANCELLAZIONE TERMINALI Tramite il pulsante NUOVO possiamo aggiungere un terminale alla lista del nostro impianto. Comparirà una finestra che permette

Dettagli

MOBILE WEB DESIGN TUTORIAL ANDROID METAIO AUGMENTED REALITY

MOBILE WEB DESIGN TUTORIAL ANDROID METAIO AUGMENTED REALITY MOBILE WEB DESIGN TUTORIAL ANDROID METAIO AUGMENTED REALITY 1 Sommario 1. INTRODUZIONE... 3 2. GET METAIO... 4 2.1. PREREQUISITI... 4 2.2. INTALLAZIONE... 4 2.3. PROGETTI ESEMPLIFICATIVI... 4 3. USARE

Dettagli

Corso Eclipse. Prerequisiti. 1 Introduzione

Corso Eclipse. Prerequisiti. 1 Introduzione Corso Eclipse 1 Introduzione 1 Prerequisiti Uso elementare del pc Esecuzione ricerche su Internet Esecuzione download Conoscenza elementare della programmazione 2 1 Cos è Eclipse Eclipse è un IDE (Integrated

Dettagli

PROGETTO PER LA TRASMISSIONE DOCUMENTI RELATIVI ALL APPROVAZIONE DELLE MANIFESTAZIONI IN FORMA DIGITALE

PROGETTO PER LA TRASMISSIONE DOCUMENTI RELATIVI ALL APPROVAZIONE DELLE MANIFESTAZIONI IN FORMA DIGITALE PROGETTO PER LA TRASMISSIONE DOCUMENTI RELATIVI ALL APPROVAZIONE DELLE MANIFESTAZIONI IN FORMA DIGITALE L approvazione di una manifestazione nazionale od internazionale comporta spesso la trasmissione

Dettagli

Sistemi Mobili e Wireless Android Primi passi

Sistemi Mobili e Wireless Android Primi passi Sistemi Mobili e Wireless Android Primi passi Stefano Burigat Dipartimento di Matematica e Informatica Università di Udine www.dimi.uniud.it/burigat stefano.burigat@uniud.it Ambiente di sviluppo L'ambiente

Dettagli

Manuale di Aggiornamento BOLLETTINO. Rel. 5.20.1H4. DATALOG Soluzioni Integrate a 32 Bit

Manuale di Aggiornamento BOLLETTINO. Rel. 5.20.1H4. DATALOG Soluzioni Integrate a 32 Bit Manuale di Aggiornamento BOLLETTINO Rel. 5.20.1H4 DATALOG Soluzioni Integrate a 32 Bit - 2 - Manuale di Aggiornamento Sommario 1 2 PER APPLICARE L AGGIORNAMENTO... 3 1.1 Aggiornamento Patch Storica...

Dettagli

1 Introduzione...1 2 Installazione...1 3 Configurazione di Outlook 2010...6 4 Impostazioni manuali del server... 10

1 Introduzione...1 2 Installazione...1 3 Configurazione di Outlook 2010...6 4 Impostazioni manuali del server... 10 Guida per l installazione e la configurazione di Hosted Exchange Professionale con Outlook 2010 per Windows XP Service Pack 3, Windows Vista e Windows 7 Edizione del 20 febbraio 2012 Indice 1 Introduzione...1

Dettagli

Mac Application Manager 1.3 (SOLO PER TIGER)

Mac Application Manager 1.3 (SOLO PER TIGER) Mac Application Manager 1.3 (SOLO PER TIGER) MacApplicationManager ha lo scopo di raccogliere in maniera centralizzata le informazioni piu salienti dei nostri Mac in rete e di associare a ciascun Mac i

Dettagli

Guida alla configurazione della posta elettronica dell Ateneo di Ferrara sui più comuni programmi di posta

Guida alla configurazione della posta elettronica dell Ateneo di Ferrara sui più comuni programmi di posta Guida alla configurazione della posta elettronica dell Ateneo di Ferrara sui più comuni programmi di posta. Configurazione Account di posta dell Università di Ferrara con il Eudora email Eudora email può

Dettagli

1) GESTIONE DELLE POSTAZIONI REMOTE

1) GESTIONE DELLE POSTAZIONI REMOTE IMPORTAZIONE ESPORTAZIONE DATI VIA FTP Per FTP ( FILE TRANSFER PROTOCOL) si intende il protocollo di internet che permette di trasferire documenti di qualsiasi tipo tra siti differenti. Per l utilizzo

Dettagli

FPf per Windows 3.1. Guida all uso

FPf per Windows 3.1. Guida all uso FPf per Windows 3.1 Guida all uso 3 Configurazione di una rete locale Versione 1.0 del 18/05/2004 Guida 03 ver 02.doc Pagina 1 Scenario di riferimento In figura è mostrata una possibile soluzione di rete

Dettagli

Il web server Apache Lezione n. 3. Introduzione

Il web server Apache Lezione n. 3. Introduzione Procurarsi ed installare il web server Apache Introduzione In questa lezione cominciamo a fare un po di pratica facendo una serie di operazioni preliminari, necessarie per iniziare a lavorare. In particolar

Dettagli

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi Capitolo Terzo Primi passi con Microsoft Access Sommario: 1. Aprire e chiudere Microsoft Access. - 2. Aprire un database esistente. - 3. La barra multifunzione di Microsoft Access 2007. - 4. Creare e salvare

Dettagli

Progetto: ARPA Fonte Dati. ARPA Fonte Dati. Regione Toscana. Manuale Amministratore

Progetto: ARPA Fonte Dati. ARPA Fonte Dati. Regione Toscana. Manuale Amministratore ARPA Fonte Dati Regione Toscana 1 Redatto da L. Folchi (TAI) Rivisto da Approvato da Versione 1.1 Data emissione 09/10/13 Stato FINAL 2 Versione Data Descrizione 1,0 06/08/13 Versione Iniziale 1.1 09/10/2013

Dettagli

Scuola Digitale. Manuale utente. Copyright 2014, Axios Italia

Scuola Digitale. Manuale utente. Copyright 2014, Axios Italia Scuola Digitale Manuale utente Copyright 2014, Axios Italia 1 SOMMARIO SOMMARIO... 2 Accesso al pannello di controllo di Scuola Digitale... 3 Amministrazione trasparente... 4 Premessa... 4 Codice HTML

Dettagli

Excel. A cura di Luigi Labonia. e-mail: luigi.lab@libero.it

Excel. A cura di Luigi Labonia. e-mail: luigi.lab@libero.it Excel A cura di Luigi Labonia e-mail: luigi.lab@libero.it Introduzione Un foglio elettronico è un applicazione comunemente usata per bilanci, previsioni ed altri compiti tipici del campo amministrativo

Dettagli

Lande Immortali: Riepilogo dello Stato di Avanzamento del Progetto

Lande Immortali: Riepilogo dello Stato di Avanzamento del Progetto Lande Immortali: Riepilogo dello Stato di Avanzamento del Progetto Progetto a cura di Martino Michele Matricola: 0124000461 Miglio Stefano Matricola: 0124000462 Obiettivi Iniziali Si intende realizzare

Dettagli

BMSO1001. Orchestrator. Istruzioni d uso 02/10-01 PC

BMSO1001. Orchestrator. Istruzioni d uso 02/10-01 PC BMSO1001 Orchestrator Istruzioni d uso 02/10-01 PC 2 Orchestrator Istruzioni d uso Indice 1. Requisiti Hardware e Software 4 1.1 Requisiti Hardware 4 1.2 Requisiti Software 4 2. Concetti fondamentali 4

Dettagli

Modulo. Programmiamo in Pascal. Unità didattiche COSA IMPAREREMO...

Modulo. Programmiamo in Pascal. Unità didattiche COSA IMPAREREMO... Modulo A Programmiamo in Pascal Unità didattiche 1. Installiamo il Dev-Pascal 2. Il programma e le variabili 3. Input dei dati 4. Utilizziamo gli operatori matematici e commentiamo il codice COSA IMPAREREMO...

Dettagli

Capitolo 3. L applicazione Java Diagrammi ER. 3.1 La finestra iniziale, il menu e la barra pulsanti

Capitolo 3. L applicazione Java Diagrammi ER. 3.1 La finestra iniziale, il menu e la barra pulsanti Capitolo 3 L applicazione Java Diagrammi ER Dopo le fasi di analisi, progettazione ed implementazione il software è stato compilato ed ora è pronto all uso; in questo capitolo mostreremo passo passo tutta

Dettagli

GateManager. 1 Indice. tecnico@gate-manager.it

GateManager. 1 Indice. tecnico@gate-manager.it 1 Indice 1 Indice... 1 2 Introduzione... 2 3 Cosa vi serve per cominciare... 2 4 La Console di amministrazione... 2 5 Avviare la Console di amministrazione... 3 6 Come connettersi alla Console... 3 7 Creare

Dettagli

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto: Tipi primitivi Il linguaggio Java offre alcuni tipi di dato primitivi Una variabile di tipo primitivo può essere utilizzata direttamente. Non è un riferimento e non ha senso tentare di istanziarla mediante

Dettagli

Esercitazione n 4. Obiettivi

Esercitazione n 4. Obiettivi Esercitazione n 4 Obiettivi Progettare e implementare per intero un componente software in Java Linguaggio Java: Classi astratte Utilizzo di costruttori e metodi di superclasse Polimorfismo Esempio guida:

Dettagli

I TUTORI. I tutori vanno creati la prima volta seguendo esclusivamente le procedure sotto descritte.

I TUTORI. I tutori vanno creati la prima volta seguendo esclusivamente le procedure sotto descritte. I TUTORI Indice Del Manuale 1 - Introduzione al Manuale Operativo 2 - Area Tutore o Area Studente? 3 - Come creare tutti insieme i Tutori per ogni alunno? 3.1 - Come creare il secondo tutore per ogni alunno?

Dettagli

Manuale Utente SIRECO

Manuale Utente SIRECO Corte Dei Conti Manuale Utente SIRECO Guida all accesso a SIRECO Indice dei contenuti 1. Obiettivo del documento... 3 1.1 Acronimi, abbreviazioni, e concetti di base... 3 2. Registrazione di un Responsabile...

Dettagli

Software di interfacciamento sistemi gestionali Manuale di installazione, configurazione ed utilizzo

Software di interfacciamento sistemi gestionali Manuale di installazione, configurazione ed utilizzo 01595 Software di interfacciamento sistemi gestionali Manuale di installazione, configurazione ed utilizzo INDICE DESCRIZIONE DEL SOFTWARE DI INTERFACCIAMENTO CON I SISTEMI GESTIONALI (ART. 01595) 2 Le

Dettagli

Laurea Specialistica in Informatica, Tecnologie Informatiche Anno Accademico 2008/2009 Reti Applicazioni e Servizi

Laurea Specialistica in Informatica, Tecnologie Informatiche Anno Accademico 2008/2009 Reti Applicazioni e Servizi Laurea Specialistica in Informatica, Tecnologie Informatiche Anno Accademico 2008/2009 Reti Applicazioni e Servizi Implementazione di una MIDlet che realizza un sistema di voto Christian Tiralosi Sviluppatori:

Dettagli

IRSplit. Istruzioni d uso 07/10-01 PC

IRSplit. Istruzioni d uso 07/10-01 PC 3456 IRSplit Istruzioni d uso 07/10-01 PC 2 IRSplit Istruzioni d uso Indice 1. Requisiti Hardware e Software 4 1.1 Requisiti Hardware 4 1.2 Requisiti Software 4 2. Installazione 4 3. Concetti fondamentali

Dettagli

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito)

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito) Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito) Le seguenti istruzioni sono relative all installazione di IBM SPSS Modeler Text Analytics versione 15 mediante un licenza

Dettagli

STUDIUM.UniCT Tutorial per gli studenti

STUDIUM.UniCT Tutorial per gli studenti STUDIUM.UniCT Tutorial per gli studenti Studium.UniCT Tutorial Studenti v. 6 06/03/2014 Pagina 1 Sommario 1. COS È STUDIUM.UniCT... 3 2. COME ACCEDERE A STUDIUM.UniCT... 3 3. COME PERSONALIZZARE IL PROFILO...

Dettagli

Sistemi Mobili e Wireless Android Activity

Sistemi Mobili e Wireless Android Activity Sistemi Mobili e Wireless Android Activity Stefano Burigat Dipartimento di Matematica e Informatica Università di Udine www.dimi.uniud.it/burigat stefano.burigat@uniud.it Activity Tipicamente, un'activity

Dettagli

GESGOLF SMS ONLINE. Manuale per l utente

GESGOLF SMS ONLINE. Manuale per l utente GESGOLF SMS ONLINE Manuale per l utente Procedura di registrazione 1 Accesso al servizio 3 Personalizzazione della propria base dati 4 Gestione dei contatti 6 Ricerca dei contatti 6 Modifica di un nominativo

Dettagli

Guida alla Prima Configurazione dei Servizi

Guida alla Prima Configurazione dei Servizi Guida alla Prima Configurazione dei Servizi Indice Indice Guida all attivazione del servizio centralino 3 A. Applicazione Centralino su PC 5 B. Gruppo Operatori 9 Gestione all attivazione dei servizi internet

Dettagli

Argo Palm Manuale utente Versione 4.0.0 del 05-05-2010

Argo Palm Manuale utente Versione 4.0.0 del 05-05-2010 Argo Palm Manuale utente Versione 4.0.0 del 05-05-2010 Sommario Premessa... 3 Installazione... 3 Requisiti minimi per l installazione:... 3 Installazione del software sul Palmare... 4 Uso del programma...

Dettagli

Mon Ami 3000 Multimagazzino Gestione di più magazzini fisici e/o logici

Mon Ami 3000 Multimagazzino Gestione di più magazzini fisici e/o logici Prerequisiti Mon Ami 3000 Multimagazzino Gestione di più magazzini fisici e/o logici L opzione Multimagazzino è disponibile per le versioni Azienda Light e Azienda Pro. Introduzione L opzione Multimagazzino

Dettagli

2 Fortino Lugi. Figura Errore. Nel documento non esiste testo dello stile specificato.-3 -- Finestra attiva o nuovo documento

2 Fortino Lugi. Figura Errore. Nel documento non esiste testo dello stile specificato.-3 -- Finestra attiva o nuovo documento 1 Fortino Lugi STAMPA UNIONE OFFICE 2000 Vi sarà capitato sicuramente di ricevere lettere pubblicitarie indirizzate personalmente a voi; ovviamente quelle missive non sono state scritte a mano, ma utilizzando

Dettagli

Tools For Autism 1.0. Manuale d uso

Tools For Autism 1.0. Manuale d uso Tools For Autism 1.0 Manuale d uso Introduzione L applicazione per tablet Android Tools For Autism consente la creazione, visualizzazione e modifica di due strumenti didattici quali le storie sociali e

Dettagli

Manuale LiveBox WEB ADMIN. http://www.liveboxcloud.com

Manuale LiveBox WEB ADMIN. http://www.liveboxcloud.com 2014 Manuale LiveBox WEB ADMIN http://www.liveboxcloud.com LiveBox Srl non rilascia dichiarazioni o garanzie in merito al contenuto o uso di questa documentazione e declina qualsiasi garanzia espressa

Dettagli

GUIDA DI INSTALLAZIONE E PRIMA CONFIGURAZIONE DI EDILCONNECT PER I CONSULENTI

GUIDA DI INSTALLAZIONE E PRIMA CONFIGURAZIONE DI EDILCONNECT PER I CONSULENTI 1 GUIDA DI INSTALLAZIONE E PRIMA CONFIGURAZIONE DI EDILCONNECT PER I CONSULENTI Introduzione Dal 24 ottobre è possibile per i consulenti effettuare l installazione e la configurazione del nuovo applicativo

Dettagli

Guida all uso della piattaforma. E-did@blog. portale Weblog & Podcast del MIUR COME UTILIZZARE AL MEGLIO L AMMINISTRAZIONE DEL BLOG

Guida all uso della piattaforma. E-did@blog. portale Weblog & Podcast del MIUR COME UTILIZZARE AL MEGLIO L AMMINISTRAZIONE DEL BLOG Guida all uso della piattaforma E-did@blog portale Weblog & Podcast del MIUR COME UTILIZZARE AL MEGLIO L AMMINISTRAZIONE DEL BLOG L area amministrativa si suddivide in due aree: la gestione del blog e

Dettagli

Il sofware è inoltre completato da una funzione di calendario che consente di impostare in modo semplice ed intuitivo i vari appuntamenti.

Il sofware è inoltre completato da una funzione di calendario che consente di impostare in modo semplice ed intuitivo i vari appuntamenti. SH.MedicalStudio Presentazione SH.MedicalStudio è un software per la gestione degli studi medici. Consente di gestire un archivio Pazienti, con tutti i documenti necessari ad avere un quadro clinico completo

Dettagli

MANUALE D USO DELLA PIATTAFORMA ITCMS

MANUALE D USO DELLA PIATTAFORMA ITCMS MANUALE D USO DELLA PIATTAFORMA ITCMS MANULE D USO INDICE 1. INTRODUZIONE... 2 2. ACCEDERE ALLA GESTIONE DEI CONTENUTI... 3 3. GESTIONE DEI CONTENUTI DI TIPO TESTUALE... 4 3.1 Editor... 4 3.2 Import di

Dettagli

E possibile modificare la lingua dei testi dell interfaccia utente, se in inglese o in italiano, dal menu [Tools

E possibile modificare la lingua dei testi dell interfaccia utente, se in inglese o in italiano, dal menu [Tools Una breve introduzione operativa a STGraph Luca Mari, versione 5.3.11 STGraph è un sistema software per creare, modificare ed eseguire modelli di sistemi dinamici descritti secondo l approccio agli stati

Dettagli

Guida Compilazione Piani di Studio on-line

Guida Compilazione Piani di Studio on-line Guida Compilazione Piani di Studio on-line SIA (Sistemi Informativi d Ateneo) Visualizzazione e presentazione piani di studio ordinamento 509 e 270 Università della Calabria (Unità organizzativa complessa-

Dettagli

CREAZIONE DI UN AZIENDA

CREAZIONE DI UN AZIENDA CREAZIONE DI UN AZIENDA La creazione di un azienda in Businesspass avviene tramite la funzione Aziende Apertura azienda ; dalla medesima sarà possibile richiamare le aziende precedentemente create per

Dettagli

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) 12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica,

Dettagli

Guida Utente PS Contact Manager GUIDA UTENTE

Guida Utente PS Contact Manager GUIDA UTENTE GUIDA UTENTE Installazione...2 Prima esecuzione...5 Login...7 Registrazione del programma...8 Inserimento clienti...9 Gestione contatti...11 Agenti...15 Archivi di base...16 Installazione in rete...16

Dettagli

Portale tirocini. Manuale utente Per la gestione del Progetto Formativo

Portale tirocini. Manuale utente Per la gestione del Progetto Formativo GESTIONE PROGETTO FORMATIVO Pag. 1 di 38 Portale tirocini Manuale utente Per la gestione del Progetto Formativo GESTIONE PROGETTO FORMATIVO Pag. 2 di 38 INDICE 1. INTRODUZIONE... 3 2. ACCESSO AL SISTEMA...

Dettagli

OSSERVATORIO REGIONALE CONTRATTI PUBBLICI DI LAVORI, SERVIZI E FORNITURE

OSSERVATORIO REGIONALE CONTRATTI PUBBLICI DI LAVORI, SERVIZI E FORNITURE REGIONE LOMBARDIA DIREZIONE GENERALE INFRASTRUTTURE E MOBILITA U.O. INFRASTRUTTURE VIARIE E AEROPORTUALI OSSERVATORIO REGIONALE CONTRATTI PUBBLICI DI LAVORI, SERVIZI E FORNITURE PROGRAMMI TRIENNALI Manuale

Dettagli

2.7 La cartella Preparazioni e CD Quiz Casa

2.7 La cartella Preparazioni e CD Quiz Casa 2.7 La cartella Preparazioni e CD Quiz Casa SIDA CD Quiz Casa è il cd che permette al candidato di esercitarsi a casa sui quiz ministeriali e personalizzati. L autoscuola può consegnare il cd al candidato

Dettagli

Client - Server. Client Web: il BROWSER

Client - Server. Client Web: il BROWSER Client - Server Client Web: il BROWSER Il client Web è un applicazione software che svolge il ruolo di interfaccia fra l utente ed il WWW, mascherando la complessità di Internet. Funzioni principali Inviare

Dettagli

Corso basi di dati Installazione e gestione di PWS

Corso basi di dati Installazione e gestione di PWS Corso basi di dati Installazione e gestione di PWS Gianluca Di Tomassi Email: ditomass@dia.uniroma3.it Università di Roma Tre Cosa è PWS? Il Personal Web Server altro non è che una versione ridotta del

Dettagli

COME CREARE UNA COMUNICAZIONE / NEWSLETTER

COME CREARE UNA COMUNICAZIONE / NEWSLETTER COME CREARE UNA COMUNICAZIONE / NEWSLETTER Benvenuti nella MINI GUIDA di Centrico per la creazione di una nuova Comunicazione o Newsletter. Grazie a questa guida, potrai creare delle comunicazioni ad hoc

Dettagli

MANUALE UTENTE. In questo manuale verranno descritte tutte le sue funzioni. Il sistema OTRS è raggiungibile al seguente link:

MANUALE UTENTE. In questo manuale verranno descritte tutte le sue funzioni. Il sistema OTRS è raggiungibile al seguente link: MANUALE UTENTE OTRS è il sistema di ticketing per la gestione delle richieste tecniche e di supporto ai clienti e partner di Delta Progetti 2000. La nuova versione 3.2.10 introduce una grafica più intuitiva

Dettagli

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica Consiglio regionale della Toscana Regole per il corretto funzionamento della posta elettronica A cura dell Ufficio Informatica Maggio 2006 Indice 1. Regole di utilizzo della posta elettronica... 3 2. Controllo

Dettagli

Configurare TPTP in Eclipse e testare un applicazione

Configurare TPTP in Eclipse e testare un applicazione Configurare TPTP in Eclipse e testare un applicazione Questa guida concentra la sua attenzione sul tool TPTP (Test & Performance Tools Platform) presente nell ambiente di sviluppo Eclipse. Verrà descritta

Dettagli

MANUALE UTENTE. TeamPortal Liste Distribuzioni 20120100

MANUALE UTENTE. TeamPortal Liste Distribuzioni 20120100 MANUALE UTENTE 20120100 INDICE Introduzione... 3 1 - Messaggi... 4 1.1 Creazione / Modifca Email... 6 1.2 Creazione / Modifca Sms... 8 2 -Liste... 10 3 Gruppi Liste... 15 4 Tipi Messaggi... 17 5 Amministrazione...

Dettagli

Express Import system

Express Import system Express Import system Manuale del destinatario Sistema Express Import di TNT Il sistema Express Import di TNT Le consente di predisporre il ritiro di documenti, pacchi o pallet in 168 paesi con opzione

Dettagli

Procedure di ripristino del sistema.

Procedure di ripristino del sistema. Procedure di ripristino del sistema. Procedura adatta a sistemi con sistema operativo Microsoft Windows 8.1 In questo manuale verranno illustrate tutte le procedure che potrete utilizzare per creare dei

Dettagli

Giornale di Cassa e regolarizzazione dei sospesi

Giornale di Cassa e regolarizzazione dei sospesi Servizi di sviluppo e gestione del Sistema Informativo del Ministero dell Istruzione dell Università e della Ricerca Giornale di Cassa e regolarizzazione dei sospesi Guida Operativa Versione 1.0 del RTI

Dettagli

MODELLO CLIENT/SERVER. Gianluca Daino Dipartimento di Ingegneria dell Informazione Università degli Studi di Siena daino@unisi.it

MODELLO CLIENT/SERVER. Gianluca Daino Dipartimento di Ingegneria dell Informazione Università degli Studi di Siena daino@unisi.it MODELLO CLIENT/SERVER Gianluca Daino Dipartimento di Ingegneria dell Informazione Università degli Studi di Siena daino@unisi.it POSSIBILI STRUTTURE DEL SISTEMA INFORMATIVO La struttura di un sistema informativo

Dettagli

Guida alla registrazione on-line di un NovaSun Log

Guida alla registrazione on-line di un NovaSun Log Guida alla registrazione on-line di un NovaSun Log Revisione 4.1 23/04/2012 pag. 1 di 16 Contenuti Il presente documento è una guida all accesso e all utilizzo del pannello di controllo web dell area clienti

Dettagli

Modulo 4 Il pannello amministrativo dell'hosting e il database per Wordpress

Modulo 4 Il pannello amministrativo dell'hosting e il database per Wordpress Copyright Andrea Giavara wppratico.com Modulo 4 Il pannello amministrativo dell'hosting e il database per Wordpress 1. Il pannello amministrativo 2. I dati importanti 3. Creare il database - Cpanel - Plesk

Dettagli

Per chi ha la Virtual Machine: avviare Grass da terminale, andando su Applicazioni Accessori Terminale e scrivere grass

Per chi ha la Virtual Machine: avviare Grass da terminale, andando su Applicazioni Accessori Terminale e scrivere grass 0_Iniziare con GRASS Avvio di Grass e creazione della cartella del Database di GRASS Per chi ha la Virtual Machine: avviare Grass da terminale, andando su Applicazioni Accessori Terminale e scrivere grass

Dettagli

Presentazione della pratica online

Presentazione della pratica online Presentazione della pratica online Dalla prima pagina del sito del comune http://www.comune.ficulle.tr.it/, selezionate Sportello Unico Attività Produttive ed Edilizia Selezionate ora ACCEDI nella schermata

Dettagli

INSTALLAZIONE NUOVO CLIENT TUTTOTEL (04 Novembre 2014)

INSTALLAZIONE NUOVO CLIENT TUTTOTEL (04 Novembre 2014) INSTALLAZIONE NUOVO CLIENT TUTTOTEL (04 Novembre 2014) Se la Suite risulta già stata installata e quindi sono già presenti le configurazioni di seguito indicate, si prega di andare direttamente alla fine

Dettagli

File, Modifica, Visualizza, Strumenti, Messaggio

File, Modifica, Visualizza, Strumenti, Messaggio Guida installare account in Outlook Express Introduzione Questa guida riguarda di sicuro uno dei programmi maggiormente usati oggi: il client di posta elettronica. Tutti, ormai, siamo abituati a ricevere

Dettagli