Création de map de pointeur sur fonction membre.

Fermé
Spowny Messages postés 7 Date d'inscription mercredi 15 août 2012 Statut Membre Dernière intervention 6 janvier 2013 - 6 janv. 2013 à 04:07
mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 - 8 janv. 2013 à 00:34
Bonjour,

Je souhaite créer un gestionnaire d'évent pour la SFML.
J'ai décider de faire ce dernier avec une map ayant pour clef le type d'évent et pour valeur un pointeur sur une fonction membre de ce même objet.
J'ai essayer beaucoup de "bidouilles" différentes et celle que je vous joint est celle qui me semble le plus correcte.

Pouvez vous m'aider svp ?

EventManager.h:

#pragma once
 
#include				<map>
#include				<iostream>
#include				<string>
#include				"mySFML.h"
 
class IEventManager
{
public:
	virtual void closeApp(sf::RenderWindow *);
};
 
typedef void (IEventManager::*FPTR)(sf::RenderWindow*);
 
class EventManager: public IEventManager
{
private:
	sf::Event currentEvent;
	sf::RenderWindow *app;
	std::map<sf::Event::EventType, FPTR> eventMap;
public:
	EventManager(sf::RenderWindow *app);
	~EventManager(void);
	void	initEventMap();
	void	treatEvents();
	void	closeApp(sf::RenderWindow *);
};


EventManager.cpp:

 
#include "EventManager.h"
 
EventManager::EventManager(sf::RenderWindow *win)
{
	app = win;
	initEventMap();
}
 
void    EventManager::closeApp(sf::RenderWindow *app)
{
	app->close();
}
 
void	EventManager::initEventMap()
{
	eventMap[(sf::Event::Closed)] = &IEventManager::closeApp;
}
 
void	EventManager::treatEvents()
{
	while (app->pollEvent(currentEvent))
	{
		if (eventMap[currentEvent.type])
		{
			 eventMap[currentEvent.type](this->app);
		}
	}
}
 
EventManager::~EventManager(void)
{
}


Le sortie de compilation:

 
1>------ Début de la génération*: Projet*: ZERO_CHECK, Configuration*: Debug Win32 ------
2>------ Début de la génération*: Projet*: c_rtype++, Configuration*: Debug Win32 ------
2>  main.cpp
2>  EventManager.cpp
2>..\src\EventManager.cpp(25): error C2064: le terme ne correspond pas à une fonction qui prend 1 arguments
2>  Génération de code en cours...
3>------ Début de la génération*: Projet*: ALL_BUILD, Configuration*: Debug Win32 ------
3>  Build all projects
4>------ Génération ignorée*: Projet*: INSTALL, Configuration*: Debug Win32 ------
4>Projet non sélectionné dans le cadre d'une génération pour cette configuration de solution 
5>------ Génération ignorée*: Projet*: PACKAGE, Configuration*: Debug Win32 ------
5>Projet non sélectionné dans le cadre d'une génération pour cette configuration de solution 
========== Génération*: 2 a réussi, 1 a échoué, 0 mis à jour, 2 a été ignoré ==========


A voir également:

1 réponse

mamiemando Messages postés 33446 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 20 décembre 2024 7 812
8 janv. 2013 à 00:34
La syntaxe du typedef me paraît bizarre.

Personnellement, pour éviter d'avoir à passer des pointeurs de fonctions, j'aurais plutôt fait un foncteur (par exemple std::less en est un dans la STL)
http://www.cplusplus.com/reference/functional/less/

... ou la généralisation d'un foncteur (un visiteur) :
https://www.boost.org/doc/libs/1_52_0/libs/graph/doc/visitor_concepts.html

Dans ton cas ton visiteur ressemblerait à ceci :

struct mon_visiteur_t {
  void close_application(sf::RenderWindow *) {
  
  }
};


Ensuite tu passes une instance de ton visiteur en paramètre de ton constructeur EventManager et l'affaire est réglée ;-) Voire ici, comme le visiteur ne stocke rien, on peut même le créer directement dans le constructeur

class EventManager: public IEventManager {
  private:
    sf::Event currentEvent;
    sf::RenderWindow *app;
    std::map<sf::Event::EventType, FPTR> eventMap;
    mon_visiteur_t vis;
  public:
    EventManager(
      sf::RenderWindow *app,
    ):
      vis()
    {
      ...
    }
};


Ensuite pour instancier ta fonction il suffit d'appeler this->vis.close_application(...).

Bonne chance
0