\part{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 à cheval sur le client et le serveur) et nous ne parerons ici que du serveur, puis du code client. \paragraph{} Voici une 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] {bouncing-cube} child { node {BouncingCube.js}} child { node {main.js}} } child [missing] {} child [missing] {} child {node [folder] {multi-sphere} child {node {main.js}} } child [missing] {} child {node [folder] {stream-demo} child {node {main.js}} } child [missing] {} 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} \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'inconviéniant 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, et c'est pourquoi nous avons utilisé \texttt{npm-shrinkwrap.json} pour préciser les versions de chacune des dépendances de manière récursive. \paragraph{} Les \emph{packages} que nous utilisons sont les suivants : \begin{itemize} \item \emph{express} : un framework web pour NodeJs \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 reqûetes \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-controleur} : en JavaScript, nos modèles seront des objets simples, 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. \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 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 notamment leurs recommandations et leurs pièces rouges. \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 section \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 tutoriel 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} C'est une interface qui permet de créer des pièces : en cliquant sur une paroi, un pièce apparait, et en cliquant sur une pièce, elle disparaît. Cette interface possède un bouton qui permet d'envoyer un mail contenant les données des pièces crées au format JSON. \subsubsection{Coin-editor} Cette interface permet d'étier les pièces : elle est similaire à la précédente, mais expose une variable globale lors du clic sur une pièce qui permet de déplacer celle-ci. Elle sert à corriger les bugs potentiels introduits par l'interface précédente, notamment lorsqu'une pièce traverse une paroi. \subsubsection{Coin-checker} Elle permet de chercher toutes les pièces d'une scène, au cas où certaines se soient glissées à l'intérieur du modèle.