Avant d'ajouter les nouveaux
Animator, une difficulté propre à Rust doit être
résolue.
Les animations
Collide et
Repulse devront modifier une entité tout en
consultant les autres entités de la fenêtre.
Autrement dit, elles devront accéder simultanément à une entité en modification
et à l'ensemble auquel elle appartient.
Une telle situation est difficile à analyser statiquement.
Le
borrow-checker
ne peut pas garantir à la compilation que deux accès incompatibles ne se produiront
jamais, et Rust refuse donc ce type de code.
La solution consiste à reporter cette vérification à l'exécution grâce au mécanisme
d'
interior mutability
(exclusivité dynamique), fourni par le type
std::cell::RefCell.
Avec
RefCell, les données ne sont accessibles qu'à travers des références partagées.
Lorsqu'un accès est nécessaire, il doit être demandé explicitement :
- borrow() pour un accès en lecture ;
- borrow_mut() pour un accès en écriture.
RefCell vérifie alors à l'exécution que les règles d'emprunt sont respectées.
En cas de conflit, le programme est interrompu par un
panic!().
Pour appliquer ce mécanisme, remplacez le type du membre
entities de
Window par :
Adaptez ensuite votre code afin que chaque entité soit stockée dans un
RefCell,
notamment dans
add_entity().
Enfin, remplacez les accès directs aux entités par des appels à
borrow() ou
borrow_mut(), selon que vous souhaitez les consulter ou les modifier.
Vérifiez que l'application conserve le même comportement qu'au laboratoire précédent.