\mypart{Architecture du programme} Comme dit précédemment, le programme se décompose en un côté serveur et un côté client. Le cas du \emph{streaming} sera traité à part (dans la partie \ref{streaming}, puisqu'il est comporte des parties à la fois sur le client et le serveur) et nous ne parlerons ici que du serveur, puis du code client. \paragraph{} Voici une \emph{simplification} de l'arborescence de la version de développement : \begin{figure}[H] \centering \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {root} child { node [folder] {js} child {node [folder] {l3d} child {node [folder] {src}} child {node [folder] {apps}} } child [missing] {} child [missing] {} child {node [folder] {Autres libraries}} child {node {Makefile}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node [folder] {lib} child {node {NodeLog.js}} child {node {controllers.js}} child {node {posts.js}} child {node {mail.js}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node [folder] {controllers}} child { node [folder] {posts}} child { node [folder] {geo} child {node {Geo.js}} child {node {Mesh.js}} child {node {MeshContainer.js}} child {node {MeshStreamer.js}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node {private.js }} child { node {package.json }} child { node {npm-shrinkwrap.json }} child { node {server.js }}; \end{tikzpicture} \caption{Vue globale} \end{subfigure} ~ \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {src} child { node [folder] {cameras} child { node {FixedCamera.js}} child { node {PointerCamera.js}} child { node {ReplayCamera.js}} } child [missing] {} child [missing] {} child [missing] {} child { node [folder] {canvases} child { node { MousePointer.js}} child { node { Previewer.js}} child { node { StartCanvas.js}} } child [missing] {} child [missing] {} child [missing] {} child { node [folder] {loaders} child { node { ProgressiveLoader.js }} } child [missing] {} child { node [folder] {math} child { node { Hermite.js }} } child [missing] {} child { node [folder] {recommendations} child { node { Arrow.js}} child { node { Viewport.js}} } child [missing] {} child [missing] {} child { node [folder] {scenes}} child { node [folder] {utils} child { node [folder] {closure-compiler}} child { node [folder] {simple-compiler}} child { node { build\_all.sh}} child { node { demon.sh}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node {l3d.js}} ; \end{tikzpicture} \caption{Détail des sources de L3D} \end{subfigure} ~ \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {apps} child {node [folder] {prototype} child {node [folder] {interactive} child {node {main.js}} } child [missing] {} child {node [folder] {replay} child {node {main.js}} } child [missing] {} child {node [folder] {tutorial} child {node {main.js}} } child [missing] {} child {node [folder] {coin-creator} child {node {main.js}} } child [missing] {} child {node [folder] {coin-viewer} child {node {main.js}} } child [missing] {} child {node [folder] {coin-checker} child {node {main.js}} } child [missing] {} child {node {ButtonManager.js}} child {node {Coin.js}} child {node {GlobalFunctions.js}} } ; \end{tikzpicture} \caption{Détail des applications} \end{subfigure} \caption{Arborescence du \emph{dépôt} de développement} \end{figure} \tikzstyle{every node}=[] \section{Code serveur} Le code serveur est situé à la racine du projet : le fichier \texttt{server.js} est en fait le programme principal du serveur. \subsection{Dépendances} Le programme principal utilise de nombreuses libraires : les dépendances de notre serveur sont définies dans le fichier \texttt{package.json}. L'inconvénient d'avoir de nombreuses librairies en même temps est la compatibilité des versions : en effet, une des dépendances nécessite une version particulière d'une autre librairie. Chaque dépendance est une librairie, qui a elle même ses dépendances, etc... \paragraph{} J'ai recontré ce problème au cours du projet : une librairie utilisait une version précise d'une dépendance qui en nécessitait une autre. Nous avons donc utilisé une fonctionnalité de \emph{npm} (le programme qui permet d'installer des librairies dans un serveur NodeJs) qui s'appelle \emph{shrinkwrap} et qui permet de figer l'arbre de dépendance d'une application NodeJs. \paragraph{} Les \emph{packages} que nous utilisons sont les suivants : \begin{itemize} \item \emph{express} : un framework web pour NodeJs qui permet de gérer facilement les urls, les requêtes, les réponses, etc... \item \emph{jade} : un moteur de template pour simplifier la génération des pages HTML \item \emph{pg} : une librairie permettant la connexion à la base de données \item \emph{body-parser} : une librairie permettant de traiter simplement les paramètres passés aux requêtes \item \emph{cookie-parser} et \emph{cookie-session} : une librairie gérant les sessions sous forme de cookies \item \emph{socket.io} : une librairie permettant d'utiliser facilement les sockets (côté serveur et client) \item \emph{serve-favicon} : une librairie pour choisir facilement l'icône du site \item \emph{emailjs} : une librairie permettant de se connecter à une adresse e-mail \end{itemize} \subsection{Modèle, vue, contrôleur} Pour ce projet, nous avons adopté une version simplifiée du design-pattern \emph{modèle-vue-contrôleur} : en JavaScript, nos modèles seront des objets simples (en JavaScript, un objet n'est qu'une liste de paires \emph{clé-valeur}), et le modèle sera limité à l'exécution des requêtes SQL. \paragraph{} Les contrôleurs sont chargés au démarrage par le fichier \texttt{controllers.js}, qui parcourt les dossiers qui sont contenus dans le dossier \texttt{controllers}. Dans chacun de ces dossiers, deux fichiers et un dossier sont présents : \begin{itemize} \item \texttt{index.js} qui contient des fonctions (contrôleurs) qui répondent à des requêtes \item \texttt{urls.js} qui contient les urls existantes et les fonctions auxquelles elles vont être associées \item \texttt{views}, dossier qui contient les vues qui vont être utilisées par les contrôleurs définis dans \texttt{index.js} \end{itemize} \paragraph{} La même technique à été appliquée pour le dossier \texttt{posts} et le fichier \texttt{posts.js}, à la différence près que les requêtes traitées sont des requêtes POST et non pas des requêtes GET : elles servent principalement à stocker des informations dans la base de donneés. \newpage \section{Code client} Le code client est séparé en trois parties : \begin{itemize} \item une partie dans le répertoire \texttt{src} contenant de nombreuses fonctions et classes \item une partie dans le répertoire \texttt{apps} contenant des applications que nous avons développées \item des autres librairies développées par des tiers, dans le répertoire \texttt{js} \end{itemize} Le \texttt{Makefile} présent dans le dossier \texttt{js} est celui qui concatènera nos sources, les \emph{minifieras} et génèrera les scripts que nous utiliserons par la suite. \paragraph{} Dans la suite, nous allons seulement parler de L3D, puisque c'est le code que nous avons développé. \subsection{Les sources} L3D est composée de plusieurs classes : \begin{itemize} \item les caméras, permettant de choisir des caméras avec des mouvements particuliers \item les canvas, qui permettent d'afficher des informations supplémentaires à l'écran \item les loaders, qui permettent de charger des modèles de manière différente de celles proposées par \threejs{} \item les classes mathématiques, comme les polynômes de Hermite \item les recommandations, notamment les flèches et les \emph{viewports} \end{itemize} \paragraph{} Elle contient aussi quelques fonctions qui permettent de créer les scènes que nous avons utilisées, et de les initialiser correctement. \paragraph{} Dans le répertoire \texttt{utils}, il y a plusieurs outils pratiques pour le développement et le déploiement : c'est là qu'est rangé le \emph{minifier} de Google, \closurecompiler{}, et une version simplifiée, le Simple-Compiler, qui utilise les mêmes paramètres mais se contente de concaténer le code. \paragraph{} Pour L3D, le premier fichier qui sera dans la version finale est \texttt{l3d.js}. Il contient simplement l'initialisation du \emph{namespace} \texttt{L3D}, auquel toutes les classes et fonctions appartiendront. \subsection{Les applications} Les applications sont principalement composées de programmes principaux, qui utilisent les classes de L3D, ainsi, elles ne sont pas fusionnées avec L3D, et laissées dans le namespace global. \subsubsection{Interactive} Ceci est l'interface principale, où l'utilisateur doit rechercher les pièces. Nous en parlerons plus dans la partie \ref{interface}. \subsubsection{Replay} C'est l'interface qui crée une \texttt{ReplayCamera} et permet de visionner une expérience qui a été faite dans le passé. \subsubsection{Tutorial} C'est le didacticiel de l'application : il possède notamment une classe qui copie la caméra principale tout en permettant de vérifier que les interactions sont faites comme il faut. \subsubsection{Coin-creator, Coin-editor et Coin-checker} Ce sont des outils de développement qui seront détaillés dans la section \ref{coins}.