#0 

06-12-2008 13:11:21

Stobbyo
Membre
Date d'inscription: 06-12-2008
Messages: 16

Bonjour,

J'utilise Irrlicht bien entendu, mais le sujet de ce message n'est pas directement lié à Irrlicht.
C'est mon premier message, je poste rarement. Je n'aime pas trop m'inscrire sur les forums,
je me suis inscrit ici car j'utilise Irrlicht lol. Donc désolé, si le message n'est pas directement lié
à Irrlicht.

Je voulais savoir si il est possible de définir un pointeur de fonctions dans une classe. hmm

En fait, j'ai conçu un système de fenêtrage, pour les dialogues dans un jeu.

Dans ces fenêtres, j'affiche du texte, le nombre de lignes affichables est limité.

Si le nombre de lignes dans la conversation, est supérieur au nombre de lignes affichables,
je voudrais que la fonction pour afficher le texte ne soit pas la même.

Par exemple, afficher une flèche en bas de la fenêtre. Permettre le défilement du texte...

Bien sur, je pourrais créer une autre classe dérivant de la première, mais je voudrais faire
autrement, j'ai donc pensé aux pointeurs de fonctions.

Merci de votre attention.

A plus.

Hors ligne


#1 

06-12-2008 14:02:35

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Tout d'abord, sois le bienvenu.
C'est vrai que c'est le forum d'Irrlicht, mais bon, c'est aussi la section C++, et si cela peut t'aider à avancer dans ton projet Irrlicht, alors il n'y a pas de problème...

Pour revenir donc à ta question, hmmm, je vois à peut près ce que tu veux dires (du moins je pense).

Faisont les choses doucemenent.
Donc, supposons que nous définissions une classe, nous allons écrire:
(les nom et classe employées sont uniquement là pour l'exemple, bien sûr)

Code:

class Nomclass
{
  ...
  int (*CollideFnt)   (CEntity* scene, int a); 
  ...

  // methodes
  inline void SetCollideCallBack( int (*fC) (CEntity* scene,int a))
  {    
     CollideFnt = fC;
  }
  inline void Routine()
  {     ...
    CollideFnt(entity, val);
        ...
  }

};

puis dans le code de notre appli, nous définissons par exemple un objet

Code:

Nomclass *test

en suite, c'est simple, dans notre programme, nous pourrons définir le pointeur de notre fonction.
On code une fonction quelconque, en respectant le type de définition établi dans Nomclass

Code:

int maFonction( CEntity* scene, int a )
{ 
 ...
}

En suite, il suffit d'affecter ta fonction à la valeur définit dans ta classe:

Code:

test->SetCollideCallBack( maFonction );

puis plus loin selon tes besoin, tu pourras écrire

Code:

 test->Routine()

Tu peux donc en final changer l'appel à ta fonction en passant par la fonction 'SetCollideCallBack', en choisissant
la fonction de ton choix.

C'est un concept pas du tout évidant à appréhender, mais qui est hyper puissant. Il est très employé dans la mise
sur pieds de ce que l'on appel les CallBack (d'ou le nom utilisé plus haut).

wink


Force et sagesse...

Hors ligne


#2 

06-12-2008 15:02:23

Stobbyo
Membre
Date d'inscription: 06-12-2008
Messages: 16

Salut,

Merci beaucoup pour cette réponse détaillée !

Je vais essayer d'implémenté ça. Mon dieu que c'est compliqué lol !

Je vais réfléchir.

En fait, ce que je voudrais faire c'est une fonction membre publique qui pointe vers une fonction membre privée.

J'ai une fonction dans ma classe qui permet d'ajouter du texte,
la voici, dans son état actuel :

Code:

void CWindow::addLine(const wchar_t *text)
{
    if(text != 0)
    {
        // Calculate width of the text
        irr::core::dimension2d<irr::s32> textSize = CWindow::m_Font->getDimension(text);

        if(textSize.Width > m_TextWidth)
        {
            CWindow::m_TextWidth = textSize.Width;
        }

        // Add the text in the array
        CWindow::m_TextArray.push_back(text);
    }
}

J'aimerai la modifier en ceci :

Code:

void CWindow::addLine(const wchar_t *text)
{
     if(text != 0)
    {
        // Calculate width of the text
        irr::core::dimension2d<irr::s32> textSize = CWindow::m_Font->getDimension(text);

        if(textSize.Width > m_TextWidth)
        {
            CWindow::m_TextWidth = textSize.Width;
        }

        // Add the text in the array
        CWindow::m_TextArray.push_back(text);

        if( (CWindow::m_TextArray.size() > CWindow::m_MaxNumberOfLines) && (!CWindow::m_IsMultiline) )
        {
             drawText = &DrawTextMultiline_; // changement d'adresse 
             CWindow::m_IsMultiline = true;
        }   
    }
}

C'était juste pour préciser ce que j'aurais voulu faire.
Je posterai en cas de souci.

Merci beaucoup en tout cas smile

Dernière modification par Stobbyo (16-02-2009 15:23:54)

Hors ligne


#3 

06-12-2008 15:11:36

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Ton code éclaire un peut mieux effectivement tes souhaits.

Je suis peut-être à coté de la plaque, mais pourquoi ne pas utiliser tout simplement un bon vieux 'switch', affectant selon la situation
l'orientation vers une fonctions ou une autre ?


Force et sagesse...

Hors ligne


#4 

06-12-2008 15:23:16

Stobbyo
Membre
Date d'inscription: 06-12-2008
Messages: 16

lol non tu n'es pas à côté de la plaque, je vais changer de système.

En effet, je modifierai le booléen : m_IsMultiLine .
Et appellerai la méthode en fonction de cette valeur.
Ce sera sans aucun doute plus simple.

A plus et merci encore smile

Dernière modification par Stobbyo (06-12-2008 15:24:16)

Hors ligne


#5 

06-12-2008 15:26:42

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Pas de quoi, j'espère que nous auront l'occasion de te recroiser ici régulièrement
smile


Force et sagesse...

Hors ligne


#6 

17-12-2008 19:33:23

Stobbyo
Membre
Date d'inscription: 06-12-2008
Messages: 16

Salut wink

J'ai continué à chercher pour pouvoir mettre en place ce que j'aurais voulu faire.

J'utilise une classe "statique", donc ça simplifie la mise en place, je donne cet exemple,

ça aidera peut-être quelqu'un :

Code:

#include <iostream>

enum TYPE { HELLO, SALUT, HOLA };

// displayPtr devient un type de pointeur sur fonctions
typedef void (*displayPtr)(void);

class Test
{

public :
    
    // On crée un pointeur de fonctions de ce type
    static displayPtr  display;
    
    // On change l'adresse de la fonction
    static void setType(const TYPE type)
    {
        switch(type)
        {
            case(HELLO) :
            {
                display = &displayHello;

                break;
            }

            case(SALUT) :
            {
                display = &displaySalut;

                break;
            }

            case(HOLA) :
            {
                display = &displayHola;

                break;
            }

            default :
            {
                break;
            }
        }
    }

private :

    static void displayHello(void)
    {
        std::cout<<"Hello"<<std::endl;
    }

    static void displaySalut(void)
    {
        std::cout<<"Salut"<<std::endl;
    }

    static void displayHola(void)
    {
        std::cout<<"Hola"<<std::endl;
    }
};

// Initialise les variables statiques
displayPtr Test::display = 0;

int main(void)
{
    // On ne peut pas faire ça car la fonction ne pointe sur rien ( 0 )
    // Test::display(); // segmentation fault
    
    // Il faut donc donner une adresse valide au pointeur de fonctions
    Test::setType(HELLO);

    Test::display();

    Test::setType(SALUT);

    Test::display();

    Test::setType(HOLA);

    Test::display();
    
    return 0;
}

C'est vrai que c'est puissant.

Voici deux liens qui m'ont aidé, sans oublier l'explication précédente de tmyke smile

The Function Pointer Tutorials

Pointers to C++ Member Functions

J'ai par contre encore du mal à comprendre le principe de "CallBack" mais ça viendra lol.

A plus !

Dernière modification par Stobbyo (18-12-2008 15:55:29)

Hors ligne


#7 

17-12-2008 19:36:02

tmyke
Administrateur
Date d'inscription: 24-03-2008
Messages: 1025

Merci pour ta contribution, cool wink


Force et sagesse...

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1427 sujets
11117 messages
Dernier membre inscrit: Bidule
53 invités en ligne
Aucun membre connecté
RSS Feed