Compare commits
54 commits
Author | SHA1 | Date | |
---|---|---|---|
efa28a3c30 | |||
669dd4bec3 | |||
07ae3f42f1 | |||
538fc053eb | |||
5349d5e89a | |||
99c8809d6a | |||
1182b1307a | |||
3373084c62 | |||
ebd74a8088 | |||
fc0c8e3a71 | |||
074b5adb19 | |||
5bc9979c90 | |||
470aa9a45c | |||
7ad0f154d2 | |||
b4495026cb | |||
c22771f587 | |||
7d8750f128 | |||
4c37ab4ef4 | |||
8a334d46be | |||
e8ff85b383 | |||
1ee2bc5603 | |||
af2646e46e | |||
95765193a8 | |||
c55907adce | |||
d107592ae3 | |||
74ad46d137 | |||
f4782634ce | |||
929187436b | |||
47ee545c0a | |||
5631318c73 | |||
095419a1f8 | |||
9ebf1af816 | |||
8bb2629fa8 | |||
62091bf314 | |||
510b8680e8 | |||
7b2726c5d2 | |||
8d3b9973a6 | |||
616d08822e | |||
c4927de1eb | |||
dd0c3d6bd5 | |||
9173dfc39a | |||
428d594e7b | |||
3232e8ea7f | |||
f098d1977e | |||
dee0cde24b | |||
8d887ab28e | |||
0b06f924f3 | |||
7cf3097046 | |||
9f66c43e1e | |||
1ac596769a | |||
4564e76aa3 | |||
7f55fb9a5e | |||
|
3b21fdbe9b | ||
|
368c88423d |
22 changed files with 862 additions and 57 deletions
26
Makefile
26
Makefile
|
@ -9,6 +9,11 @@ OBJETS = $(patsubst %.cpp,%.cpp.o,$(notdir $(SOURCES)))
|
||||||
EXE = tp5
|
EXE = tp5
|
||||||
EXE_EXT = out
|
EXE_EXT = out
|
||||||
|
|
||||||
|
PDF_LOCATION = report
|
||||||
|
PDF_FILE = explications.pdf
|
||||||
|
|
||||||
|
ARCHIVE = $(EXE).tar
|
||||||
|
|
||||||
%.cpp.o: src/%.cpp
|
%.cpp.o: src/%.cpp
|
||||||
$(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS)
|
$(CXX) -c -o $@ $< $(CXXFLAGS) $(DEVFLAGS)
|
||||||
|
|
||||||
|
@ -25,10 +30,19 @@ compilation: $(OBJETS)
|
||||||
all:
|
all:
|
||||||
main
|
main
|
||||||
|
|
||||||
clean:
|
pdf-make:
|
||||||
$(RM) $(OBJETS) $(EXE).$(EXE_EXT)
|
cd report && \
|
||||||
|
$(MAKE)
|
||||||
|
|
||||||
archive:
|
pdf-clean:
|
||||||
$(TAR) "$(EXE).tar" $(SOURCES) $(wildcard includes/*.hpp) Makefile \
|
cd report && \
|
||||||
binome.txt
|
$(MAKE) clean
|
||||||
# diagramme_uml.* explications.pdf
|
|
||||||
|
clean: pdf-clean
|
||||||
|
-$(RM) $(OBJETS) "$(EXE).$(EXE_EXT)" "$(ARCHIVE)"
|
||||||
|
|
||||||
|
archive: pdf-make
|
||||||
|
cp "$(PDF_LOCATION)/$(PDF_FILE)" .
|
||||||
|
$(TAR) "$(ARCHIVE)" $(SOURCES) $(wildcard includes/*.hpp) Makefile \
|
||||||
|
binome.txt "$(PDF_FILE)" diagramme_uml.png
|
||||||
|
$(RM) "$(PDF_FILE)"
|
||||||
|
|
108
TODO.md
108
TODO.md
|
@ -2,7 +2,107 @@
|
||||||
|
|
||||||
TODO avant rendu :
|
TODO avant rendu :
|
||||||
|
|
||||||
- [ ] "Vous remettrez en plus de votre code une page rédigée montrant que vous
|
- [x] Page rédigée montrant que l'on a tenu compte des problématiques de copies et sécurité (private/public) en expliquant en français non technique comment vous les avez traitées (`x` à pas accès à `y`)
|
||||||
avez tenu compte de certaines problématiques de copies/sécurité etc en
|
- [x] Écrire des tests pour montrer que ça fonctionne
|
||||||
expliquant en français non technique comment vous les avez traitées"
|
|
||||||
- [ ] Écrire un "écrirez un petit jeu de test, clair"
|
## Notes
|
||||||
|
|
||||||
|
- [x] Toute classe doit être surchargée avec `<<`
|
||||||
|
- [x] Gestion satisfaisante des copies, affectation, destruction
|
||||||
|
|
||||||
|
### Projet
|
||||||
|
|
||||||
|
- [x] Ne dois **pas** être instanciée directement
|
||||||
|
- [x] Se décompose en tâches (vecteur de tâches)
|
||||||
|
- [x] Durée totale dépend du degré de parallélisme que le gestionnaire décide
|
||||||
|
- [x] Deux natures de projets dépendantent de `Projet`
|
||||||
|
- En cours d'élaboration (`ProtoProjet`)
|
||||||
|
- En cours d'exécution (`RunProjet`)
|
||||||
|
- [x] Peut être vu comme un graphe acyclique (utilisation de `vector`) des tâches
|
||||||
|
- Les sommets sont des tâches
|
||||||
|
- Une tâche `fin` servira de source au graphe
|
||||||
|
- Garder un ordre topologique (triée par dépendances)
|
||||||
|
- [x] Mère des deux classes `ProtoProjet` et `RunProjet`
|
||||||
|
- [x] Méthodes utiles qu'à ses sous-classes
|
||||||
|
- Méthodes (cf. le PDF du prof)
|
||||||
|
- [x] `pick_two_random_tasks()`
|
||||||
|
- [x] `contains()`
|
||||||
|
- [x] Surcharge de `<<` : afficher toutes les tâches
|
||||||
|
- [x] `consult_tasks()`
|
||||||
|
- [x] `topologicalSort()`
|
||||||
|
|
||||||
|
#### ProtoProjet
|
||||||
|
|
||||||
|
- Permet de pouvoir ajouter de nouvelles tâches
|
||||||
|
- Ne peut pas progresser (a.k.a ne peut pas lancer les tâches)
|
||||||
|
- Champs
|
||||||
|
- [x] Tâche `début`
|
||||||
|
- [x] Tâche `fin`
|
||||||
|
- Méthodes (cf. le PDF du prof) **⇒ Tout ça avec l'ordre topologique**
|
||||||
|
|
||||||
|
- Pas de méthode d'ajout d'un objet `Tache`
|
||||||
|
- [x] `bool ajoute(nom, durée)` : sélectionne au hasard 2 tâches déjà
|
||||||
|
enregistrer et **ajoute** la nouvelle tâche entres-elles
|
||||||
|
- [x] `bool ajoute(nom, durée, id)` : **ajoute** une tâche qui doit se réaliser
|
||||||
|
**après** la tâche qui à l'`id` correspondant (et avant la tâche finale)
|
||||||
|
- [x] `bool ajoute(nom, durée, id1, id2)` : **ajoute** une tâche entre les 2 tâches
|
||||||
|
qui ont l'identifiant `id1` et `id2`
|
||||||
|
- [x] Surcharge de `<<`
|
||||||
|
|
||||||
|
#### RunProjet
|
||||||
|
|
||||||
|
- [x] Construit uniquement via un `ProtoProjet`
|
||||||
|
- [x] Avance vers sa conclusion en prenant en compte des tâches ponctuelles
|
||||||
|
- [x] Vide le contenu d'un `ProtoProjet` pour se construire, rendre les tâches "read-only"
|
||||||
|
- Méthodes (cf. le PDF du prof)
|
||||||
|
- [x] `run(id)` : Lance une tâche
|
||||||
|
- [x] `run(sequence_taches)` : Exécute une liste de tâches dans l'ordre donnée
|
||||||
|
- [x] Surcharge de `<<`
|
||||||
|
|
||||||
|
### Concepteur
|
||||||
|
|
||||||
|
L'utilisateur final en somme
|
||||||
|
|
||||||
|
- [x] Interagis avec un `ProtoProjet` pour y mettre des tâches
|
||||||
|
|
||||||
|
### Gestionnaire
|
||||||
|
|
||||||
|
- [x] Étudie/Analyse des `RunProjet`
|
||||||
|
|
||||||
|
- [x] Recommande des ordonnancements pour la suite des exécutions à venir
|
||||||
|
(ordre d'exécutions des tâches)
|
||||||
|
- [x] Calcule la durée totale restante d'un projet
|
||||||
|
- [x] Demande un salaire pour travailler
|
||||||
|
- Méthodes
|
||||||
|
- [x] Surcharge de `<<` : Affiche une facturation
|
||||||
|
- [x] `pair<vector<int>, int> avis(const RunProjet &)` : renvoie l'ordonnancement
|
||||||
|
et la durée totale restante
|
||||||
|
|
||||||
|
#### Consultant
|
||||||
|
|
||||||
|
- [x] Calcule **sans** parallélisation des tâches
|
||||||
|
|
||||||
|
#### Expert
|
||||||
|
|
||||||
|
- [x] Calcule **avec** parallélisation des tâches
|
||||||
|
|
||||||
|
### Tâches
|
||||||
|
|
||||||
|
- [x] Dépendantes, entre-elles
|
||||||
|
- [x] Durée exacte, fixe, propre à elle-même
|
||||||
|
- [x] Ne peut être lancé que si toutes les dépendances sont réalisées
|
||||||
|
- [x] Dépendances = autres tâches
|
||||||
|
- [x] Élément atomique (final)
|
||||||
|
- Champs
|
||||||
|
- [x] Nom
|
||||||
|
- [x] Numéro unique
|
||||||
|
- [x] État (réalisée/en attente)
|
||||||
|
- Réalisée → En attente : **interdit**
|
||||||
|
- En attente → Réalisée : **autorisé**
|
||||||
|
- [x] Vision locale des dépendances (`vector`)
|
||||||
|
- Méthodes (cf. le PDF du prof)
|
||||||
|
- [x] `bool realise()`
|
||||||
|
- [x] `bool depends_from(Tache & x)`
|
||||||
|
- [x] `bool ajouteDependance(Tache & x)`
|
||||||
|
- [x] `int dureeParal()`
|
||||||
|
- [x] Surcharge de `<<`
|
||||||
|
|
70
diagramme_uml.md
Normal file
70
diagramme_uml.md
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<!-- https://mermaid.live -->
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
%%{init: {'theme': 'neutral'}}%%
|
||||||
|
|
||||||
|
classDiagram
|
||||||
|
%% Classes
|
||||||
|
class Tache {
|
||||||
|
-static_counter_id
|
||||||
|
-nom
|
||||||
|
-duree_total
|
||||||
|
-etat
|
||||||
|
-dependances
|
||||||
|
+unique_id
|
||||||
|
+visite
|
||||||
|
|
||||||
|
+realise()
|
||||||
|
+depends_from(tache)
|
||||||
|
+ajouteDependance(tache)
|
||||||
|
+dureeParal()
|
||||||
|
+PP_postfixe(liste_tache)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Projet {
|
||||||
|
#tache_fin
|
||||||
|
#tache_debut
|
||||||
|
#taches
|
||||||
|
-cleanMarks()*
|
||||||
|
#pick_two_random_tasks()
|
||||||
|
#contains(id ou name)
|
||||||
|
#topologicalSort()
|
||||||
|
+consult_tasks()
|
||||||
|
}
|
||||||
|
class ProtoProjet {
|
||||||
|
-cleanMarks()
|
||||||
|
+ajoute(nom, duree)
|
||||||
|
+ajoute(nom, duree, id)
|
||||||
|
+ajoute(nom, duree, id1, id2)
|
||||||
|
}
|
||||||
|
class RunProjet {
|
||||||
|
+run(id ou liste_tache)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Gestionnaire {
|
||||||
|
-salaire
|
||||||
|
+payer(argent)
|
||||||
|
+avis(RunProjet)*
|
||||||
|
}
|
||||||
|
class Consultant {
|
||||||
|
+avis(RunProjet)
|
||||||
|
}
|
||||||
|
class Expert {
|
||||||
|
+avis(RunProjet)
|
||||||
|
}
|
||||||
|
|
||||||
|
%% Héritage
|
||||||
|
Projet <|-- ProtoProjet
|
||||||
|
ProtoProjet <|-- RunProjet
|
||||||
|
|
||||||
|
Gestionnaire <|-- Consultant
|
||||||
|
Gestionnaire <|-- Expert
|
||||||
|
|
||||||
|
%% Friends (Dependency)
|
||||||
|
%% pour : consult_tasks()
|
||||||
|
Projet ..> Consultant
|
||||||
|
Projet ..> Expert
|
||||||
|
|
||||||
|
%% Composition
|
||||||
|
Tache --* Projet
|
||||||
|
```
|
BIN
diagramme_uml.png
Normal file
BIN
diagramme_uml.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -1,9 +1,9 @@
|
||||||
#ifndef TP5_CONSULTANT_HPP
|
#ifndef TP5_CONSULTANT_HPP
|
||||||
#define TP5_CONSULTANT_HPP 1
|
#define TP5_CONSULTANT_HPP 1
|
||||||
|
|
||||||
#include <iostream>
|
#include "Gestionnaire.hpp"
|
||||||
|
|
||||||
class Consultant {
|
class Consultant final : public Gestionnaire {
|
||||||
friend std::ostream &operator<<(std::ostream &, const Consultant &);
|
friend std::ostream &operator<<(std::ostream &, const Consultant &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -12,6 +12,8 @@ public:
|
||||||
|
|
||||||
Consultant(const Consultant &); // copy constructor
|
Consultant(const Consultant &); // copy constructor
|
||||||
const Consultant &operator=(const Consultant &); // copy assignement
|
const Consultant &operator=(const Consultant &); // copy assignement
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef TP5_EXPERT_HPP
|
#ifndef TP5_EXPERT_HPP
|
||||||
#define TP5_EXPERT_HPP 1
|
#define TP5_EXPERT_HPP 1
|
||||||
|
|
||||||
#include <iostream>
|
#include "Gestionnaire.hpp"
|
||||||
|
|
||||||
class Expert {
|
class Expert final : public Gestionnaire {
|
||||||
friend std::ostream &operator<<(std::ostream &, const Expert &);
|
friend std::ostream &operator<<(std::ostream &, const Expert &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -12,6 +12,8 @@ public:
|
||||||
|
|
||||||
Expert(const Expert &); // copy constructor
|
Expert(const Expert &); // copy constructor
|
||||||
const Expert &operator=(const Expert &); // copy assignement
|
const Expert &operator=(const Expert &); // copy assignement
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, int> avis(const RunProjet &projet) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,17 +1,37 @@
|
||||||
#ifndef TP5_GESTIONNAIRE_HPP
|
#ifndef TP5_GESTIONNAIRE_HPP
|
||||||
#define TP5_GESTIONNAIRE_HPP 1
|
#define TP5_GESTIONNAIRE_HPP 1
|
||||||
|
|
||||||
#include <iostream>
|
#include "RunProjet.hpp"
|
||||||
|
|
||||||
class Gestionnaire {
|
class Gestionnaire {
|
||||||
|
int salaire_attendu;
|
||||||
|
int salaire_recu;
|
||||||
|
|
||||||
|
// Renvoie le reste à payer pour donner une expertise
|
||||||
|
int reste_a_payer() const;
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &, const Gestionnaire &);
|
friend std::ostream &operator<<(std::ostream &, const Gestionnaire &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Auxiliaire pour simplifier l'affichage d'un projet
|
||||||
|
std::ostream &print(std::ostream &) const;
|
||||||
|
|
||||||
|
// Vrai si Gestionnaire à été payé.e
|
||||||
|
bool payer() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gestionnaire(); // constructor
|
Gestionnaire(); // constructor
|
||||||
virtual ~Gestionnaire(); // destructor
|
virtual ~Gestionnaire(); // destructor
|
||||||
|
|
||||||
Gestionnaire(const Gestionnaire &); // copy constructor
|
Gestionnaire(const Gestionnaire &); // copy constructor
|
||||||
const Gestionnaire &operator=(const Gestionnaire &); // copy assignement
|
const Gestionnaire &operator=(const Gestionnaire &); // copy assignement
|
||||||
|
|
||||||
|
// Paye Gestionnaire, renvoie le montant restant à payer
|
||||||
|
int payer(const int argent);
|
||||||
|
|
||||||
|
// Renvoie l'ordonnancement et la durée totale restante
|
||||||
|
// Renvoie une liste vide et une durée totale -1 si pas payé.e
|
||||||
|
virtual std::pair<std::vector<int>, int> avis(const RunProjet &) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,17 +1,58 @@
|
||||||
#ifndef TP5_PROJET_HPP
|
#ifndef TP5_PROJET_HPP
|
||||||
#define TP5_PROJET_HPP 1
|
#define TP5_PROJET_HPP 1
|
||||||
|
|
||||||
#include <iostream>
|
#include "Tache.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
struct RunProjet;
|
||||||
|
|
||||||
class Projet {
|
class Projet {
|
||||||
friend std::ostream &operator<<(std::ostream &, const Projet &);
|
// Auxilliaire pour simplifier les copies
|
||||||
|
void _copy(const Projet &);
|
||||||
|
|
||||||
|
// Auxiliiaire pour simplifier la libération de mémoire des tâches
|
||||||
|
void free_taches();
|
||||||
|
|
||||||
|
// Remet tous les marquages à leur valeur initiale
|
||||||
|
virtual void cleanMarks() const = 0;
|
||||||
|
|
||||||
|
friend std::ostream &operator<<(std::ostream &, const Projet &);
|
||||||
|
friend RunProjet;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Tache
|
||||||
|
// Source du graphe aka la dernière à être exécutée
|
||||||
|
*fin,
|
||||||
|
|
||||||
|
// Première tâche qui sera exécutée
|
||||||
|
*debut;
|
||||||
|
|
||||||
public:
|
|
||||||
Projet(); // constructor
|
Projet(); // constructor
|
||||||
virtual ~Projet(); // destructor
|
virtual ~Projet(); // destructor
|
||||||
|
|
||||||
Projet(const Projet &); // copy constructor
|
Projet(const Projet &); // copy constructor
|
||||||
const Projet &operator=(const Projet &); // copy assignement
|
const Projet &operator=(const Projet &); // copy assignement
|
||||||
|
|
||||||
|
// Graphe acyclique
|
||||||
|
std::vector<Tache *> taches;
|
||||||
|
|
||||||
|
// Auxiliaire pour simplifier l'affichage d'un projet
|
||||||
|
std::ostream &print(std::ostream &) const;
|
||||||
|
|
||||||
|
// Retourne une paire d'indentifiants de tâches au hasard
|
||||||
|
const std::pair<const int, const int> pick_two_random_tasks() const;
|
||||||
|
|
||||||
|
// Indique pour une tâche si elle fait partie du projet
|
||||||
|
Tache *contains(const int id) const;
|
||||||
|
Tache *contains(const std::string name) const;
|
||||||
|
|
||||||
|
// Corrige les éventuelles anomalies du vector de tâches
|
||||||
|
void topologicalSort();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Donne une version du vecteur de tâches non modifiable
|
||||||
|
const std::vector<const Tache *> consult_tasks() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "Projet.hpp"
|
#include "Projet.hpp"
|
||||||
|
|
||||||
class ProtoProjet : public Projet {
|
class ProtoProjet : public Projet {
|
||||||
|
void cleanMarks() const;
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &, const ProtoProjet &);
|
friend std::ostream &operator<<(std::ostream &, const ProtoProjet &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -12,6 +14,18 @@ public:
|
||||||
|
|
||||||
ProtoProjet(const ProtoProjet &); // copy constructor
|
ProtoProjet(const ProtoProjet &); // copy constructor
|
||||||
const ProtoProjet &operator=(const ProtoProjet &); // copy assignement
|
const ProtoProjet &operator=(const ProtoProjet &); // copy assignement
|
||||||
|
|
||||||
|
// Insère une nouvelle tâche en la plaçant entre deux tâches au hasard
|
||||||
|
bool ajoute(const std::string nom, const int duree);
|
||||||
|
|
||||||
|
// Insère une nouvelle tâche en la plaçant après la tâche avec l'ID
|
||||||
|
// renseignée et avant la tâche finale, en créant une dépendance
|
||||||
|
bool ajoute(const std::string nom, const int duree, const int id);
|
||||||
|
|
||||||
|
// Insère une nouvelle tâche en la plaçant entre les deux tâches renseignée
|
||||||
|
// via ID
|
||||||
|
bool ajoute(const std::string nom, const int duree, const int id1,
|
||||||
|
const int id2);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,15 +3,29 @@
|
||||||
|
|
||||||
#include "ProtoProjet.hpp"
|
#include "ProtoProjet.hpp"
|
||||||
|
|
||||||
class RunProjet : public ProtoProjet {
|
struct Consultant;
|
||||||
|
struct Expert;
|
||||||
|
|
||||||
|
class RunProjet final : protected ProtoProjet {
|
||||||
friend std::ostream &operator<<(std::ostream &, const RunProjet &);
|
friend std::ostream &operator<<(std::ostream &, const RunProjet &);
|
||||||
|
|
||||||
|
// Ami pour pouvoir consulter les tâches
|
||||||
|
friend Consultant;
|
||||||
|
friend Expert;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RunProjet(); // constructor
|
RunProjet() = delete; // remove default constructor
|
||||||
|
RunProjet(ProtoProjet &); // constructor
|
||||||
virtual ~RunProjet(); // destructor
|
virtual ~RunProjet(); // destructor
|
||||||
|
|
||||||
RunProjet(const RunProjet &); // copy constructor
|
RunProjet(const RunProjet &); // copy constructor
|
||||||
const RunProjet &operator=(const RunProjet &); // copy assignement
|
const RunProjet &operator=(const RunProjet &); // copy assignement
|
||||||
|
|
||||||
|
// Lance une tâche
|
||||||
|
bool run(const int id) const;
|
||||||
|
|
||||||
|
// Exécute une liste de tâches dans l'ordre donnée
|
||||||
|
void run(const std::vector<const Tache *> sequence_taches) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Tache {
|
class Tache final {
|
||||||
// Compteur global pour les IDs
|
// Compteur global pour les IDs
|
||||||
static int counter_id;
|
static int counter_id;
|
||||||
|
|
||||||
|
@ -12,9 +12,8 @@ class Tache {
|
||||||
enum Etat { EnAttente, Realisee };
|
enum Etat { EnAttente, Realisee };
|
||||||
friend std::ostream &operator<<(std::ostream &, const Etat &);
|
friend std::ostream &operator<<(std::ostream &, const Etat &);
|
||||||
|
|
||||||
// ID unique de la tâche
|
// Nom de la tâche
|
||||||
const int unique_id;
|
std::string name;
|
||||||
|
|
||||||
// Durée totale pour faire la tâche
|
// Durée totale pour faire la tâche
|
||||||
int duree_total;
|
int duree_total;
|
||||||
// Etat actuelle de la tâche
|
// Etat actuelle de la tâche
|
||||||
|
@ -28,7 +27,12 @@ class Tache {
|
||||||
void _copy(const Tache &);
|
void _copy(const Tache &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tache(const int); // constructor
|
// ID unique de la tâche
|
||||||
|
const int unique_id;
|
||||||
|
// Vrai si la tâche à été visitée par le parcours en profondeur
|
||||||
|
bool visite;
|
||||||
|
|
||||||
|
Tache(const std::string, const int); // constructor
|
||||||
virtual ~Tache(); // destructor
|
virtual ~Tache(); // destructor
|
||||||
|
|
||||||
Tache(const Tache &); // copy constructor
|
Tache(const Tache &); // copy constructor
|
||||||
|
@ -45,6 +49,15 @@ public:
|
||||||
|
|
||||||
// Calcule la durée totale max de réalisation d'une tâche et des dépendances
|
// Calcule la durée totale max de réalisation d'une tâche et des dépendances
|
||||||
int dureeParal() const;
|
int dureeParal() const;
|
||||||
|
|
||||||
|
// Parcours en profondeur
|
||||||
|
void PP_postfixe(std::vector<Tache *> &);
|
||||||
|
|
||||||
|
// Récupère la durée totale
|
||||||
|
int get_duree_totale() const;
|
||||||
|
|
||||||
|
// Récupère le nom
|
||||||
|
std::string get_name() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
5
report/.gitignore
vendored
Normal file
5
report/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
*
|
||||||
|
|
||||||
|
!.gitignore
|
||||||
|
!Makefile
|
||||||
|
!*.tex
|
16
report/Makefile
Normal file
16
report/Makefile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
NAME = explications
|
||||||
|
|
||||||
|
TEX = $(NAME).tex
|
||||||
|
SRC = $(TEX)
|
||||||
|
PDF = $(TEX:.tex=.pdf)
|
||||||
|
|
||||||
|
TEXMK = latexmk -shell-escape -lualatex
|
||||||
|
|
||||||
|
all: $(PDF)
|
||||||
|
|
||||||
|
$(PDF): %.pdf: %.tex
|
||||||
|
$(TEXMK) $<
|
||||||
|
|
||||||
|
EXTS = aux fdb_latexmk fls log nav out snm synctex.gz toc
|
||||||
|
clean:
|
||||||
|
rm -rf $(PDF) _minted-$(NAME)/ $(foreach ext,$(EXTS),$(NAME).$(ext))
|
49
report/explications.tex
Normal file
49
report/explications.tex
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
\documentclass{article}
|
||||||
|
|
||||||
|
\usepackage[T1]{fontenc} % encoding
|
||||||
|
\renewcommand{\familydefault}{\sfdefault} % sans-serif font
|
||||||
|
|
||||||
|
\usepackage[french]{babel} % langages
|
||||||
|
\frenchsetup{SmallCapsFigTabCaptions=false}
|
||||||
|
|
||||||
|
\usepackage[hidelinks]{hyperref} % clickable links in table of contents
|
||||||
|
|
||||||
|
\usepackage{graphicx} % images
|
||||||
|
|
||||||
|
\newcommand{\emma}{Emma Botti}
|
||||||
|
\newcommand{\anri}{Anri Kennel}
|
||||||
|
|
||||||
|
\newcommand{\pp}{\texttt{ProtoProjet}}
|
||||||
|
\newcommand{\rp}{\texttt{RunProjet}}
|
||||||
|
|
||||||
|
\title{Explications TP5}
|
||||||
|
\author{\emma\thanks{\emma : 00000000} et \anri\thanks{\anri : 22302653} \\
|
||||||
|
Langages à objet avancés $\cdot$ Université Paris Cité}
|
||||||
|
\date{Année universitaire 2023-2024}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\maketitle
|
||||||
|
\tableofcontents
|
||||||
|
\clearpage
|
||||||
|
|
||||||
|
\section{Explications}
|
||||||
|
\subsection{Problématique de copies}
|
||||||
|
La liste des tâches est créée lors du \pp, et vider de la mémoire
|
||||||
|
lorsque \rp~disparaît. Lors du passage des tâches entre \pp~et \rp, il n'y a pas de copie.
|
||||||
|
|
||||||
|
\subsection{Problématique de sécurité}
|
||||||
|
Les variables sont toutes encapsulées dans des classes qui leur correspondent.
|
||||||
|
Les variables, quand elles n'ont pas à être exposé, sont soit cachés,
|
||||||
|
soit immuable.
|
||||||
|
|
||||||
|
\section{Diagramme UML}
|
||||||
|
|
||||||
|
\begin{figure}[h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[width=1.3\textwidth]{../diagramme_uml.png}
|
||||||
|
\caption{Diagramme UML}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
|
@ -1,10 +1,10 @@
|
||||||
#include "../includes/Consultant.hpp"
|
#include "../includes/Consultant.hpp"
|
||||||
|
|
||||||
Consultant::Consultant() { std::cout << "Hello, Consultant!\n"; }
|
Consultant::Consultant() {}
|
||||||
|
|
||||||
Consultant::~Consultant() {}
|
Consultant::~Consultant() {}
|
||||||
|
|
||||||
Consultant::Consultant(const Consultant &) {}
|
Consultant::Consultant(const Consultant &) : Gestionnaire() {}
|
||||||
|
|
||||||
const Consultant &Consultant::operator=(const Consultant &src) {
|
const Consultant &Consultant::operator=(const Consultant &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
|
@ -13,3 +13,27 @@ const Consultant &Consultant::operator=(const Consultant &src) {
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Consultant &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, int>
|
||||||
|
Consultant::avis(const RunProjet &projet) const {
|
||||||
|
std::vector<int> ordonnancement;
|
||||||
|
if (!payer()) {
|
||||||
|
return std::make_pair(ordonnancement, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<const Tache *> taches = projet.consult_tasks();
|
||||||
|
int duree_totale = 0;
|
||||||
|
for (const Tache *it : taches) {
|
||||||
|
duree_totale += it->get_duree_totale();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Tache *it : taches) {
|
||||||
|
ordonnancement.push_back(it->unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(ordonnancement, duree_totale);
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "../includes/Expert.hpp"
|
#include "../includes/Expert.hpp"
|
||||||
|
|
||||||
Expert::Expert() { std::cout << "Hello, Expert!\n"; }
|
Expert::Expert() {}
|
||||||
|
|
||||||
Expert::~Expert() {}
|
Expert::~Expert() {}
|
||||||
|
|
||||||
Expert::Expert(const Expert &) {}
|
Expert::Expert(const Expert &) : Gestionnaire() {}
|
||||||
|
|
||||||
const Expert &Expert::operator=(const Expert &src) {
|
const Expert &Expert::operator=(const Expert &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
|
@ -13,3 +13,23 @@ const Expert &Expert::operator=(const Expert &src) {
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Expert &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, int> Expert::avis(const RunProjet &projet) const {
|
||||||
|
std::vector<int> ordonnancement;
|
||||||
|
if (!payer()) {
|
||||||
|
return std::make_pair(ordonnancement, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<const Tache *> taches = projet.consult_tasks();
|
||||||
|
const int duree_totale = taches.front()->dureeParal();
|
||||||
|
|
||||||
|
for (const Tache *it : taches) {
|
||||||
|
ordonnancement.push_back(it->unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(ordonnancement, duree_totale);
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,59 @@
|
||||||
#include "../includes/Gestionnaire.hpp"
|
#include "../includes/Gestionnaire.hpp"
|
||||||
|
|
||||||
Gestionnaire::Gestionnaire() { std::cout << "Hello, Gestionnaire!\n"; }
|
Gestionnaire::Gestionnaire() {
|
||||||
|
salaire_attendu = rand() % 500 + 400; // Entre 400 et 899
|
||||||
|
salaire_recu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Gestionnaire::~Gestionnaire() {}
|
Gestionnaire::~Gestionnaire() {}
|
||||||
|
|
||||||
Gestionnaire::Gestionnaire(const Gestionnaire &) {}
|
Gestionnaire::Gestionnaire(const Gestionnaire &src)
|
||||||
|
: salaire_attendu(src.salaire_attendu), salaire_recu(0) {}
|
||||||
|
|
||||||
const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) {
|
const Gestionnaire &Gestionnaire::operator=(const Gestionnaire &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
salaire_attendu = src.salaire_attendu;
|
||||||
|
salaire_recu = src.salaire_recu;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &Gestionnaire::print(std::ostream &out) const {
|
||||||
|
out << "La facture s'élève à " << salaire_attendu << "€, il reste "
|
||||||
|
<< reste_a_payer() << "€ à payer";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Gestionnaire &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Gestionnaire::reste_a_payer() const {
|
||||||
|
return salaire_attendu - salaire_recu;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Gestionnaire::payer() const {
|
||||||
|
bool return_val = salaire_recu >= salaire_attendu;
|
||||||
|
|
||||||
|
if (!return_val) {
|
||||||
|
std::cerr << "Je n'ai pas été payé. " << *this << ".\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Gestionnaire::payer(const int argent) {
|
||||||
|
if (reste_a_payer() <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
salaire_recu += argent;
|
||||||
|
if (reste_a_payer() <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reste_a_payer();
|
||||||
|
}
|
||||||
|
|
110
src/Projet.cpp
110
src/Projet.cpp
|
@ -1,15 +1,117 @@
|
||||||
#include "../includes/Projet.hpp"
|
#include "../includes/Projet.hpp"
|
||||||
|
|
||||||
Projet::Projet() { std::cout << "Hello, project!\n"; }
|
Projet::Projet() : fin(new Tache("Fin", 0)), debut(new Tache("Début", 0)) {
|
||||||
|
fin->ajouteDependance(*debut);
|
||||||
|
|
||||||
Projet::~Projet() {}
|
taches.push_back(fin);
|
||||||
|
taches.push_back(debut);
|
||||||
|
}
|
||||||
|
|
||||||
Projet::Projet(const Projet &) {}
|
Projet::~Projet() { free_taches(); }
|
||||||
|
|
||||||
|
void Projet::_copy(const Projet &src) {
|
||||||
|
// Copie des tâches
|
||||||
|
taches.reserve(src.taches.size());
|
||||||
|
for (Tache *t : src.taches) {
|
||||||
|
taches.push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Projet::free_taches() { taches.clear(); }
|
||||||
|
|
||||||
|
Projet::Projet(const Projet &src) : fin(src.fin), debut(src.debut) {
|
||||||
|
_copy(src);
|
||||||
|
}
|
||||||
|
|
||||||
const Projet &Projet::operator=(const Projet &src) {
|
const Projet &Projet::operator=(const Projet &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
fin = src.fin;
|
||||||
|
debut = src.debut;
|
||||||
|
free_taches();
|
||||||
|
_copy(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &Projet::print(std::ostream &out) const {
|
||||||
|
// Liste vide
|
||||||
|
if (taches.empty()) {
|
||||||
|
out << "[]";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "[\n";
|
||||||
|
for (Tache *t : taches) {
|
||||||
|
out << " " << *t << ",\n";
|
||||||
|
}
|
||||||
|
out << ']';
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Projet &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const int, const int> Projet::pick_two_random_tasks() const {
|
||||||
|
// Choix aléatoire d'une tâche
|
||||||
|
size_t size = this->taches.size();
|
||||||
|
size_t rand1 = static_cast<size_t>(rand()) % size;
|
||||||
|
size_t rand2 = static_cast<size_t>(rand()) % size;
|
||||||
|
|
||||||
|
Tache *tache1 = this->taches[rand1];
|
||||||
|
Tache *tache2 = this->taches[rand2];
|
||||||
|
|
||||||
|
// tache2 ne doit pas dépendre transitivement de tache1
|
||||||
|
if (tache2->depends_from(*tache1)) {
|
||||||
|
return pick_two_random_tasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
int id1 = tache1->unique_id;
|
||||||
|
int id2 = tache2->unique_id;
|
||||||
|
return std::make_pair(id1, id2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tache *Projet::contains(const int id) const {
|
||||||
|
for (Tache *t : this->taches) {
|
||||||
|
if (id == t->unique_id) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tache *Projet::contains(const std::string name) const {
|
||||||
|
for (Tache *t : this->taches) {
|
||||||
|
if (name == t->get_name()) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<const Tache *> Projet::consult_tasks() const {
|
||||||
|
return std::vector<const Tache *>(taches.begin(), taches.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Projet::topologicalSort() {
|
||||||
|
// Construction de la pile
|
||||||
|
std::vector<Tache *> pile;
|
||||||
|
for (Tache *it : taches) {
|
||||||
|
if (!it->visite) {
|
||||||
|
it->PP_postfixe(pile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nettoyage des marques
|
||||||
|
cleanMarks();
|
||||||
|
|
||||||
|
// Reverse de la pile
|
||||||
|
std::reverse(pile.begin(), pile.end());
|
||||||
|
|
||||||
|
// Modifie la liste des tâches topologiquement triée
|
||||||
|
taches = pile;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "../includes/ProtoProjet.hpp"
|
#include "../includes/ProtoProjet.hpp"
|
||||||
|
|
||||||
ProtoProjet::ProtoProjet() { std::cout << "Hello, protoProject!\n"; }
|
ProtoProjet::ProtoProjet() {}
|
||||||
|
|
||||||
ProtoProjet::~ProtoProjet() {}
|
ProtoProjet::~ProtoProjet() {}
|
||||||
|
|
||||||
ProtoProjet::ProtoProjet(const ProtoProjet &) : Projet() {}
|
ProtoProjet::ProtoProjet(const ProtoProjet &src) : Projet(src) {}
|
||||||
|
|
||||||
const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
|
const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
|
@ -13,3 +13,50 @@ const ProtoProjet &ProtoProjet::operator=(const ProtoProjet &src) {
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ProtoProjet &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoProjet::cleanMarks() const {
|
||||||
|
for (auto t : taches) {
|
||||||
|
t->visite = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ProtoProjet::ajoute(const std::string nom, const int duree) {
|
||||||
|
// Sélection de 2 tâches au hasard
|
||||||
|
auto tasks = pick_two_random_tasks();
|
||||||
|
|
||||||
|
// Ajout des tâches
|
||||||
|
return ajoute(nom, duree, tasks.first, tasks.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id) {
|
||||||
|
// Ajout de la tâche entre l'ID voulu et la tâche finale
|
||||||
|
return ajoute(nom, duree, id, fin->unique_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProtoProjet::ajoute(const std::string nom, const int duree, const int id1,
|
||||||
|
const int id2) {
|
||||||
|
Tache *tache1 = contains(id1);
|
||||||
|
Tache *tache2 = contains(id2);
|
||||||
|
|
||||||
|
// Vérifie que les tâches avec les id1 et id2 existent bien dans la liste
|
||||||
|
if (!tache1 || !tache2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création des dépendances
|
||||||
|
Tache *tache = new Tache(nom, duree);
|
||||||
|
if (!tache1->ajouteDependance(*tache) && !tache->ajouteDependance(*tache2)) {
|
||||||
|
// Problème de dépendance
|
||||||
|
delete tache;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mise à jour du vecteur avec tri topologique
|
||||||
|
taches.push_back(tache);
|
||||||
|
topologicalSort();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
#include "../includes/RunProjet.hpp"
|
#include "../includes/RunProjet.hpp"
|
||||||
|
|
||||||
RunProjet::RunProjet() { std::cout << "Hello, runProject!\n"; }
|
RunProjet::RunProjet(ProtoProjet &src) : ProtoProjet(src) { src.free_taches(); }
|
||||||
|
|
||||||
RunProjet::~RunProjet() {}
|
RunProjet::~RunProjet() {
|
||||||
|
// Ici on veut supprimes les tâches
|
||||||
|
for (Tache *it : taches) {
|
||||||
|
delete it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RunProjet::RunProjet(const RunProjet &) : ProtoProjet() {}
|
RunProjet::RunProjet(const RunProjet &src) : ProtoProjet(src) {}
|
||||||
|
|
||||||
const RunProjet &RunProjet::operator=(const RunProjet &src) {
|
const RunProjet &RunProjet::operator=(const RunProjet &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
|
@ -13,3 +18,24 @@ const RunProjet &RunProjet::operator=(const RunProjet &src) {
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const RunProjet &data) {
|
||||||
|
return data.print(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunProjet::run(const int id) const {
|
||||||
|
Tache *tache = contains(id);
|
||||||
|
// La tâche n'existe pas
|
||||||
|
if (!tache) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renvoie si la tâche s'est réalisée
|
||||||
|
return tache->realise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunProjet::run(const std::vector<const Tache *> sequence_taches) const {
|
||||||
|
for (const Tache *it : sequence_taches) {
|
||||||
|
run(it->unique_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
int Tache::counter_id = 0;
|
int Tache::counter_id = 0;
|
||||||
|
|
||||||
Tache::Tache(const int duree)
|
Tache::Tache(const std::string n, const int duree)
|
||||||
: unique_id(++counter_id), duree_total(duree), etat(EnAttente),
|
: name(n), duree_total(duree), etat(EnAttente),
|
||||||
dependances(std::vector<Tache *>()) {}
|
dependances(std::vector<Tache *>()), unique_id(counter_id++),
|
||||||
|
visite(false) {}
|
||||||
|
|
||||||
Tache::~Tache() {}
|
Tache::~Tache() {}
|
||||||
|
|
||||||
|
@ -17,7 +18,8 @@ void Tache::_copy(const Tache &src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Tache::Tache(const Tache &src)
|
Tache::Tache(const Tache &src)
|
||||||
: unique_id(++counter_id), duree_total(src.duree_total), etat(src.etat) {
|
: name(src.name), duree_total(src.duree_total), etat(src.etat),
|
||||||
|
unique_id(counter_id++), visite(src.visite) {
|
||||||
_copy(src);
|
_copy(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,8 +27,10 @@ const Tache &Tache::operator=(const Tache &src) {
|
||||||
if (this == &src) {
|
if (this == &src) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
name = src.name;
|
||||||
duree_total = src.duree_total;
|
duree_total = src.duree_total;
|
||||||
etat = src.etat;
|
etat = src.etat;
|
||||||
|
visite = src.visite;
|
||||||
_copy(src);
|
_copy(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +38,7 @@ const Tache &Tache::operator=(const Tache &src) {
|
||||||
std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
|
std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case Tache::EnAttente:
|
case Tache::EnAttente:
|
||||||
out << "En Attente";
|
out << "Attend";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Tache::Realisee:
|
case Tache::Realisee:
|
||||||
|
@ -45,8 +49,8 @@ std::ostream &operator<<(std::ostream &out, const Tache::Etat &data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const Tache &data) {
|
std::ostream &operator<<(std::ostream &out, const Tache &data) {
|
||||||
out << "Tâche #" << data.unique_id << " " << data.etat << " avec "
|
out << "Tâche(#" << data.unique_id << ", \"" << data.name << "\", "
|
||||||
<< data.dependances.size() << " dépendances";
|
<< data.etat << ")\t=> " << data.dependances.size() << " dépendances";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,9 +63,11 @@ bool Tache::realise() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Ca veux dire quoi déclencher une tâche ?
|
// TODO: Faire une vérification si le temps est écoulée ?
|
||||||
|
// Dans ce cas là faut stocker le temps d'exécution actuelle de la tâche ?
|
||||||
|
|
||||||
etat = Realisee;
|
etat = Realisee;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tache::depends_from(const Tache &x) const {
|
bool Tache::depends_from(const Tache &x) const {
|
||||||
|
@ -82,7 +88,7 @@ bool Tache::depends_from(const Tache &x) const {
|
||||||
bool Tache::ajouteDependance(Tache &x) {
|
bool Tache::ajouteDependance(Tache &x) {
|
||||||
// On ne créer pas de dépendances cyclique aka 2 tâches
|
// On ne créer pas de dépendances cyclique aka 2 tâches
|
||||||
// qui dépendent l'une de l'autre
|
// qui dépendent l'une de l'autre
|
||||||
if (depends_from(x)) {
|
if (x.depends_from(*this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,3 +115,19 @@ int Tache::dureeParal() const {
|
||||||
// On ajoute la valeur max à notre durée totale
|
// On ajoute la valeur max à notre durée totale
|
||||||
return ret_value + max_duree;
|
return ret_value + max_duree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tache::PP_postfixe(std::vector<Tache *> &pile) {
|
||||||
|
visite = true;
|
||||||
|
for (Tache *it : dependances) {
|
||||||
|
if (!it->visite) {
|
||||||
|
it->PP_postfixe(pile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moment post-fix du parcours
|
||||||
|
pile.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Tache::get_duree_totale() const { return duree_total; }
|
||||||
|
|
||||||
|
std::string Tache::get_name() const { return name; }
|
||||||
|
|
162
src/main.cpp
162
src/main.cpp
|
@ -1 +1,161 @@
|
||||||
int main(int argc, char const *argv[]) { return 0; }
|
#include "../includes/Consultant.hpp"
|
||||||
|
#include "../includes/Expert.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// Fait des tests pour vérifier/montrer que ça fonctionne
|
||||||
|
void test();
|
||||||
|
|
||||||
|
// Transforme un vecteur<int> en string
|
||||||
|
std::string vecint_tostring(std::vector<int> list);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
/* test();
|
||||||
|
return EXIT_SUCCESS; */
|
||||||
|
|
||||||
|
ProtoProjet pp;
|
||||||
|
|
||||||
|
pp.ajoute("a", 10); // probablement numero 2
|
||||||
|
cout << pp; // avec ses 3 taches
|
||||||
|
cout << "\n----------" << endl;
|
||||||
|
|
||||||
|
pp.ajoute("b", 15, 0, 1); // en supposant que 0: fin et 1: début
|
||||||
|
cout << pp;
|
||||||
|
cout << "\n----------" << endl;
|
||||||
|
|
||||||
|
RunProjet rp{pp};
|
||||||
|
cout << "----- verification : ProtoProjet vide " << endl;
|
||||||
|
cout << pp << endl;
|
||||||
|
|
||||||
|
Consultant c;
|
||||||
|
c.payer(1000);
|
||||||
|
cout << c.avis(rp).second << endl; // dira 25
|
||||||
|
|
||||||
|
Expert e;
|
||||||
|
e.payer(1000);
|
||||||
|
cout << e.avis(rp).second << endl; // dira 15
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
/********************************** Projet **********************************/
|
||||||
|
// Projet p; // impossible car classe abstraite
|
||||||
|
|
||||||
|
/******************************* ProtoProjet *******************************/
|
||||||
|
ProtoProjet pp;
|
||||||
|
cout << "pp: " << pp << "\n";
|
||||||
|
/* pp: [
|
||||||
|
* Tâche(#0, "Fin", Attend) => 1 dépendances,
|
||||||
|
* Tâche(#1, "Début", Attend) => 0 dépendances,
|
||||||
|
* ] */
|
||||||
|
|
||||||
|
pp.ajoute("a", 10); // ajoute une dépendance à #1 le "début"
|
||||||
|
pp.ajoute("b", 15, 0, 1); // ajoute une dépendance à #0 (id1)
|
||||||
|
cout << "pp: " << pp << "\n";
|
||||||
|
/* pp: [
|
||||||
|
* Tâche(#0, "Fin", Attend) => 2 dépendances,
|
||||||
|
* Tâche(#3, "b", Attend) => 0 dépendances,
|
||||||
|
* Tâche(#1, "Début", Attend) => 1 dépendances,
|
||||||
|
* Tâche(#2, "a", Attend) => 0 dépendances,
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* => L'ordre pour les dépendances est respecté */
|
||||||
|
|
||||||
|
/******************************** RunProjet ********************************/
|
||||||
|
// RunProjet rp; // impossible car le constructeur vide n'existe pas
|
||||||
|
RunProjet rp(pp);
|
||||||
|
cout << "pp: " << pp << "\n";
|
||||||
|
/* pp: []
|
||||||
|
*
|
||||||
|
* => La liste est bien vidée*/
|
||||||
|
|
||||||
|
cout << "rp: " << rp << "\n";
|
||||||
|
/* rp: [
|
||||||
|
* Tâche(#0, "Fin", Attend) => 2 dépendances,
|
||||||
|
* Tâche(#3, "b", Attend) => 0 dépendances,
|
||||||
|
* Tâche(#1, "Début", Attend) => 1 dépendances,
|
||||||
|
* Tâche(#2, "a", Attend) => 0 dépendances,
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* => Les mêmes tâches ont étés transférés à RunProjet (pas de copie vérifiés
|
||||||
|
* par les ID identiques) */
|
||||||
|
|
||||||
|
/******************************** Consultant *******************************/
|
||||||
|
Consultant c;
|
||||||
|
cout << "c: " << c << "\n";
|
||||||
|
/* c: La facture s'élève à 693€, il reste 693€ à payer
|
||||||
|
*
|
||||||
|
* => Affiche la facture */
|
||||||
|
|
||||||
|
auto avis = c.avis(rp);
|
||||||
|
cout << "c(avis): (" << vecint_tostring(avis.first) << ", " << avis.second
|
||||||
|
<< ")\n";
|
||||||
|
/* Je n'ai pas été payé. La facture s'élève à 693€, il reste 693€ à payer.
|
||||||
|
* c(avis): ([], -1)
|
||||||
|
*
|
||||||
|
* => Iel ne donne pas d'avis car pas payé. */
|
||||||
|
|
||||||
|
cout << "c(payer 1000): " << c.payer(1000) << "\n";
|
||||||
|
/* c(payer 1000): 0
|
||||||
|
*
|
||||||
|
* On donne 1000 pour être sûr qu'iel soit content
|
||||||
|
* Il renvoie 0 car iel a plus besoin d'être payé */
|
||||||
|
|
||||||
|
auto avis2 = c.avis(rp);
|
||||||
|
cout << "c(avis): (" << vecint_tostring(avis2.first) << ", " << avis2.second
|
||||||
|
<< ")\n";
|
||||||
|
/* c(avis): ([0, 3, 1, 2], 25)
|
||||||
|
*
|
||||||
|
* => Iel donne la liste d'exécution
|
||||||
|
* et le temps d'exécution sans parallélisation */
|
||||||
|
|
||||||
|
/********************************** Expert *********************************/
|
||||||
|
Expert e;
|
||||||
|
cout << "e: " << e << "\n";
|
||||||
|
/* e: La facture s'élève à x€, il reste x€ à payer
|
||||||
|
*
|
||||||
|
* => Affiche la facture */
|
||||||
|
|
||||||
|
auto avis3 = e.avis(rp);
|
||||||
|
cout << "e(avis): (" << vecint_tostring(avis3.first) << ", " << avis3.second
|
||||||
|
<< ")\n";
|
||||||
|
/* Je n'ai pas été payé. La facture s'élève à y€, il reste y€ à payer.
|
||||||
|
* e(avis): ([], -1)
|
||||||
|
*
|
||||||
|
* => Iel ne donne pas d'avis car pas payé. */
|
||||||
|
|
||||||
|
cout << "e(payer 1000): " << e.payer(1000) << "\n";
|
||||||
|
/* e(payer 1000): 0
|
||||||
|
*
|
||||||
|
* On donne 1000 pour être sûr qu'iel soit content
|
||||||
|
* Il renvoie 0 car iel a plus besoin d'être payé */
|
||||||
|
|
||||||
|
auto avis4 = e.avis(rp);
|
||||||
|
cout << "e(avis): (" << vecint_tostring(avis4.first) << ", " << avis4.second
|
||||||
|
<< ")\n";
|
||||||
|
/* e(avis): ([0, 3, 1, 2], 15)
|
||||||
|
*
|
||||||
|
* => Iel donne la liste d'exécution
|
||||||
|
* et le temps d'exécution avec parallélisation */
|
||||||
|
|
||||||
|
/* A la fin, la mémoire est correctement libérée, testé via Valgrind-3.21.0 :
|
||||||
|
* HEAP SUMMARY:
|
||||||
|
* in use at exit: 0 bytes in 0 blocks
|
||||||
|
* total heap usage: 33 allocs, 33 frees, 75,550 bytes allocated
|
||||||
|
* All heap blocks were freed -- no leaks are possible
|
||||||
|
* ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) */
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string vecint_tostring(std::vector<int> list) {
|
||||||
|
std::string return_value = "[";
|
||||||
|
if (list.empty()) {
|
||||||
|
return return_value + "]";
|
||||||
|
}
|
||||||
|
for (auto it : list) {
|
||||||
|
return_value += std::to_string(it) + ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// \b\b pour retirer la dernière virgule
|
||||||
|
return return_value + "\b\b]";
|
||||||
|
}
|
||||||
|
|
Reference in a new issue