Ca faisait longtemps que je n'étais pas venu vous embêter avec mes petits problèmes...
Voilà, dans un projet que j'ai en cours, je gère dans une boucle principale majoritairement trois objets.
Un bouton.
Un encodeur rotatif.
Et un objet qui génère des sons en fonction d'une interface utilisateur.
Cet objet qui gère des sons est défini dans une classe (Pad, StepSequencer et Bounce par exemple), qui hérite d'une classe abstraite SoundObject, ce qui me permet de définir un pointeur vers la classe abstraite, et d'appeler toujours les mêmes méthodes dans ma boucle prinicpale, même si l'objet change en fonction du mode choisi.
Jusque là ca va. L'encodeur rotatif est lu dans la boucle principale. Découvrant il y a quelques jours le concept de pointeurs sur fonction, je me suis dit que ce serait pratique de pouvoir attacher une fonction à l'encodeur. Comme ça je pourrais, en même temps que je change de "contexte" pour l'instrument utilisé, changer la manière dont réagit l'encodeur et lui faire exécuter une fonction dédiée.
Aussitôt dit aussitôt fait, je lui ai rattaché une méthode attach(), une méthode détach(), qui font très bien ce que l'on suppose qu'elles font, et une méthode exec() qui transmet l'état de l'encodeur à la fonction attachée.
Je suis surpris d'y être parvenue aussi bien aussi vite, ça fonctionne au poil... Avec des fonctions statiques.
D'ailleurs la bibliothèque est là, pour ceux que ça intéresse.
Maintenant j'aimerais assez pouvoir attacher une fonction membre d'une classe, mais ça bloque.
J'ai bien compris que ça ne fonctionne pas:
//Pointeur vers classe mère des objets gestionnaires de sons
SoundModule *module = NULL;
//Instanciation et définition de l'encodeur
Encoder wheel = Encoder();
wheel.begin(7, 8);
//instanciation, depuis le menu, d'un nouvel instrument, ici le step sequencer
Step *step = new Step();
//auquel je passe les références aux instanciations du synthétiseur, de l'interface graphique, et des notes réglées.
step->begin(&synth, &interface, ¬es);
//et ici je le rattache au pointeur de la classe mère, ce qui me permet d'y avoir accès depuis la boucle principale via des méthodes communes.
module = step;
//et pour finir, je rattache la fonction désirée à mon encodeur
wheel.attach(step->updateSpeed);
Donc, ça ne marche pas. Je sais pourquoi, c'est parce que pour une fonction non statique, il faudrait que je remplace, dans la définition de l'encodeur, la première définition du pointeur par la deuxième, si j'ai bien compris.
//version actuelle, pour fonction statiques.
void (*_function)()
//ce qu'il faudrait, pour fonctions membres.
void (Step::*_function)()[
Or ça me pose un problème: je voulais pouvoir simplifier les choses avec ce pointeur sur fonction, mais si je dois définir un pointeur différent pour chaque type d'objet vers lequel il peut pointer, je pers tout la souplesse du système!
Je suppose que je pourrais aussi définir cette fonction comme une fonction virtuelle de ma classe SoundModule, mais d'une part tous les modules n'ont pas besoin de gérer l'encodeur, et d'autre part il faudrait aussi spécialiser la classe de l'encodeur.
Est-ce que vous savez si ce problème peut avoir une solution, ou bien si je tente de le contourner d'une manière ou l'autre? Jusque là je suis parvenu à conserver des sous-ensembles plutôt indépendants dans mon programme, j'amieria bien pouvoir continuer sur cette voie saine!
Merci par avance!
Edit: NOTA: dans mon cas je pourrai probablement m'en sortir, parce que l'encodeur devrait intervenir sur des objets qui sont définis en début de programme, et restent accessible. Je pourrais donc écrire quelques fonctions statiques qui seraient dédiées à faire ces modifications. Mais ça reste quand même, il me semble, une manière de contourner le problème, le plus simple serait de pouvoir accéder directement aux objets concernés, quel que soit leur type.