Bonsoir,
sur le petit jeu que je suis en train de programmer, je me trouve confronté à un petit problème que je pensais classique mais sur lequel je ne parviens pas à trouver de réponse satisfaisante. Il se trouve que je me suis rendu compte que je vais avoir besoin d'un séquenceur (pour les animations et quelques effets que je voudrais ajouter, entres autres). Donc j'ai implémenté un séquenceur super simple, dont l'unité de temps est la frame (je suis en frame rate constant), qui n'est rien d'autre qu'une queue d'événements finalement.
Et donc mon problème est le suivant:
J'ai implémenté mes évènements comme des Command classique: une "interface" IEvent avec une fonction Execute(). Ce que j'ai fais, c'est que cette fonction Execute() je l'ai déclarée comme une boost::function, mais je ne pense pas que ce soit important.
Le soucis, c'est que ces événement vont être de nature très variée. Et donc, je vais avoir besoin de passer des paramètres à cette fonction Execute. Et des paramètres de types très variés. Et donc mon problème c'est ça: trouver une façon propre et robuste (la robustesse de mon code est primordiale car c'est un projet voué à la collaboration) pour gérer les paramètres de mes événements.
Dans un premier temps, j'avais pensé à déclarer une "interface" IEventParam, totalement vide, qui me permet, en passant par un pointeur, de downcaster le paramètre à la réception. Quelque chose comme ça:
avec un exemple d'utilisation:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct IEventParam(){} struct IEvent { virtual void Execute( IEventParam * ) = 0; };
Bon, en vérité, j'ai fais plus simple, parce que à la place d'une structure héritant de IEvent, je passe par une boost::function<IEventParam*> et ça m'évite de passer par une structe IEvent et j'appelle directement les fonctions souhaitées sans passer par Ivent::Execute(). Mais ça ne change rien au problème et c'est plus clair comme ça.
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 struct MoveUnitParam { Unit* unit; // unité à déplacer float vitesse; // en pixel par frame unsigned int direction; }; struct MoveUnit: public IEvent //cet événement déplace une unité sur la carte { void Execute( IEventParam * param ) { MoveUnitParam * muParam = (MoveUnitParam *) param; muParam ->unit->Move( muParam ->vitesse, muParam ->direction ); } };
Donc, comme on peut le voir dans cet exemple, il y a des choses assez moches dans cette méthode, et je cherche un moyen plus propre, et surtout plus robuste pour le faire. Là par exemple, le downcast me parait dangereux. Autre chose qui ne me plait pas, c'est que j'ai tout un tas d'évenements qui n'ont pas besoin de paramètres, mais il faut tout de même que je les déclare avec un IEventParam* en paramètre. Ca ne me parait pas logique, je pense donc que ce n'est pas un modèle valide.
Donc voilà, si vous avez compris ce que je raconte (c'est que ça à l'air de rien, mais c'est pas facile à expliquer!), je cherche une solution propre et robuste pour gérer les paramètres de mes événements.
Partager