Le problème du undo/redo est un problème récurrent dès qu'on souhaite réaliser un logiciel un peu poussé. De fait, les solutions existent.
Dans ton problème, la manière de procéder semble être de créer un snapshot de l'état de l'application avant d'appliquer la modification, et de ne conserver dans le snapshoot que ce qui est modifié - si tu modifie un vertex, tu sauve ce vertex. Si tu modifie une matrice, tu sauves la matrice. Si tu modifie une association modèle/texture, tu sauve la valeur précédente. etc.
Si l'utilisateur veut défaire ce qu'il a fait, tu récupères l'état précédent et tu l'appliques. Si il souhaite refaire ses modifications défaites, tu descends dans la liste des sauvegardes d'état et tu les appliques.
Un exemple vaut mieux qu'un long discours :
L'idée est de ne sauvegarder vraiment que ce qui change et qui ne peut pas être recalculé avec les données de l'état courant, afin de minimiser la mémoire prise par le système et le temps de stockage. Tout ce qui est fait par la carte graphique ne fait pas partie de l'état courant (c'est le résultat d'un calcul). Par contre, toutes les entrées de la carte graphique font partie de l'état courant.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 init: liste_etats <-- nouvelle liste<ETAT> change_matrice: etat_prec <-- nouvel_etat_matrice(matrice_précédente) etat_courant <-- nouvel_etat_matrice(nouvelle_matrice) liste_etat.supprimer_dernier_et_suivant liste_etat.ajoute(etat_prec) liste_etat.ajoute(etat_courant) pointeur_liste_etat <-- liste_etat.dernier change_vertex: etat_prec <-- nouvel_etat_vertex(vertex_avant_modif) etat_courant <-- nouvel_etat_vertex(vertex_après_modif) liste_etat.supprimer_dernier_et_suivant liste_etat.ajoute(etat_prec) liste_etat.ajoute(etat_courant) pointeur_liste_etat <-- liste_etat.dernier undo: pointeur_liste_etat <-- pointeur_liste_etat.précédent applique_etat(pointeur_liste_etat.etat) redo: pointeur_liste_etat <-- pointeur_liste_etat.suivant applique_etat(pointeur_liste_etat.etat)
Il est illusoire de vouloir créer des transformations inverses - elles ne seront jamais assez précises, sauf dans certains cas chanceux (le cas ou une transformation ET son inverse peuvent être représentés sans perte, que ce soit sur un float ou un double (qui sont, je le rappelle, soumis au même restrictions)).
Partager