Forum de la communauté SFML

Général => Suggestions de nouvelles fonctionnalités => Discussion démarrée par: L01man le Avril 27, 2012, 10:52:05 am

Titre: [Résolu] Une classe Group héritant de Drawable
Posté par: L01man le Avril 27, 2012, 10:52:05 am
EDIT : une page sur le wiki (https://github.com/SFML/SFML/wiki/TutorialDrawableGroup) a été créée.

Je pense qu'il manque un dernier enfant à Drawable pour que la famille soit complète. Dans d'autres frameworks, comme Pygame ou Pyglet, j'ai récemment remarqué que cette classe était déjà implémentée. Avant, j'avais vite trouvé le besoin de la créer, et je pense qu'à partir d'un certain niveau d'abstraction tout le monde en a besoin.
#ifndef GROUP_INCLUDED_HPP
#define GROUP_INCLUDED_HPP

#include "Drawable.hpp"

class Group : public sf::Drawable, public std::vector<sf::Drawable*> {
public:
Group();
~Group();

void render(sf::RenderTarget&) const;
};

#endif
#include "group.hpp"

Group::Group() :
sf::Drawable(),
std::vector<sf::Drawable*>() {
}
Group::~Group() {
for(std::vector<sf::Drawable*>::iterator i = begin(); i != end(); ++i) {
delete *i;
}
}

void Group::render(sf::RenderTarget& Tar) const {
for(std::vector<sf::Drawable*>::iterator i = begin(); i != end(); ++i) {
Tar.draw(*i);
}
}
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 27, 2012, 12:19:41 pm
Ouaip, sauf qu'il y a un choix à faire quant à l'ownership des éléments, et que ce choix sera certainement différent pour chacun. Et comme la moitié du code de la classe concerne ce truc, ça ne servirait à rien d'en fournir une version officielle qui de toute façon ne satisfera jamais à 100% les gens.
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Avril 27, 2012, 07:08:15 pm
Excuse-moi, que veux-tu dire par "ownership des éléments" ?
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 27, 2012, 07:32:48 pm
Qui prend la responsabilité de les détruire.
Titre: Re : Une classe Group héritant de Drawable
Posté par: lezebulon le Avril 27, 2012, 09:22:59 pm
Ca serait pas plus cool d'hériter de std::vector<std::unique_ptr<sf::Drawable*>> et du coup pas de prise de tête d'ownership? (et de destructeur)
Titre: Re : Une classe Group héritant de Drawable
Posté par: Nexus le Avril 27, 2012, 10:35:24 pm
Je pense que hériter de std::vector est une mauvaise idée en général. Il serait mieux de garder std::vector comme membre et d'offrir quelques méthodes pour l'accès (si nécessaire).

Et lezebulon, tu veux dire std::unique_ptr<sf::Drawable> sans étoile ;)
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 27, 2012, 10:37:16 pm
Citer
Ca serait pas plus cool d'hériter de std::vector<std::unique_ptr<sf::Drawable*>> et du coup pas de prise de tête d'ownership? (et de destructeur)
Mon point n'était pas technique mais conceptuel : parfois tu voudras que le groupe prenne l'ownership des éléments, et parfois au contraire tu voudras simplement qu'il stocke des pointeurs vers des objets gérés ailleurs. On ne peut pas trancher définitivement.
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Avril 28, 2012, 11:47:03 am
Ah, le problème est donc Group::~Group(). Dans ce cas, on peut ajouter une variable "hasOwnership" qui détermine si, à sa destruction, le groupe détruit ses items ou non.
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 28, 2012, 12:19:59 pm
Et peut-être que quelqu'un voudra des responsabilités partagés, et donc utiliser des std::shared_ptr dans sa classe Group.

On peut toujours trouver des solutions techniques qui semblent résoudre le problème immédiat, mais si on prend du recul ça ne marche pas. Comme je l'ai déjà dit c'est un problème de conception, ça ne sert à rien d'ajouter des booléens ou autre.
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Avril 28, 2012, 10:59:39 pm
Je vois. Pourtant, dans Pygame & cie., cette classe est bien présente et semble convenir à tous ! A vrai dire, les cas de figure qui seraient problématiques ne me viennent pas à l'esprit. On devrait les énumérer pour voir si une solution est possible. Par exemple, rendre Group abstraite pour que chacun l'implémente comme il veut ou fournir plusieurs Group qui couvrent toutes les utilisations.
En ce qui me concerne, je vois trois utilisations : Dans le premier cas, le Group est sensé n'être détruit qu'à la fin du programme. Dans le deuxième, aussi. Dans le troisième, le Group est bien considéré comme un objet et pas comme un "tiroir", et ses éléments lui appartiennent. Donc, pour tous ces cas, il est normal que le Group détienne l'ownership.
On peut aussi très bien copier l'adresse d'un élément vers un autre endroit et faire un erase() pour que le Group n'ait plus cet ownership.
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 28, 2012, 11:02:55 pm
Citer
Pourtant, dans Pygame & cie., cette classe est bien présente et semble convenir à tous !
Python est un langage interprété qui possède un ramasse-miettes, il n'y a pas notion explicite d'ownership pour le programmeur.

Citer
Par exemple, rendre Group abstraite pour que chacun l'implémente comme il veut
Ca n'avancerait pas beaucoup les gens dans ce cas, ça ne ferait que leur imposer une interface figée.

Citer
ou fournir plusieurs Group qui couvrent toutes les utilisations.
Plusieurs variantes d'une classe pour une seule fonctionnalité bien spécifique, ça ferait un peu bourrin pour SFML ;)
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Avril 29, 2012, 11:36:11 am
D'accord x). Pourrait-on au moins en proposer une version dans les tutoriels, afin que les débutants aient une base ?
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 29, 2012, 12:56:05 pm
Pas dans les tutoriels non, mais mets-en une sur le wiki si tu veux :)
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Avril 30, 2012, 06:08:05 pm
C'est fait. (https://github.com/SFML/SFML/wiki/TutorialDrawableGroup)
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Avril 30, 2012, 06:57:45 pm
Pourquoi est-ce que personne ne lit jamais les règles avant de créer des pages sur le wiki ? C'est vraiment pénible >:(

Sinon :
- tu devrais indiquer que ton code est pour SFML 1.6
-- pourquoi ne pas le faire en 2.0 ? plus personne n'utilisera 1.6 bientôt
- le code de ton destructeur a trop de lignes de code pour ce qu'il fait :P
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Mai 01, 2012, 12:26:40 am
Désolé pour le titre. C'était pourtant un paragraphe sur l'accueil du wiki, mais peut-être pas assez visible. Il n'y a pas moyen d'afficher ce message sur la page d'édition ?
Voilà, j'ai précisé. En fait, qu'est-ce qui change, pour ce code, avec SFML 2.0 ? J'en déduis que je suis l'un des rares à encore utiliser la 1.6 :D. Je ferai bientôt le changement, alors.
Ca va mieux, pour le dtor ?
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Mai 01, 2012, 09:43:14 am
Citer
Il n'y a pas moyen d'afficher ce message sur la page d'édition ?
Non, malheureusement. Ce serait bien pratique en effet.

Citer
En fait, qu'est-ce qui change, pour ce code, avec SFML 2.0 ?
La classe Drawable n'est plus la même, les fonctions sont en lowerCamelCase, etc.

Citer
Ca va mieux, pour le dtor ?
Oui, mais :
- ce serait mieux avec un itérateur ;D
- le clear() est inutile, ton objet est en train d'être détruit de toute façon
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Mai 01, 2012, 11:39:43 am
Et voilà ! Notons quand-même qu'avec Haskell, par exemple, on écrirait simplement :
map draw group pour remplacer la méthode Draw().
Titre: Re : Une classe Group héritant de Drawable
Posté par: Lo-X le Mai 01, 2012, 10:46:56 pm
Je suis pas sur d'avoir vraiment compris l'utilité d'une telle classe.

En gros c'est un tableau de pointeur sur ce que tu dois dessiner ?
Titre: Re : Une classe Group héritant de Drawable
Posté par: Laurent le Mai 01, 2012, 10:56:15 pm
Ca permet d'aggréger plusieurs entités comme étant une seule, et d'affecter une position, rotation, ... à tout le groupe, en plus des transformations individuelles des entités qui le composent.
Titre: Re : Une classe Group héritant de Drawable
Posté par: L01man le Mai 01, 2012, 11:03:02 pm
EDIT : grillé
C'est ça. Mais on peut appeler Draw dessus, puisque c'est un Drawable lui-même. Ca permet de faire des
layers, de faire des corps articulés, des calculs de collisions sur un groupe précis d'objets en évitant de parcourir une liste entière d'objets, etc.
Titre: Re : Une classe Group héritant de Drawable
Posté par: Lo-X le Mai 01, 2012, 11:13:17 pm
Ah ok, merci