diff --git a/Rapport/rapport.tex b/Rapport/rapport.tex index c998f03..649f574 100644 --- a/Rapport/rapport.tex +++ b/Rapport/rapport.tex @@ -1,119 +1 @@ -\documentclass[10pt,a4paper]{article} -\usepackage[utf8]{inputenc} -\usepackage{color} -\usepackage[francais]{babel} -\usepackage{listings} -\usepackage[T1]{fontenc} -\usepackage{graphicx} -\usepackage[export]{adjustbox} -\bibliographystyle{ieeetr} -\author{GAILLARD Valentin FONTENAY Clément CHERIFI Ali} -\title{Rapport de projet\\Programmation système} -\begin{document} -\maketitle -\newpage -\tableofcontents -\newpage - -\section{Sauvegarde et chargement des cartes} -La principale source de réflexion ici a été de trouver une convention de stockage afin de stocker la carte avec toutes ses propriétés afin de nous simplifier au maximum les phases de d'écriture et de lecture. -Nous avons donc choisi de procéder comme suivant : -\begin{itemize} -\item Hauteur de la carte -\item Largeur de la carte -\item Nombre d'objets -\item Matrice de la carte (identifiant de l'objet) -\end{itemize} -Puis pour chaque objet : -\begin{itemize} -\item Taille de la chaine de caractère du nom de l'objet -\item Nom de l'objet -\item Caractéritiques de l'objet. -\end{itemize} -\subsection{Sauvegarde} - - La sauvegarde est pleinenement fonctionnelle. Tous les objets sont sauvegardés y compris ceux n'ayant aucune présence physique sur la carte. Il est donc possible d'utiliser tous les objets ultérieurement. - - Si la création du fichier de sauvegarde ne se déroule pas correctement, un message est affiché sur la sortie standard d'erreur et le code d'erreur est renvoyé à l'utilisateur. - Le sauvegaarde débute par la largeur et la hauteur et le nombre d'objets. Ces valeurs sont inscrites directement dans le fichier via la fonction \textit{write()}. - Par la suite, un tabeleau de taille \textit{largeur * hauteur} est créé. Un tableau de cette taille permet de stocker l'intégralité de la carte en un seul parcours et de n'effectuer qu'un seul appel bufferisé à \textit{write()}. - - Un tableau du nombre de caractéristiques est ensuite créé. Il permettra de façon similaire au tableau de la carte, de n'effectuer qu'un seul appel à appel à \textit{write()} pour sauvegarder toutes les caractéristiques en une seule fois dans le fichier de sauvegarde. - -\subsection{Chargement} - - Pour charger une carte, le fichier de sauvegarde est ouvert. Une vérification du bon déroulement de l'ouverture est fait. Si une erreur se produit, le code de l'erreur est affiché sur la sortie standard. La fonction commence par lire la largeur, la hauteur et le nombre d'objets. Une nouvelle carte est ensuite allouée. Une double boucle de la taille de la carte place tous les objets. A chaque itération un appel à \textit{read()} est effectué pour lire l'ID de l'objet dans la matrice et le placer sur le carte via un appel à \textit{map\_set()}. - - Il faut maintenant récupérer le nom de chaque objet ainsi que ses caractéritiques. Un appel à la fonction \textit{map\_object\_begin()} est effectué pour initier l'allocation des objets. Un boucle de la taille du nombre d'objets est effectué et lit pour chaque objet la taille du nom de l'objet et extrait le nom de cet objet. Lors de cette lecture le premier objet lu dans le fichier aura l'ID 0 ce qui correspond bien à l'ordre d'enregistrement lors de la sauvegarde. Les caractéristiques des objets sont ensuite lues dans le fichier. Ces dernières sont passées en paramètre à la fonction \textit{generer\_flags()} qui se charge de générer un seul entier contenant la solidité de l'objet et les flags actif c'est-à-dire à 1. L'allocation est ensuite faite via la fonction \textit{map\_object\_add}. - - La sauvegarde et le chargement ont été rélaisé ainsi dans le but de minimiser les apples systèmes. Cependant il ne nous a pas été possible de lire le nom du fichier à l'aide d'un seul appel système. En effet, pour les noms de fichiers de 16 caractères exactement, le lecture résultait en l'ajout de caractères aléatoires à la fin du nom de l'objet. Il a donc fallu lire caractère le nom du fichier pour s'assurer que le nom n'est pas erroné. - - -\section{Maputil} - Dans le main de maputil, on vérifie d'abord que le nombre d'arguments est d'au moins 2, puis on compare le deuxième argument aux différentes actions possibles. Et on vérifie également les erreurs possibles, comme l'ouverture du fichier map ou une erreurs dans les arguments. -\subsection{getwidth, height, objects, info} - Chaque fonction get, se contente de se placer à la bonne position dans le fichier map et de renvoyer la valeur de la fonction lireEntierPositif, qui appel read et qui vérifie si il y a une erreur. Puis on affiche, tout en testant le retour de la fonction get. -\subsection{Remplacement des objets d'une carte} - \subsubsection{Fonction de verification des arguments} - Avant d'appeler la fonction setObjects, on va d'abord verifier les arguments avec la fonction \textit{verificationArgumentsSetObjects}. - Dans cette fonction on vérfie d'abord si le nombre d'arguments est bon, donc pour ça on vérfifie d'abord si c'est un multiple 6, puisque l'utilisateur doit envoyer le nom de l'objet suivie des caractéristiques, ce qui fait plusieurs paquet de 6, de plus il faut vérifier que le nombre d'objets actuellement sur la carte est inférieur ou égale au nombre d'objets que l'utilisateur passe en parametre. Si la taille des arguments n'est pas bonne on renvoie ERRTAILLE - - Puis on vérifie les noms des arguments, pour ça, on vérifie si c'est bien un chiffre après le nom de l'image (le chiffre est la valeur de frame), donc pour ça, dans la boucle du parcours des arguments, si i est un multiple de 6 alors c'est que c'est une image et donc l'élement suivant doit être un chiffre, si ce n'est pas un chiffre on renvoie ERRNOM. - Ensuite on vérifie les arguments suivants, pour ça on utilise un tableau qui contient les noms "solid", "air", "collectible" ... et donc on compare les arguments avec les élements du tableau, si on ne retrouve pas l'argument dans le tableau on renvoie ERRNOM. - - \subsubsection{Fonction setobjects} - L'idée globale de la fonction c'est de supprimer dans le fichier tout sauf la hauteur et la largeur, pour pouvoir changer le nombre d'objet, et écrire la nouvelle liste. - - Pour ça on commence par se placer dans le fichier, au début de la matrice de la carte, puis on sauvegarde la matrice en lisant ligne par ligne (puisque on sait qu'une ligne est de taille largeur*sizeof(int) octets). - Ensuite on supprime le contenu du fichier sans supprimer les 2*sizeof(int) premier octets (qui sont la largeur et la hauteur), puis on écrit à la fin du fichier map la nouvelle valeur du nombre d'objet et la matrice. - - Enfin on écrit la nouvelle liste, pour ça on a une boucle qui va de 0 au nombre d'arguments, si i est un multiple de 6, alors c'est qu'on a une chaîne de caractère à écrire, donc comme notre convention l'exige, on doit écrire, dans le fichier map, la taille de la chaine. Donc on écrit la taille de la chaine, puis la chaine, puis le frame. On écrit le frame directement ici car il est traité différement des autres arguments. - Pour les autres arguments, on parcourt le tableau des caractéristiques, si l'argument est à l'index 0, 1 ou 2 on écrit 0, 1 ou 2 puisque c'est soit "solid" soit "semi-solid" soit "air". Si l'argument est à l'index 3,4 ou 5 on écrit 1 puisque c'est "collectible", "destructible" ou "generator", et sinon on écrit 0. - -\subsection{Modification de la taille de la carte} -\quad Le but de cette fonction est de permettre l'agrandissement ou la diminution en hauteur ou en largeur de la taille de la carte du jeu.\\ -\quad Dans le main du fichier maputil.c on vérifie si l'utilisateur a bien choisi une des deux set, si les informations sont correctes on lance la fonction unique \textit{setWidthHeight} avec les paramètres contenant :\\ -\begin{itemize} -\item la valeur de la hauteur ou largeur. -\item le type de la dimension (largeur ou hauteur). -\item le fichier contenant les informations de la carte. -\end{itemize} -\quad La fonction est découpé en 3 parties, la lecture et le stockage des informations du fichier map, la création de la nouvelle matrice contenant les éléments en fonction de la nouvelle dimension que l'utilisateur a donné en argument et enfin la réécriture des informations dans le fichier map.\\ -\quad Pour récupérer les informations du fichier map d'origine on utilise la fonction read et on stocke chacune des informations dans des variables ou des tableaux. La taille du tableaux contenant la chaine de caractère définissant un élément du jeu n'étant pas connu lors de son utilisation, nous avons eu à utiliser un malloc pour allouer l'espace nécessaire en fonction de valeur de l'entier contenant la taille de la chaine récupéré précédemment.\\ -\quad Une fois les informations récupérées on définit la nouvelle largeur et hauteur en fonction de la valeur placé en argument de la fonction et on initialise la nouvelle matrice en fonction de cette nouvelle donnée et on initialise la valeurs de ses cases à \textit{MAP\_OBJECT\_NONE} pour que chaque case correspondent à l'identifiant d'un block vide sur la carte. On remplit ensuite la nouvelle matrice avec les valeurs de l'ancienne, si les nouvelle dimensions sont plus petites que les anciennes certains objets peuvent être perdus.\\ -\quad On doit ensuite réécrire l'intégralité du fichier map, pour cela on commence déjà par effacer l'intégralité du contenu du fichier map d'origine avec la fonction \textit{ftruncate}, on place ensuite le curseur au début du fichier avec \textit{lseek} puis on écrit dans le fichier avec \textit{write}. On supprime enfin les allocations crées pour le tableau chaine avec une nouvelle boucle for. - -\subsection{Suppression des objets non utilisés} -\quad La fonction \textit{pruneObjects} permet de supprimer les objets qui ne sont pas présents sur la carte du jeu mais enregistrer dans le fichier map.\\ -\quad On commence d'abord par lire le fichier map et on stockent les valeurs dans des variables. Après cela un tableau de compteur est utilisé pour trouvé le nombre d'occurences de chaque objet dans la carte et donc savoir quel type d'objet est présent. On se sert ensuite d'une boucle pour déterminer les identifiants des objets présent sur la carte.\\ -La dernière partie est identique à celle de la fonction \textit{setWidthHeight} à la différence que l'on écrit dans le fichier map seulement les objets ayant l'identifiant contenue dans le tableau crée précédemment. - -\section{Gestion des temporisateurs} - - Afin de gérer des évenements dépendant du temps, nous avons une structrure de données semblable à une liste doublement chainée. Cette liste contient un évenement, le suivant, le précédent, le temps courant et le paramètre. La liste est triée chonologiquement de sorte que le premier élément soit toujours celui dont le temps d'éxecution est le plus petit. - - Les primitives mises en place sont celles nous donnant accès au premier élément de la liste ainsi que la suppression du premier élément. Nous avons opté pour un telle liste afin d'avoir comme premier élément l'événement le proche de sa fin en premier. Cela facilite le processus de suppression. Lors de l'ajout d'un objet, il est ajouté en fin de liste et la liste est ensuite triée. - - Cette liste nous permet de n'avoir à gérer que la tête de liste. Les autres éléments sont tirés en ordre croissants et chaque élément deviendra le premier à mesure que l'ancin premier élément expire. Il rest juste à gérer les calculs de temps pour de multiples objets. - -\subsection{Implémentation simple} - - L'appel à \textit{timer\_init()} en début de jeu nous permet d'allouer notre structure et de mettre en place le thread qui va réceptionner les événements. Le programme principal ne peut donc pas recevoir le signal, seul le thread le pourra. - - Lorsqu'un événement se produit, une nouvel élément de la liste est alloué. Le délai d'activation de cet événement est calculé et placé dans la structure de temps de l'élément. On ajoute également à l'élément le paramètre de l'événement. Le paramètre est ensuite ajouté à la liste et le timer est déclenché. - - Le thread se chargeant de l'éxecution du signal attend sa délivrance. Une fois le signal délivré, l'action du premier élément de la file est executé. L'élément est ensuite supprimé. Un autre timer est ensuite armé si il reste encore un élément dans la liste. - - Avec un seul objet, l'événement courant est toujours le premier de la liste. Il est donc facile de traiter cet événement puisqu'aucun calcul de temps n'a lieu, armer les temporisateurs suffit à gérer l'événement tout seul. - - \subsection{Implémentation complète} - L'implémentation complète ne marche pas comme il le faudrait, les élements s'activent dans l'ordre, mais par exemple si on a n bombes sur la carte, il faut attendre que la mèche de la nième bombe soit terminée pour que la première lance son timer d'explosion. Nous avons essayé de corriger cela en triant la file; mais nous nous sommes aperçu trop tard que notre tri n'était pas le bon pour ce problème. En plus du tri nous n'avons pas trouvé comment transmettre le bon temps restant à chaque élément. Mais donc nous avons mis en commentaires les appels à \textit{triFile}. - - Notre tri marche ainsi: - Nous commencons par récupérer depuis combien de temps le timer du premier élément est lancé, avec la fonction \textit{getitimer}, puis on compare cette valeur avec le temps de temporisation des autres éléments. Et donc si le temps du premier élément est supérieur au suivant on les inverses. - - - - - -\end{document} +\documentclass[10pt,a4paper]{article} \usepackage[utf8]{inputenc} \usepackage{color} \usepackage[francais]{babel} \usepackage{listings} \usepackage[T1]{fontenc} \usepackage{graphicx} \usepackage[export]{adjustbox} \bibliographystyle{ieeetr} \author{GAILLARD Valentin FONTENAY Clément CHERIFI Ali} \title{Rapport de projet\\Programmation système} \begin{document} \maketitle \newpage \tableofcontents \newpage \section{Sauvegarde et chargement des cartes} La principale source de réflexion ici a été de trouver une convention de stockage afin de stocker la carte avec toutes ses propriétés afin de nous simplifier au maximum les phases de d'écriture et de lecture. Nous avons donc choisi de procéder comme suivant : \begin{itemize} \item Hauteur de la carte \item Largeur de la carte \item Nombre d'objets \item Matrice de la carte (identifiant de l'objet) \end{itemize} Puis pour chaque objet : \begin{itemize} \item Taille de la chaine de caractère du nom de l'objet \item Nom de l'objet \item Caractéritiques de l'objet. \end{itemize} \subsection{Sauvegarde} La sauvegarde est pleinenement fonctionnelle. Tous les objets sont sauvegardés y compris ceux n'ayant aucune présence physique sur la carte. Il est donc possible d'utiliser tous les objets ultérieurement. Si la création du fichier de sauvegarde ne se déroule pas correctement, un message est affiché sur la sortie standard d'erreur et le code d'erreur est renvoyé à l'utilisateur. La sauvegarde débute par la largeur et la hauteur et le nombre d'objets. Ces valeurs sont inscrites directement dans le fichier via la fonction \textit{write()}. Par la suite, un tableau de taille \textit{largeur * hauteur} est créé. Un tableau de cette taille permet de stocker l'intégralité de la carte en un seul parcours et de n'effectuer qu'un seul appel bufferisé à \textit{write()}. Un tableau du nombre de caractéristiques est ensuite créé. Il permettra de façon similaire au tableau de la carte, de n'effectuer qu'un seul appel à appel à \textit{write()} pour sauvegarder toutes les caractéristiques en une seule fois dans le fichier de sauvegarde. \subsection{Chargement} Pour charger une carte, le fichier de sauvegarde est ouvert. Une vérification du bon déroulement de l'ouverture est fait. Si une erreur se produit, le code de l'erreur est affiché sur la sortie standard. La fonction commence par lire la largeur, la hauteur et le nombre d'objets. Une nouvelle carte est ensuite allouée. Une double boucle de la taille de la carte place tous les objets. A chaque itération un appel à \textit{read()} est effectué pour lire l'ID de l'objet dans la matrice et le placer sur le carte via un appel à \textit{map\_set()}. Il faut maintenant récupérer le nom de chaque objet ainsi que ses caractéritiques. Un appel à la fonction \textit{map\_object\_begin()} est effectué pour initier l'allocation des objets. Une boucle de la taille du nombre d'objets est effectuée et lit pour chaque objet la taille du nom de l'objet et extrait le nom de cet objet. Lors de cette lecture le premier objet lu dans le fichier aura l'ID 0 ce qui correspond bien à l'ordre d'enregistrement lors de la sauvegarde. Les caractéristiques des objets sont ensuite lues dans le fichier. Ces dernières sont passées en paramètre à la fonction \textit{generer\_flags()} qui se charge de générer un seul entier contenant la solidité de l'objet et les flags actif c'est-à-dire à 1. L'allocation est ensuite faite via la fonction \textit{map\_object\_add}. La sauvegarde et le chargement ont été réalisé ainsi dans le but de minimiser les appels systèmes. Cependant il ne nous a pas été possible de lire le nom du fichier à l'aide d'un seul appel système. En effet, pour les noms de fichiers de 16 caractères exactement, la lecture résultait en l'ajout de caractères aléatoires à la fin du nom de l'objet. Il a donc fallu lire caractère le nom du fichier pour s'assurer que le nom n'est pas erroné. \section{Maputil} Dans le main de maputil, on vérifie d'abord que le nombre d'arguments est d'au moins 2, puis on compare le deuxième argument aux différentes actions possibles. Et on vérifie également les erreurs possibles, comme l'ouverture du fichier map ou une erreur dans les arguments. \subsection{getwidth, height, objects, info} Chaque fonction get, se contente de se placer à la bonne position dans le fichier map et de renvoyer la valeur de la fonction \textit{lireEntierPositif}, qui appel \textit{read} et qui vérifie si il y a une erreur. Puis on affiche, tout en testant le retour de la fonction get. \subsection{Remplacement des objets d'une carte} \subsubsection{Fonction de verification des arguments} Avant d'appeler la fonction setObjects, on va d'abord vérifier les arguments avec la fonction \textit{verificationArgumentsSetObjects}. Dans cette fonction on vérifie d'abord si le nombre d'arguments est bon, donc pour ça on vérifie d'abord si c'est un multiple 6, puisque l'utilisateur doit envoyer le nom de l'objet suivie des caractéristiques, ce qui fait plusieurs paquets de 6, de plus il faut vérifier que le nombre d'objets actuellement sur la carte est inférieur ou égale au nombre d'objets que l'utilisateur passe en paramètre. Si la taille des arguments n'est pas bonne on renvoie ERRTAILLE Puis on vérifie les noms des arguments, pour ça, on vérifie si c'est bien un chiffre après le nom de l'image (le chiffre est la valeur de frame), donc pour ça, dans la boucle du parcours des arguments, si i est un multiple de 6 alors c'est que c'est une image et donc l'élément suivant doit être un chiffre, si ce n'est pas un chiffre on renvoie ERRNOM. Ensuite on vérifie les arguments suivants, pour ça on utilise un tableau qui contient les noms "solid", "air", "collectible" ... et donc on compare les arguments avec les éléments du tableau, si on ne retrouve pas l'argument dans le tableau on renvoie ERRNOM. \subsubsection{Fonction setobjects} L'idée globale de la fonction c'est de supprimer dans le fichier tout sauf la hauteur et la largeur, pour pouvoir changer le nombre d'objet, et écrire la nouvelle liste. Pour ça on commence par se placer dans le fichier, au début de la matrice de la carte, puis on sauvegarde la matrice en lisant ligne par ligne (puisque on sait qu'une ligne est de taille largeur*sizeof(int) octets). Ensuite on supprime le contenu du fichier sans supprimer les 2*sizeof(int) premier octets (qui sont la largeur et la hauteur), puis on écrit à la fin du fichier map la nouvelle valeur du nombre d'objet et la matrice. Enfin on écrit la nouvelle liste, pour ça on a une boucle qui va de 0 au nombre d'arguments, si i est un multiple de 6, alors c'est qu'on a une chaîne de caractère à écrire, donc comme notre convention l'exige, on doit écrire, dans le fichier map, la taille de la chaine. Donc on écrit la taille de la chaine, puis la chaine, puis le frame. On écrit le frame directement ici car il est traité différemment des autres arguments. Pour les autres arguments, on parcourt le tableau des caractéristiques, si l'argument est à l'index 0, 1 ou 2 on écrit 0, 1 ou 2 puisque c'est soit "solid" soit "semi-solid" soit "air". Si l'argument est à l'index 3,4 ou 5 on écrit 1 puisque c'est "collectible", "destructible" ou "generator", et sinon on écrit 0. \subsection{Modification de la taille de la carte} \quad Le but de cette fonction est de permettre l'agrandissement ou la diminution en hauteur ou en largeur de la taille de la carte du jeu.\\ \quad Dans le main du fichier maputil.c on vérifie si l'utilisateur a bien choisi une des deux set, si les informations sont correctes on lance la fonction unique \textit{setWidthHeight} avec les paramètres contenant :\\ \begin{itemize} \item la valeur de la hauteur ou largeur. \item le type de la dimension (largeur ou hauteur). \item le fichier contenant les informations de la carte. \end{itemize} \quad La fonction est découpé en 3 parties, la lecture et le stockage des informations du fichier map, la création de la nouvelle matrice contenant les éléments en fonction de la nouvelle dimension que l'utilisateur a donnée en argument et enfin la réécriture des informations dans le fichier map.\\ \quad Pour récupérer les informations du fichier map d'origine on utilise la fonction read et on stocke chacune des informations dans des variables ou des tableaux. La taille du tableau contenant la chaine de caractère définissant un élément du jeu n'étant pas connu lors de son utilisation, nous avons eu à utiliser un malloc pour allouer l'espace nécessaire en fonction de valeur de l'entier contenant la taille de la chaine récupérée précédemment.\\ \quad Une fois les informations récupérées on définit la nouvelle largeur et hauteur en fonction de la valeur placée en argument de la fonction et on initialise la nouvelle matrice en fonction de cette nouvelle donnée et on initialise la valeur de ses cases à \textit{MAP\_OBJECT\_NONE} pour que chaque case corresponde à l'identifiant d'un block vide sur la carte. On remplit ensuite la nouvelle matrice avec les valeurs de l'ancienne, si les nouvelles dimensions sont plus petites que les anciennes certains objets peuvent être perdus.\\ \quad On doit ensuite réécrire l'intégralité du fichier map, pour cela on commence déjà par effacer l'intégralité du contenu du fichier map d'origine avec la fonction \textit{ftruncate}, on place ensuite le curseur au début du fichier avec \textit{lseek} puis on écrit dans le fichier avec \textit{write}. On supprime enfin les allocations crées pour le tableau chaine avec une nouvelle boucle for. \subsection{Suppression des objets non utilisés} \quad La fonction \textit{pruneObjects} permet de supprimer les objets qui ne sont pas présents sur la carte du jeu mais enregistrer dans le fichier map.\\ \quad On commence d'abord par lire le fichier map et on stocke les valeurs dans des variables. Après cela un tableau de compteur est utilisé pour trouvé le nombre d'occurrences de chaque objet dans la carte et donc savoir quel type d'objet est présent. On se sert ensuite d'une boucle pour déterminer les identifiants des objets présents sur la carte.\\ La dernière partie est identique à celle de la fonction \textit{setWidthHeight} à la différence que l'on écrit dans le fichier map seulement les objets ayant l'identifiant contenue dans le tableau crée précédemment. \section{Gestion des temporisateurs} Afin de gérer des évenements dépendant du temps, nous avons une structure de données semblable à une liste doublement chainée. Cette liste contient un évènement, le suivant, le précédent, le temps courant et le paramètre. La liste est triée chronologiquement de sorte que le premier élément soit toujours celui dont le temps d'exécution est le plus petit. Les primitives mises en place sont celles nous donnant accès au premier élément de la liste ainsi que la suppression du premier élément. Nous avons opté pour un telle liste afin d'avoir comme premier élément l'événement le proche de sa fin en premier. Cela facilite le processus de suppression. Lors de l'ajout d'un objet, il est ajouté en fin de liste et la liste est ensuite triée. Cette liste nous permet de n'avoir à gérer que la tête de liste. Les autres éléments sont tirés en ordre croissants et chaque élément deviendra le premier à mesure que l'ancien premier élément expire. Il reste juste à gérer les calculs de temps pour de multiples objets. \subsection{Implémentation simple} L'appel à \textit{timer\_init()} en début de jeu nous permet d'allouer notre structure et de mettre en place le thread qui va réceptionner les événements. Le programme principal ne peut donc pas recevoir le signal, seul le thread le pourra. Lorsqu'un événement se produit, un nouvel élément de la liste est alloué. Le délai d'activation de cet événement est calculé et placé dans la structure de temps de l'élément. On ajoute également à l'élément le paramètre de l'événement. Le paramètre est ensuite ajouté à la liste et le timer est déclenché. Le thread se chargeant de l'éxecution du signal attend sa délivrance. Une fois le signal délivré, l'action du premier élément de la file est executé. L'élément est ensuite supprimé. Un autre timer est ensuite armé s’il reste encore un élément dans la liste. Avec un seul objet, l'événement courant est toujours le premier de la liste. Il est donc facile de traiter cet événement puisqu'aucun calcul de temps n'a lieu, armer les temporisateurs suffit à gérer l'événement tout seul. \subsection{Implémentation complète} L'implémentation complète ne marche pas comme il le faudrait, les éléments s'activent dans l'ordre, mais par exemple si on a n bombes sur la carte, il faut attendre que la mèche de la nième bombe soit terminée pour que la première lance son timer d'explosion. Nous avons essayé de corriger cela en triant la file ; mais nous nous sommes aperçu trop tard que notre tri n'était pas le bon pour ce problème. En plus du tri nous n'avons pas trouvé comment transmettre le bon temps restant à chaque élément. Mais donc nous avons mis en commentaires les appels à \textit{triFile}. Notre tri marche ainsi : Nous commencons par récupérer depuis combien de temps le timer du premier élément est lancé, avec la fonction \textit{getitimer}, puis on compare cette valeur avec le temps de temporisation des autres éléments. Et donc si le temps du premier élément est supérieur au suivant on les inverses. \end{document} \ No newline at end of file