Bonjour à tous.
Voici ma classe qui me permet de charger une scène 3D depuis un fichier xml.
J'utilise la bibliothèque libxml++ qui à chaque fois qu'elle rencontre un noeud récupère son nom ainsi que tous ses attributs.
Son nom est sous forme de caractères donc impossible de switcher et hors de question de faire des if, ca deviendrait vite fait illisible. J'utilise donc un map avec le nom en clé, et un pointeur sur fonction en valeur, dont le rôle est de traiter un noeud xml en fonction de son nom.
La méthode on_start_element est appelé à chaque début de noeud
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 //////////////////////////////////////////////////////////////// // Cette classe permet de charger une scène 3D depuis un fichier xml //////////////////////////////////////////////////////////////// class _sd_Export_ SceneParser : public xmlpp::SaxParser { private: /** * Objet Root utilisé pour créer la scène. */ Ogre::Root* mRoot; /** * Objet SceneManager utilisé pour créer des entitées... */ Ogre::SceneManager* mSceneManager; /** * Node parent pour la création des nodes enfants présents dans le fichier xml. */ Ogre::SceneNode* mParentNode; /** * Liste des nodes. * @Note * A chaque node que l'on rencontre on l'insert dans le conteneur. Si on rencontre la * balise de fin de node on le supprime du conteneur car il n'aura pas d'autre node enfant. */ typedef std::stack<Ogre::SceneNode*> NodeStack; NodeStack mNodesList; /** * Type pointeur de méthode de traitement d'une balise. * @Note * Chaque méthode traite une balise spécifique en fonction du type de la balise (son nom). */ typedef void (*ElementParser)(const AttributeList&s); /** * Ce map contient une chaine de caractère en clé (nom de la balise) associée à une méthode de traitement d'une balise. */ typedef std::map<Glib::ustring, ElementParser> ParserMap; ParserMap mParserMap; public: //...................................................... // Constructeur par défaut. //...................................................... SceneParser(Ogre::Root* myRoot); //...................................................... // Destructeur. //...................................................... virtual ~SceneParser(); protected: //...................................................... // SaxParser::on_start_element(). //...................................................... virtual void on_start_element(const Glib::ustring& name, const AttributeList& attributes); //...................................................... // SaxParser::on_end_element(). //...................................................... virtual void on_end_element(const Glib::ustring& name); };
On voit donc que cette méthode est très courte et qu'elle délègue le travail aux fonctions approprié (préalablement enregistrée dans le map)
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 void SceneParser::on_start_element(const Glib::ustring& name, const AttributeList& attributes) { Logger::Log() << " Début de l'élément : " << name << ".\n"; Logger::Log() << " Nom du noeud : " << name << "\n"; // On affiche les attributs du noeud courant. for(xmlpp::SaxParser::AttributeList::const_iterator Iter = attributes.begin(); Iter != attributes.end(); ++Iter) { Logger::Log() << " Attribut : " << Iter->name << " = " << Iter->value << "\n"; } // Rechercher la fonction associée à l'élément. ParserMap::const_iterator It = mParserMap.find(name); if(It != mParserMap.end()) { // On appelle la fonction associée. (It->second)(attributes); } }
Voici donc mes questions :
Comment insérer des pointeurs sur fonctions membres dans mon map puisque ce ne sont pas des fonctions simples et comment déclarer ce map?
PS : désolé Davidbrcz j'ai modifier au dernier moment, m'en veux pas ^^
Partager