IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Action limité dans le temps


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Points : 68
    Points
    68
    Par défaut Action limité dans le temps
    Bonjour,

    Je souhaiterais limité dans le temps l'action d'une méthode d'une classe.
    J'ai pensé au thread et au timer mais mon esprit est encore confus.

    Voici l'idée très simple (en soit) de mon projet :

    je lis un son à l'aide de la librairie SndObj

    J'ai un fichier texte à côté dans lequel j'indique qu'à la 5ème seconde on entend un homme parler.

    son.txt :

    Je souhaite lire mon fichier texte et afficher à la 5ème seconde de la lecture du fichier son le texte correspondant. Un peu comme des sous-titre.

    L'idée final est en réalité de manipuler une image et de modifier son aspect de façon séquentiel en fonction d'un son. Comme si je crée une ligne de temps et que je venais placer des événements se déclenchant à un temps t1 donné par le fichier son et qui s'arrête à un temps t2 donnée aussi par le fichier son. La ligne séquentielle étant donnée par le fichier texte.

    Mes effet suivent une structure du style :

    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
    16
    17
    18
    19
    20
     
     
    class Effect{
     
    protected:
    		int      m_startTime;
    		int      m_stopTime;
    		int      m_duree;
    		char     m_activity;
     
    public:
     
    //Destructor
    		virtual ~Effect();
     
    	void start(void);
            void stop(void);
     
            virtual void update(void) = 0;
    };
    ainsi dans le corps du programme je souhaiterais appeler mon effet à l'aide de start() et qu'il s'arrête lorsque la valeur stopTime est atteinte.

    J'ai voulu utiliser des timer que j'associe à mes objets... mais cette solution ne semble pas idéale et surtout ne fonctionne pas :
    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
    16
    17
    18
    19
    20
    21
    22
    23
     
    void Effect::start(void)
    {
        struct itimerval timerEffect;
    	int duree = m_duree; //en secondes
    	int u_duree = 0; //en milliseconde
    	timerEffect.it_interval.tv_sec = 0;
    	timerEffect.it_interval.tv_usec = 0;
    	timerEffect.it_value.tv_sec = duree; /* set timer for variable duree in seconds */
    	timerEffect.it_value.tv_usec = u_duree; /* set timer for variable u_duree in milliseconds */
    	setitimer(ITIMER_REAL, &tout_val,0);
     
    	signal(SIGALRM,stop); /* set the Alarm signal capture */
     
        m_activity = 1;
    }
     
    void Effect::stop(void)
    {
            m_activity = 0;
    	cout<<"Timer finished : fin"<<endl;
    	signal(SIGALRM,stop);
    }

    Ça ne passe pas la compilation et je m'en doutais bien car la fonction associé au timer doit être une fonction et non une méthode....

    Je ne vois donc pas comment faire.

    Une idée ??

    Merci d'avance !


    Merci d'avance pour votre aide.

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    J'ai rencontré ce problème quand j'ai voulu utiliser OpenGL. Tu ne peux pas passer une méthode d'objet, qui requiert un type de pointeur spécifique, mais tu peux par contre passer une méthode de classe (déclarée avec static) ; si tu peux trouver un moyen d'appeler la méthode nécessaire sur l'objet dont tu as besoin en passant par cette méthode static, ça ira. Tu auras peut-être besoin de recourrir à d'autres ruses, utiliser un pattern comme le singleton, par exemple.

  3. #3
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par SpongeBob Voir le message

    Ça ne passe pas la compilation et je m'en doutais bien car la fonction associé au timer doit être une fonction et non une méthode....
    Tu peux préciser le prototype?
    (peut etre tu peux t'en sortir avec boost::bind)

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 129
    Points : 68
    Points
    68
    Par défaut
    Comme je l'ai compris :

    l'appel de signal system nécessite l'utilisation de fonctions global ou statique et non une fonction membre C++ comme celle-ci ( stop() ).

    Comme je souhaite faire des actions spécifique suivant les objets, cette méthode de l'utilisation du timer n'est pas viable.

    Donc Bind je vois pas trop ce que ça vient faire ici.

    Pouvons-nous approfondir cette idée ?


    Noxen qu'elle est plus précisément ton idée ?

    Merci à vous

  5. #5
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Je pensais à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    signal(SIGALRM, boost::bind(&Effect::stop, *this) )
    bind est fait pour ça, non ?

  6. #6
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    L'initialisation de glut et opengl nécessite de lui passer des pointeurs vers des fonctions. Par exemple, il y a besoin d'une fonction d'affichage pour que la bibliothèque sache ce qu'elle doit afficher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void paintApp(){ .... } // fonction d'affichage de l'application
     
    int main(){
    .....
        glutDisplayFunc(paintApp); // glut a besoin qu'on lui passe une fonction void func (void)
    ...
    }
    A la place on peut lui passer une méthode de classe, static:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class LibraryInterface{
    public:
        static void paint() { .... }
    ......
    };
     
    int main(){
        glutDisplayFunc(LibraryInterface::paint);
    ....
    }
    Sauf que tu peux mémoriser des informations dans ta classe via des variables static (entre autre). Donc dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class LibraryInterface{
    private:
        static Effect* currentEffect;
    ...
    public:
        void setEffect(Effect* ef) {currentEffect = ef;}
     
        void stopEffect() { if(currentEffect) currentEffect->stop(); }
     
    .....
    };
    Et dans le code appellant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Effect::start(){
    ....
     
        LibraryInterface::setEffect(this);
        signal(SIGALRM, LibraryInterface::stopEffect);
    ...
    }
    Ceci-dit, je ne connais pas boost::bind, alors il est très possible que ce soit une meilleure solution.

  7. #7
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par Noxen Voir le message
    Ceci-dit, je ne connais pas boost::bind, alors il est très possible que ce soit une meilleure solution.
    Ben tu peux vraiment faire ce que tu veux avec boost::bind (et même std::tr1::bind maintenant ). C'est fait pour ça! Pas besoin de changer ton code...

  8. #8
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    Il va vraiment faloir que je m'accorde un peu de temps pour étudier boost

  9. #9
    Membre à l'essai
    Inscrit en
    Septembre 2008
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 21
    Points : 24
    Points
    24
    Par défaut
    Je suis pas certain que l'utilisation d'un signal soit le plus pertinent dans le cas que tu décris (mais je suis pas un unixien de base, et l'utilisation des signaux n'est pas ma spécialité).

    Tu pourrais stoker l'ensemble de tes événements (les objets Effect) dans un container et traiter cette liste soit avec une boucle suivit éventuellement d'un Sleep ou d'une synchro vidéo (cas classique des programme d'animation 2D ou 3D), soit utiliser un thread dédié aux effets et qui attendrait sagement à l'aide d'un sleep le moment du prochain événement.

    Si tu veux tout de même utilisé un signal, il suffit que tu le programme pour appeler une fonction traitant le conteneur d'effets.

    L'utilisation d'une thread+sleep est proche de l'utilisation du signal, dans les deux cas, il faut que tu programme la duré a attendre en fonction du prochain effet à jouer.

    Par contre, dans le cas de la boucle d'affichage, il te suffit de vérifier à chaque tour de boucle si l'effet en tête du conteneur doit être jouer 'maintenant'.

    Dans tous les cas, peux être dicté par la précision temporelle que tu cherches à atteindre (en dessous de qlq 10aine de ms, ça devient très difficile)

Discussions similaires

  1. Réponses: 19
    Dernier message: 22/11/2008, 13h50
  2. Limiter dans le temps un téléchargement
    Par MANU_2 dans le forum Général Conception Web
    Réponses: 13
    Dernier message: 23/01/2008, 18h31
  3. Limiter dans le temps mon code Java
    Par GLDavid dans le forum Langage
    Réponses: 3
    Dernier message: 17/04/2007, 09h22
  4. [Licence]Programme limité dans le temps
    Par tof.p dans le forum Général Java
    Réponses: 2
    Dernier message: 28/10/2005, 14h09
  5. Réponses: 5
    Dernier message: 06/05/2005, 19h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo