Gestionnaires de ressources - sont-ils bons?

20

J'ai vu plusieurs fois dans le code source, des choses comme ça [eh bien, c'est plus une pseudo idée C ++ à moi]

typedef shared_ptr<Resource> ResourcePtr;// for ease  
ResourcePtr sound1 = resourceManager.Get<SoundResource>("boom.ogg");  
sound1->Play();  
ResourcePtr sprite = resourceManager.Get<Image>("sprite.png");

Je me demandais juste à quel point une classe comme celle-ci était utile, quelque chose qui:

  • Fichiers multimédias chargés
  • Les a stockés en mémoire
  • A fait cela au début d'un écran de chargement de niveau.
  • Nettoyé

Plutôt que d'avoir un système de:

  • Les ressources sont détenues par des entités uniquement ou en vrac.
  • Responsable de sa propre charge en mémoire.

Le premier est un «manager» en tant que tel; quelque chose que je ressens indique qu'il est mal à utiliser. Cependant, cela permet de passer quelque chose comme un vecteur de noms de ressources, plutôt que d'avoir à se démener pour trouver tout ce qui doit être chargé.

Le canard communiste
la source
1
Pas exactement. Je pense que c'est une question valable.
Ricket
Pas tout à fait, mais des domaines similaires et des avantages / inconvénients similaires. Mais il y a des choses que vous feriez avec le manager que vous ne feriez pas avec un manifeste. Les manifestes sont des choses stupides qui rassemblent simplement des ressources disparates en un seul index. Un gestionnaire de ressources peut avoir beaucoup plus de responsabilités et une meilleure interface avec le moteur de jeu.
MrCranky
Je ne pense pas que je demande la même chose. Cela semble demander si vous devriez avoir une sorte de raccourcisseur de chemin de fichier, alors que je demande une sorte de chargeur de ressources / type de cache. Cependant, je pense que cela n'est pas apparu dans seach car j'ai utilisé des ressources plutôt que des actifs.
The Communist Duck
2
@Bryan, je ne suis pas d'accord, "les gestionnaires d'actifs sont-ils une bonne idée" est une question différente de "comment implémentez-vous les gestionnaires d'actifs". Certes, certaines personnes essayaient de répondre à la première question pour la deuxième question, ce qui entraînerait un chevauchement des réponses.
Tetrad

Réponses:

20

Un bon gestionnaire de ressources est la clé de la qualité et de la flexibilité de votre «moteur» de jeu.

Non seulement cela résout beaucoup de problèmes avec la gestion des ressources de bas niveau, mais cela aide également à garantir que les ressources ne sont chargées qu'une seule fois, puis réutilisées si elles sont déjà chargées.

Si le système de ressources est bien résumé, les détails sous-jacents peuvent varier entre le système de fichiers, le stockage physfs, sql même ...

Vous venez de demander une ressource, et elle vous est donnée.

Pas besoin de vous soucier des identifiants des ressources et des trucs comme ça.

Gestion des conflits de ressources en double, etc.

Laissez le gestionnaire de ressources régler cela.

Selon la façon dont vous le concevez - si C ++, faites-vous des amis avec vos classes de gestion de scènes pour vous assurer que la propriété est correctement gérée.

Pool de ressources?

Aucun problème.

Oublier de libérer des ressources?

Aucun problème.

Même interface avec les ressources, où qu'elles se trouvent: mémoire, disque, archive, réseau.

Aucun problème.

Voulez-vous le streaming?

Enfiler?

Laissez votre centre de gestion des ressources s'en occuper.

Et vous pouvez être assuré qu'il vous informera lorsque les ressources seront prêtes à être utilisées.

Ogre 3D a un système de gestion des ressources très flexible, mais je suis sûr qu'il y en a d'autres "là-bas".

jacmoe
la source
1
Je dois vous remercier pour cette réponse. Je n'étais pas convaincu de l'utilité d'un gestionnaire de ressources dédié avant de lire ceci, et maintenant j'en implémenterai un très bientôt.
Jake McArthur
13

J'ai récemment écrit un gestionnaire de ressources qui fonctionne assez bien pour mon cas. Caractéristiques principales:

  • Les ressources sont demandées par ID de chaîne, par exemple ResourceManager::instance().getTexture("textures/player.png"),. L'ID de texture est actuellement mappé directement sur un fichier sur le disque, ce qui est pratique pendant le développement, mais il sera plus tard remplacé par une recherche dans certaines archives.

  • Le gestionnaire de ressources conserve une mappe d'ID aux ressources, il ne rechargera donc pas une ressource qui a déjà été chargée.

  • L'appel ci-dessus ne renvoie pas un Textureobjet, mais plutôt un Resource<Texture>objet; l'appelant doit stocker l' Resource<Texture>objet et non la texture réelle. Le Resource<Texture>agit comme un pointeur intelligent vers un Texture; son operator*()renvoie l' Textureobjet lui-même. L'avantage est que la texture réelle peut être rechargée ou déchargée, sans avoir besoin de mettre à jour tous les clients.

  • Le gestionnaire de ressources vérifie périodiquement si les fichiers sur le disque ont changé et les recharge si nécessaire. Cela me permet de modifier les textures ou les shaders et de voir le résultat sans même redémarrer le jeu.

  • Les ressources peuvent dépendre les unes des autres. La plupart, sinon la totalité, des ressources dépendent d'une Fileressource, qui est le fichier à partir duquel elles ont été chargées. Si, par exemple, un modèle dépend d'une texture, le modèle sera rechargé chaque fois que le fichier de la texture change sur le disque.

  • Lorsqu'une ressource est introuvable ou ne se charge pas, une ressource par défaut est remplacée silencieusement. Cela me permet d'utiliser des ressources que je n'ai pas encore créées, sans planter le jeu. (Fonction prévue: indiquer les ressources "essentielles" telles que les shaders GPGPU, sans lesquelles le jeu ne peut pas fonctionner correctement du tout.)

  • Le comptage des références et le déchargement des ressources inutilisées peuvent être ajoutés facilement. Comme mon jeu est assez petit, je n'en ai pas encore eu besoin.

Je pense que cette liste de fonctionnalités montre que, oui, les gestionnaires de ressources peuvent être bons!

Thomas
la source
2

L'une des raisons d'avoir un gestionnaire de ressources est le partage des ressources. Par exemple, lorsque vous appelez resourceManager.Get("sprite.png"), si "sprite.png" est déjà chargé, le gestionnaire de ressources peut simplement retourner un pointeur sur la ressource sprite déjà chargée plutôt que de créer une nouvelle image et de la recharger à partir du disque.

Un gestionnaire de ressources peut également mettre en cache des ressources, de sorte que, bien que la dernière référence à une ressource ait été supprimée, le gestionnaire de ressources peut choisir de la conserver en mémoire au cas où elle serait rechargée dans un proche avenir. Le gestionnaire de ressources serait programmé pour gérer automatiquement toute la gestion de la mémoire avec vos ressources.

Enfin, je pense qu'une fonctionnalité très utile est le rechargement des ressources dans le jeu. Étant donné que le gestionnaire de ressources détient des poignées pour toutes les ressources du jeu, vous pouvez créer une fonction qui provoque le rechargement de toutes les ressources à partir du disque et la mise à jour du jeu en temps réel, ce qui est extrêmement utile pour les artistes / concepteurs qui travaillent avec votre jeu. .

5ound
la source
1

En plus de la mise en cache et du comptage des références, il peut également gérer les dépendances (le modèle a a besoin de texture b? b avant de charger le modèle!)

Kaj
la source