4. Organisation du code - RoboboUPMC2016/RobApp GitHub Wiki

Nous allons parler de l'organisation du code, le code est découpé en trois packages principaux pour plus de lisibilité. Nous détaillons chaque le contenue des packages dans les parties suivantes.

A. L'Application - app

Le package app est décomposé en quatre sous-packages, app, adapter, dialog et listener. Il continent toutes les classes utilisées pour l'application c'est-à-dire les activités et ce qui leur est nécessaire pour fonctionner.

a. Le package activity

Dans le package app vous trouverez toutes les classes des activités de l'application.

  • BaseActivity : L'activité de base , elle permet de gérer la partie commune de toutes les activités, le NavigationDrawer. Toutes nos activité ont un navigation drawer commun, pour simplifier sa création nous avons créé la classe BaseActivity qui permet de gérer la création et la gestion du navigation drawer. Si vous souhaitez créer une activité avec le même navigation drawer vous devez étendre cette classe et appeler la fonction setupNavigationDrawer après avoir définit le layout dans la fonction onCreate. Il faut aussi que vous définissiez les fichiers layout de votre activité correctement en appelant bien le le fichier du navigation drawer. Vous trouverez des exemples en regardant les layouts de nos activités.

Exemple :
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_behavior);
setupDrawer();

  • BehaviorActivity : C'est l'activité pour lancer un comportement, elle permet de lancer un comportement et de l'arrêter. Elle affiche l'émotion du robot durant le comportement.

  • DownloadBehaviorActivity : Cette activité gère le téléchargement de comportements. Elle fait une requête au serveurRobHub pour récupérer la liste des comportements téléchargeables puis les affiche. On peut ensuite cliquer sur un comportement pour le télécharger. Le comportement est enregistré dans le répertoire privé (downloaded_behavior) de l'application. Pour éviter le problème de renommage des fichiers ayant le même nom chaque comportement est enregistré dans un sous répertoire dont le nom est l'identifiant du comportement sur RobHub.

Exemple : Le comportement Danse avec l'identifiant 1 et le fichier Danse.dex sera enregistré comme ceci downloader_behavior/1/Danse.dex
Un autre comportement Danse avec l'identifiant 2 et le fichier Danse.dex sera enregistré comme ceci downloader_behavior/2/Danse.dex

  • FileExplorerActivity : Avec cette activité on peut importer un fichier de comportement compilé qui se trouve sur le téléphone (Carte SD / Mémoire Interne). Ici, nous avons un explorateur de fichier qui permet de parcourir la carte SD ou la mémoire interne du téléphone. Le fichier est copié dans le répertoire privé de l'application, mais cette fois dans le dossier downloaded_behavior. Si l'utilisateur importe un fichier et qu'un fichier avec le même nom existe déjà le fichier sera renommé. Les fichiers importés non pas d'identifiant ils sont tous enregistrés dans le sous répertoire imported.

Exemple : Le fichier Danse.dex est importé il sera enregistré sous le nom Danse et sera enregistré comme ceci downloader_behavior/imported/Danse.dex
Un autre fichier Danse.dex est importé il sera renommé Danse_1 et sera enregistré comme ceci downloader_behavior/2/Danse.dex

  • QRCode Activity : L'activité QRCodeActivity génère un QRCode lié au comportement sélectionné scanné le QRCode permet d'être redirigé sur la page du comportement sélectionné. A partir de cette page l'utilisateur peut noter le comportement, poster et consulter des vidéos sur le comportements mais aussi voir le code du comportement.
b. Le package adapter

Dans le package adapter vous trouverez deux classes BehaviorAdapter et FileExplorerAdapter.

  • BehaviorAdapter : L'adapter utilisé pour gérer la liste des comportements. Cet adapter crée les vues des items comportement dans la ListView "nav_behavior" du menu. Chaque vue contient le nom du comportement et une image informant sur le faite que le comportement est un comportement téléchargé (ou importé) ou s'il s'agit d'un comportement de base de l'application.

  • FileExplorerAdapter : Ici, l'adapter crée les vues de la ListView de l'activité FileExplorerActivity. Chaque vue contient le nom du fichier et une image permettant de déterminer si c'est un fichier ou un répertoire.

c. Le package dialog

Ce package fournit plusieurs classes pour créer des boites de dialogues.

  • BehaviorSelectionDialog : Boite de dialogue pour sélectionner un comportement (C'est ici qu'est utilisé le BehaviorAdapter)

  • Launcher : Boite de dialogue pour lancer le comportement. Cette boite de dialogue va créer thread pour lancer le comportement sélectionné.

  • RobDeviceSelectionDialog : Boite de dialogue pour sélectionner le périphérique à utiliser pour la connexion bluetooth.

d. Le package listener

Dans le dernier sous-package on trouve des listeners utilisés pas l'activité FileExplorerActivity.

  • FileExplorerListener : C'est un OnClickListener utilisé pour les fichiers et les dossiers affichés par l'activité. Ce listener est utilisé pour naviguer dans l'arborescence de fichiers

  • FileExplorerLongListener : C'est un OnLongClickListener utilisé pour les fichiers et les dossier affichés par l'activité. Ce listener est utilisé pour importer le fichier.

B. Les comportements

Dans ce package on trouve le code liée à l'exécution des comportements, on y trouve aussi l'implémentation du framework RobDev.

a. actions

C'est l'implémentation de RobDev, plus exactement l'implémentation de l'interface Action. Cette classe fait le lien entre les fonctions pour manipuler le robot et celles proposées par le framework. Pour chaque fonction qui manipule le robot on va utiliser notre système de sémaphore pour verrouiller l'accès au robot afin d'éviter les accès concurrent au robot. Le robot peut effectuer une seule action à la fois, s'il reçoit une action pendant qu'il en fait une il arrête celle qu'il faisait et commence la nouvelle. Pour pouvoir piloter le robot simplement on a rendu les appels de fonction bloquant. Lorsque l'on utilise une fonction qui va communiquer avec le robot (Avancer, Tourner, etc.) la fonction ne se terminera que lorsque l'action aura été terminée. Nous avons aussi mis un petit test au début de chaque fonction, on vérifie si un handler s'exécute avant d'effectuer l'action pour ne pas perturber l'exécution du handler. Si le thread qui vérifie si un handler s'exécuter est le dernier handler créer il ne sera pas bloqué tous les autres le seront. Un handler sera bloqué tant que son handler (S'il en a un) n'aura pas terminé son exécution.

b. exception

Si l'utilisateur peut lancer un comportement il peut aussi l'arrêter pour ça nous avons utilisé les exceptions de java. Pour augmenter la lisibilité du code des comportements nous avons utilisé des RuntimeException pour ne pas avoir à les déclarer dans la déclaration des fonctions (Et celle du framework). En java, le thread n'est pas interrompu directement lorsque l'on appele la fonction interrupt. Le thread recevra l'InterruptedException quand il fera un wait. Dans notre système on s'appuie sur ce mécanisme pour interrompre le thread. Comme nous avons des wait régulièrement (Lors de la vérification de l'exécution d'un handler, attente de la fin d'une commande, etc.) on arrive à interrompre les différents handlers proprement.

c. executions

C'est le cœur du système, grâce à ces classes on peut créer les contextes d'exécutions, les supprimer, distribuer les évènements aux différents threads pour appeler les handlers associés.

  • ContextManager : Gère les différents contextes d'exécution, un contexte est créé au lancement du comportement puis un nouveau contexte est créé pour chaque handler puis il est supprimé à la fin de l'exécution du handler. On utilise cette classe pour synchroniser les handlers. Les différents handlers vont accéder a leur contexte d'exécution grâce à cette classe.

  • Dispatcher : Permet de distribuer les évènements aux différant handlers enregistrés.

  • ExecutionContext : Le contexte d'exécution, il possède un thread qui est le thread pour lequel le contexte à été créé, il a aussi un dispatcher, pour enregistrer ses propres handlers sans les mélanger avec ceux des autres contexte.

d. interfaces

Les différentes interfaces que nous avons définis pour les handlers des évènements et les comportements.

  • BehaviorItemI : C'est une interface pour gérer les comportements.
  • CmdHandlerI : Interface pour gérer l'évènement fin de commande.
  • EventHandlerI : Interface pour attendre un évènement.
  • HandlerListenerI : Interface pour attendre la fin d'un handler.
e. item

Dans ce package on trouve les implémentations de l'interface BehaviorItemI. Ces item sont utilisés dans une même liste c'est pourquoi elle on un interface commune.

  • BehaviorFileItem : Représente un comportement qui a été importé ou téléchargé.
  • NativeBehaviorItem : Représente un comportement "natif". Le code de ces comportements est inclus dans le code de l'application ce sont les comportements par défaut.
f. listener

Nous trouvons dans ce package tous nos listeners et handlers.

  • CmdHandler : Implémentation de CmdHandlerI.
  • HandlerListner : Implémentation de HandlerListenerI.
  • RobHelperListener : Implementation de RoboboServiceHelper.Listener, ce listener est utilisé pour surveiller la création du Robobo manager. Le Robobo manager permet d'interagir avec le robot.(Voir code du projet robobo)
  • StatusListener : Ce listener est utilisé pour détecter les fins de commandes(i.e Dans les moteurs ne sont plus en mouvements). Le code du projet robobo ne propose pas de manière plus simple de savoir si une commande est terminée. (Voir code du projet robobo)
  • WaitEventListener : Le premier type de handler. Ce n'est pas à proprement parler un handler, permet d'attendre un évènement avant de reprendre son exécution.
  • WhenEventListener : Le second type de handler, permet de définir une fonction à appeler lorsqu'un évènement survient.
g. loader

Ce package contient la classe BehaviorClassLoader pour charger dynamiquement une classe

h. natives

Ce package contient tous les comportements par défaut de l'application. Nous l'avons utilisé pour tester notre framework, sans avoir à compiler les comportements manuellement avant de les tester.

C. tools

Dans ce package nous trouvons des classes outils qui n'avait pas pas leur place dans les autres packages.

  • FileRequest : Permet de faire une requête http et de récupérer un fichier.
  • Utils : En ensemble de fonction pour gérer la copie de fichiers etc.
  • XmlHandler et XMLParser : Deux classes pour gérer le parsing d'un fichier xml.

Partie Suivante