Partage
  • Partager sur Facebook
  • Partager sur Twitter

classe Gestion evenement.

[SDL C++.]

    3 juillet 2007 à 3:15:26

    Bonjour à toutes et tous, voilà, je souhaitais concevoir une classe de gestion des evenements automatique.

    Citation : Zero

    ? Gnneeuu il dit quoi lui??? T'as encore bus Castorus avoue !


    Mais non, attendez, je m'explique.
    Le principe que je voulais mettre en oeuvre et que j'ai developpé est plutôt simple dans le fond :

    la classe possède des methodes virtuelles correspondant au déclenchement d'evenements (pas tous pour le moment j'en ais juste mis quelques uns pour tester) (exemple : virtual void OnQuitEvent(); ou Encore virtual void OnKeyDownEvent(); ou virtual void OnMouseMotion();)

    Bien, ces méthodes seront déclenchées par une autre méthode (static void CallBack(Uint32 SliceTime,void* param); qui teste les éventuels évenements ayant étés déclenchés)
    Cette méthode est un callback qui servira à un timer de la classe se déclenchant toutes les 50ms.

    Bon, donc pour definir ces évenements, il faut surcharger les méthodes de déclenchement d'évenement dans une classe fille (polymorphisme oblige ^^).
    Voici donc à quoi ça ressemble :

    class EventManager
    {
    protected:
    SDL_Event event;
    SDL_TimerID timer;
    bool Keys[500];
    public:
    EventManager();
    virtual void OnRightKeyDown(){}
    virtual void OnLeftKeyDown(){}
    virtual void OnUpKeyDown(){}
    virtual void OnDownKeyDown(){}
    virtual void OnRightKeyUp(){}
    virtual void OnLeftKeyUp(){}
    virtual void OnUpKeyUp(){}
    virtual void OnDownKeyUp(){}
    virtual void OnQuitEvent(){}
    virtual void OnKeydownEvent(){}
    virtual void OnKeyupEvent(){}
    virtual void OnEscapeKeyDown(){}
    virtual void OnEscapeKeyUp(){}
    static Uint32 CallBack(Uint32 sliceTime,void* param);
    virtual ~EventManager();
    };



    EventManager::EventManager()
    {
      for(int i = 0;i<500;i++)
      Keys[i]=false;
      this->timer = SDL_AddTimer(50,EventManager::CallBack,this);
    }

    Uint32 EventManager::CallBack(Uint32 sliceTime,void* param)
    {
    EventManager* acces = (EventManager*)param;
     
     while(SDL_PollEvent(&(acces->event)))
     {
     
        switch(acces->event.type)
        {
        case SDL_QUIT:
        acces->OnQuitEvent();
        break;
        case SDL_KEYDOWN:
        acces->OnKeydownEvent();
           
           switch(acces->event.key.keysym.sym)
           {
           case SDLK_ESCAPE:
           acces->Keys[SDLK_ESCAPE]=true;
           break;
           case SDLK_LEFT:
           acces->Keys[SDLK_LEFT]=true;
           break;
           case SDLK_RIGHT:
           acces->Keys[SDLK_RIGHT]=true;
           break;
           case SDLK_UP:
           acces->Keys[SDLK_UP]=true;
           break;
           case SDLK_DOWN:
           acces->Keys[SDLK_DOWN]=true;
           break;
           }

        break;
        case SDL_KEYUP:
        acces->OnKeyupEvent();
           switch(acces->event.key.keysym.sym)
           {
           case SDLK_ESCAPE:
           acces->Keys[SDLK_ESCAPE]=false;
           break;
           case SDLK_LEFT:
           acces->Keys[SDLK_LEFT]=false;
           break;
           case SDLK_RIGHT:
           acces->Keys[SDLK_RIGHT]=false;
           break;
           case SDLK_UP:
           acces->Keys[SDLK_UP]=false;
           break;
           case SDLK_DOWN:
           acces->Keys[SDLK_DOWN]=false;
           break;
           }     
        break;
        }
     }


        if(acces->Keys[SDLK_LEFT])
        acces->OnLeftKeyDown();
        if(acces->Keys[SDLK_RIGHT])
        acces->OnRightKeyDown();
        if(acces->Keys[SDLK_DOWN])
        acces->OnDownKeyDown();
        if(acces->Keys[SDLK_UP])
        acces->OnUpKeyDown();
        if(acces->Keys[SDLK_ESCAPE])
        acces->OnEscapeKeyDown();
        if(!acces->Keys[SDLK_LEFT])
        acces->OnLeftKeyUp();
        if(!acces->Keys[SDLK_RIGHT])
        acces->OnRightKeyUp();
        if(!acces->Keys[SDLK_DOWN])
        acces->OnDownKeyUp();
        if(!acces->Keys[SDLK_UP])
        acces->OnUpKeyUp();
        if(!acces->Keys[SDLK_ESCAPE])
        acces->OnEscapeKeyUp();   

    return 50;
    }


    EventManager::~EventManager()
    {
    SDL_RemoveTimer(timer);
    }
     


    Voila, donc pour bénéficier des avantages de cette classe, on doit créer une classe fille de EventManager :

    class FilleEventManager : public EventManager
    {
    public:
       void OnEscapeKeyDown()
       {
       fprintf(stderr,"Appel a OnEscapeKeyDown de la classe FilleEventManager via un Timer.\n");
       }
       void OnQuitEvent()
       {
       fprintf(stderr,"Appel a OnQuitEvent de la classe FilleEventManager via un Timer.\n");
       }
       void OnKeyDownEvent()
       {
       fprintf(stderr,"Appel a OnKeyDownEvent de la classe FilleEventManager via un Timer.\n");
       }
    };



    Bon..... donc... c'est "censé" marcher, mais... parce qu'il y a un mais, ça ne marche pas O_ô, Je ne comprend pas pourquoi la detection d'evenement ne se fait pas.
    Pouvez-vous m'aider à comprendre [ma;mes] erreurs?
    Merci d'avance @bientôt.
    • Partager sur Facebook
    • Partager sur Twitter
      3 juillet 2007 à 16:11:09

      Comment ça "ça ne marche pas" ?
      Qu'est-ce qui ne va pas? Rien d'affiché? Quelles fonctions sont/ne sont pas appelées?
      Façon simple de savoir : un cout dans chaque fonction(ou msgbox, ou bien tu DEBUG avec un bon debugger ^^).
      • Partager sur Facebook
      • Partager sur Twitter
        3 juillet 2007 à 18:24:35

        c'est interressant de creer un fichier qui te dit si tes variables ont bien été modifié

        (ou qu'un pointeur ne renvoie pas NULL...)
        • Partager sur Facebook
        • Partager sur Twitter
          3 juillet 2007 à 20:48:02

          Et bah c'est à dire que dans le fichier stderr.txt situé dans C:\Dev-Cpp\
          Bha ça met pas les phrases, alors que j'ai surcharger lesméthodes dans une classe fille.

          Donc ça marche pas... je comprend pas pourquoi snif...
          • Partager sur Facebook
          • Partager sur Twitter
            3 juillet 2007 à 21:40:14

            Et t'as pas de stderr.txt dans le dossier de ton binaire ?
            • Partager sur Facebook
            • Partager sur Twitter
              3 juillet 2007 à 23:49:09

              Bha si, mais le soucis c'est que ça écrit pas dedant là, donc ça signifie que ça arrive pas executer les méthodes surchargées (qui devraient pourtant etre bien appelées)
              Pourtant avec des test annexes d'écriture dans le stderr y'a pas de soucis...

              Ah oui par contre j'ai ciblé le problème apparement, si l'application est dans une boucle infinie, un timer executant un callback qui pousse les evenements dans un SDL_Event ne peu pas parvenir à le faire.... pourquoi je sais pas, mais j'ai essayé de raffraichir le SDL_Event de la classe FilleEventManager dans la boucle du jeu, et la ça marche... Allez savoir pourquoi hein...

              Comme ceci je veux dire :

              #include <SDL/SDL.h>
              #include <stdio.h>

              using namespace std;



              class EventManager
              {
              protected:
              SDL_Event event;
              SDL_TimerID timer;
              bool Keys[500];
              public:
              EventManager();
              virtual void OnRightKeyDown(){}
              virtual void OnLeftKeyDown(){}
              virtual void OnUpKeyDown(){}
              virtual void OnDownKeyDown(){}
              virtual void OnRightKeyUp(){}
              virtual void OnLeftKeyUp(){}
              virtual void OnUpKeyUp(){}
              virtual void OnDownKeyUp(){}
              virtual void OnQuitEvent(){}
              virtual void OnKeydownEvent(){}
              virtual void OnKeyupEvent(){}
              virtual void OnEscapeKeyDown(){}
              virtual void OnEscapeKeyUp(){}
              static Uint32 CallBack(Uint32 sliceTime,void* param);
              virtual ~EventManager();
              };



              EventManager::EventManager()
              {
                for(int i = 0;i<500;i++)
                Keys[i]=false;
                this->timer = SDL_AddTimer(50,EventManager::CallBack,this);
              }

              Uint32 EventManager::CallBack(Uint32 sliceTime,void* param)
              {
              EventManager* acces = (EventManager*)param;
               

               

                  switch(acces->event.type)
                  {
                  case SDL_QUIT:
                  acces->OnQuitEvent();
                  break;
                  case SDL_KEYDOWN:
                  acces->OnKeydownEvent();
                     
                     switch(acces->event.key.keysym.sym)
                     {
                     case SDLK_ESCAPE:
                     acces->Keys[SDLK_ESCAPE]=true;
                     break;
                     case SDLK_LEFT:
                     acces->Keys[SDLK_LEFT]=true;
                     break;
                     case SDLK_RIGHT:
                     acces->Keys[SDLK_RIGHT]=true;
                     break;
                     case SDLK_UP:
                     acces->Keys[SDLK_UP]=true;
                     break;
                     case SDLK_DOWN:
                     acces->Keys[SDLK_DOWN]=true;
                     break;
                     }

                  break;
                  case SDL_KEYUP:
                  acces->OnKeyupEvent();
                     switch(acces->event.key.keysym.sym)
                     {
                     case SDLK_ESCAPE:
                     acces->Keys[SDLK_ESCAPE]=false;
                     break;
                     case SDLK_LEFT:
                     acces->Keys[SDLK_LEFT]=false;
                     break;
                     case SDLK_RIGHT:
                     acces->Keys[SDLK_RIGHT]=false;
                     break;
                     case SDLK_UP:
                     acces->Keys[SDLK_UP]=false;
                     break;
                     case SDLK_DOWN:
                     acces->Keys[SDLK_DOWN]=false;
                     break;
                     }     
                  break;
                  }
               


                  if(acces->Keys[SDLK_LEFT])
                  acces->OnLeftKeyDown();
                  if(acces->Keys[SDLK_RIGHT])
                  acces->OnRightKeyDown();
                  if(acces->Keys[SDLK_DOWN])
                  acces->OnDownKeyDown();
                  if(acces->Keys[SDLK_UP])
                  acces->OnUpKeyDown();
                  if(acces->Keys[SDLK_ESCAPE])
                  acces->OnEscapeKeyDown();
                  if(!acces->Keys[SDLK_LEFT])
                  acces->OnLeftKeyUp();
                  if(!acces->Keys[SDLK_RIGHT])
                  acces->OnRightKeyUp();
                  if(!acces->Keys[SDLK_DOWN])
                  acces->OnDownKeyUp();
                  if(!acces->Keys[SDLK_UP])
                  acces->OnUpKeyUp();
                  if(!acces->Keys[SDLK_ESCAPE])
                  acces->OnEscapeKeyUp();   

              return 50;
              }


              EventManager::~EventManager()
              {
              SDL_RemoveTimer(timer);
              }



              class FilleEventManager : public EventManager
              {
              protected:
              bool continuer;
              public:
                 FilleEventManager(){continuer = true;}
                 void OnEscapeKeyDown()
                 {
                 fprintf(stderr,"Appel a OnEscapeKeyDown de la classe FilleEventManager via un Timer.\n");
                 continuer = false;
                 }
                 void OnQuitEvent()
                 {
                 fprintf(stderr,"Appel a OnQuitEvent de la classe FilleEventManager via un Timer.\n");
                 continuer = false;
                 }
                 void OnKeyDownEvent()
                 {
                 fprintf(stderr,"Appel a OnKeyDownEvent de la classe FilleEventManager via un Timer.\n");
                 }
                 bool GetContinuerField(){return continuer;}
                 SDL_Event* GetEventField(){return &event;}
              };


              int main(int argc, char *argv[])
              {

              SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
              SDL_Surface* Ecran = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE);

              FilleEventManager* eventManage = new FilleEventManager;

                while(eventManage->GetContinuerField())
                {
                  SDL_PollEvent(eventManage->GetEventField());   
                //OnBoucle.
                }


              delete eventManage;

              SDL_Quit();

              return EXIT_SUCCESS;
              }
               



              Quelqu'un peu m'exposer une solution peu être?
              • Partager sur Facebook
              • Partager sur Twitter
                4 juillet 2007 à 0:37:01

                Salut !

                Ce que je ferais, pour débugger, c'est créer une fonction void debug( string str) qui à chaque appel ajoute une ligne avec le contenue de str dans un fichier. ( un peu le principe de ton stderr ) Et tu appelle cette fonction à des endroits stratégiques de ton code en lui passant des paramètres claires qui expliquent ce que le programme est en train de faire, donc en regardant dans ton fichiers tu vois tout ce qu'à fait le programme, mais aussi ce qu'il a pas fait. Et tu cernes de plus en plus le problème en rajoutant des appels à cette fonction. ( Pense à la mettre au tout début du programme pour voir si elle marche ^^ )
                • Partager sur Facebook
                • Partager sur Twitter
                  4 juillet 2007 à 12:10:41

                  Essaye ça:

                  class EventManager
                  {
                  protected:
                  SDL_Event event;
                  SDL_TimerID timer;
                  bool Keys[500];
                  public:
                  EventManager();
                  virtual void OnRightKeyDown(){};
                  virtual void OnLeftKeyDown(){};
                  virtual void OnUpKeyDown(){};
                  virtual void OnDownKeyDown(){};
                  virtual void OnRightKeyUp(){};
                  virtual void OnLeftKeyUp(){};
                  virtual void OnUpKeyUp(){};
                  virtual void OnDownKeyUp(){};
                  virtual void OnQuitEvent(){};
                  virtual void OnKeydownEvent(){};
                  virtual void OnKeyupEvent(){};
                  virtual void OnEscapeKeyDown(){};
                  virtual void OnEscapeKeyUp(){};
                  static Uint32 CallBack(Uint32 sliceTime,void* param);
                  virtual ~EventManager();
                  };
                   
                  Les accolades ne dispensent pas les points-virgules.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    4 juillet 2007 à 14:00:40

                    Ben si, quand tu déclares une fonction tu mets pas de point-virgule après, ce ne sont pas des prototypes mais bien des déclarations.

                    Edit : pour castorus : j'ai testé chez moi ton code fonctionne ( mais pas la methode OnKeyDownEvent() mais par exemple su je surcharge void OnRightKeyDown()

                    void OnRightKeyDown()
                       {
                           fprintf(stderr,"Appel a OnRightKeyDown de la classe FilleEventManager via un Timer.\n");
                        }

                    Ca fonctionne tout à fait.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    classe Gestion evenement.

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown