Automate.h 5.43 KB
Newer Older
1
2
3
4
#ifndef _AUTOMATE_H
#define _AUTOMATE_H

#include <memory>
5
6
#include <Fonction.h>
#include <voisinage.h>
7
#include <QObject>
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
8
#include <autocell.h>
9

10
11
12
/// La classe automate se charge de gérer les informations d'un automate (fonction de transition, règle de voisinage, réseau, ...) et joue également le rôle de simulateur
///
/// Cette classe est un singletion est l'objet unique n'est disponible qu'avec la méthode statique getInstance(). Ainsi, il est impossible de créer des objets de cette classe. La classe agrège une fonction et une règle de voisinage dont l'utilisateur a la responsabilité. Il est également possible de laisser l'automate simuler avec un délai réglable.
13
14
15
class Automate {
	private:
		static std::unique_ptr<Automate> instance;
16
		std::string title;
17
		unsigned int delai;
18
19
		Fonction* fonction;
		RegleVoisinage* regleVoisinage;
20
21
22
23
		std::list<Reseau> buffer;
		std::list<Reseau>::iterator itBuffer;
		unsigned int h;
		unsigned int l;
24
		Reseau reseauInit;
25
26
27
		int year;
		std::string author;
		std::string desc;
28
		EnsembleEtat ensemble;
29

30
		Automate(): title(""), delai(500), fonction(nullptr), regleVoisinage(nullptr), itBuffer(buffer.begin()), h(0), l(0), reseauInit(Reseau(0, 0)), year(2000), author("Anonym"), desc("") { timer.automate = this; }
31
32
		Automate(const Automate& a) = delete;
		Automate& operator=(const Automate& a) = delete;
33
34
35
36
		class Timer: public QObject {
			private:
				int timerID;
				Automate *automate;
37
				Timer(): timerID(0) {}
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
				~Timer() { destroy(); }

			protected:
				void timerEvent(QTimerEvent *event) { automate->step(); }

			public:
				void install(const int delai) {
					if(timerID != 0)
						destroy();

					timerID = startTimer(delai);
					if(timerID == 0)
						throw "Unable to install timer";
				}
				void destroy() {
					if(timerID != 0)
						killTimer(timerID);
				}

			friend class Automate;
		};
59
		Timer timer;
60
61

	public:
62
		~Automate() = default;
63
		/// récupérer une référence sur l'instance unique du singleton Automate
64
65
66
67
68
69
70
		static Automate& getInstance() {
			if(instance == nullptr) {
				instance.reset(new Automate);
			}

			return *instance;
		}
71
		/// Définir la fonction de transition de l'automate, le cycle de vie de la focntion est géré par l'utilisateur
72
		void setFonction(Fonction& f) { fonction = &f; }
73
		/// Récupérer la fonction de transition
Romain De Laage De Bellefaye's avatar
Revert    
Romain De Laage De Bellefaye committed
74
		const Fonction& getFonction() const { return *fonction; }
75
		/// Définir une règle de voisinage, le cycle de vie de la règle est géré par l'utilisateur
76
		void setRegleVoisinage(RegleVoisinage& r) { regleVoisinage = &r; }
77
		/// Récupérer la règle de voisinage
Romain De Laage De Bellefaye's avatar
Revert    
Romain De Laage De Bellefaye committed
78
		const RegleVoisinage& getRegleVoisinage() const { return *regleVoisinage; }
79
		/// Définir le délai entre 2 itérations de l'automate en mode Timer
80
		void setDelai(const unsigned int d) { delai = d; }
81

82
83
84
85
		/// Accesseur ensemble états
		EnsembleEtat& getEnsemble() { return ensemble; }
		/// Accesseur ensemble états
		const EnsembleEtat& getEnsemble() const { return ensemble; }
86
87
88
89
90
91
		/// définir la hauteur de la grille
		void setHauteur(unsigned int hauteur) { h = hauteur; }
		/// définir la largheur de la grille
		void setLargeur(unsigned int largeur) { l = largeur; }

		/// Se placer sur l'état précédent si disponible
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
92
93
94
95
96
		void previous() {
			if(itBuffer!=buffer.begin())
				itBuffer--;
			AutoCell::getInstance().afficherGrille(&*itBuffer);
		}
97
		/// Se placer sur l'état suivant si disponible
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
98
		void next() { if(itBuffer!=(--buffer.end())) itBuffer++; }
99
		/// On vide la buffer et on l'initialise avec une première grille
100
		void reset() { buffer.clear(); buffer.push_back(reseauInit); }
101
102
103

		/// Se placer sur l'état suivant du buffer et le calculer s'il n'y en a plus de disponible
		void step() {
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
104
			if(itBuffer==(--buffer.end()))
105
106
				nextTimer();
			itBuffer++;
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
107
108
			AutoCell::getInstance().afficherGrille(&*itBuffer);
			std::cout << buffer.size() << std::endl;
109
110
111
112
113
114
		}
		/// Execution multiple de la méthode step
		void run(int n) {
			for(int i=0;i<n;i++)
				step();
		}
115

116
		/// Calcule d'une nouvelle étape à partir de la dernière
Leon Do Castelo's avatar
Leon Do Castelo committed
117
		void nextTimer();
118

119
120
121
122
		/// Démarre l'exécution automatique de l'automate avec une vitesse selon l'attribut delai s'il n'est pas déjà en route
		void start() { timer.install(delai); }
		/// Supprime le timer s'il est en route
		void pause() { timer.destroy(); }
Leon Do Castelo's avatar
Leon Do Castelo committed
123

124
		/// Récupérer un réseau correspondant à l'état courant de l'automate
Leon Do Castelo's avatar
Leon Do Castelo committed
125
		Reseau getReseauCourant() { return *itBuffer; }
126

127
		/// initialiser le buffer s'il est vide avec un réseau
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
128
		void initialiserBuffer() { buffer.clear(); buffer.push_front(reseauInit); }
129

130
		/// Définir le réseau initial de l'automate
Romain De Laage De Bellefaye's avatar
Romain De Laage De Bellefaye committed
131
		void setReseauInit(Reseau& r) { reseauInit = r; h = r.getHauteur(); l = r.getLargeur(); }
132
		/// Récupérer le réseau initial de l'automate
133
		const Reseau& getReseauInit() const { return reseauInit; }
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
		/// Récupérer le nom de l'automate
		std::string getTitle() const { return title; }
		/// Redéfinir le nom de l'automate
		void setTitle(const std::string& t) { title = t; }
		/// Récupérer le nom de l'auteur
		std::string getAuthor() const { return author; }
		/// Redéfinir le nom de l'auteur
		void setAuthor(const std::string& a) { author = a; }
		/// Récupérer la description
		std::string getDesc() const { return desc; }
		/// Redéfinir la description
		void setDesc(const std::string& d) { desc = d; }
		/// Récupérer l'année
		int getYear() const { return year; }
		/// Redéfinir le nom de l'automate
		void setYear(const int y) { year = y; }
Leon Do Castelo's avatar
Leon Do Castelo committed
150
151

		void reinitialiserAutomate();
152
153
154
};

#endif