Ponto V!

Home Arquitetura Programação Gerenciando Recursos
Bruno Crivelari Sanches
Gerenciando RecursosImprimir
Escrito por Bruno Crivelari Sanches
Índice do Artigo
Gerenciando Recursos
Implementação classe RefCounter
Classe Resource
Classe TextureResource
Classe ResourceManager
O Programa Exemplo
Considerações Finais e Código Fonte
Todas Páginas

O gerenciamento de recursos é um dos pontos chave para o bom funcionamento de um jogo. Neste artigo veremos uma forma de construir um gerenciador para texturas (usando SDL) que garante que cada imagem seja carregada uma única vez na memória (mesmo se usada por vários objetos). Apesar do exemplo ser baseado em SDL e gerenciamento de texturas, a técnica pode ser aplicada para qualquer framework e para qualquer tipo de recurso sem grandes dificuldades.

Conhecimentos Necessários

Este artigo assume que o leitor já possui conhecimento prévio no uso de Smart Pointers, em especial nos Intrusive Pointers da Boost, de contêineres intrusivos e do uso básico da SDL.

A escolha dos smart pointers e dos contêineres intrusivos foi para poder ilustrar o uso destes na prática, a SDL foi escolhida devido a simplicidade de uso (tanto na instalação quanto na programação), permitindo assim focar o artigo no gerenciamento dos recursos e não em detalhes de API.

Decisões de Design

O código exemplo construído para este artigo foi feito para fins didáticos, sendo que para tal não resolve todos os problemas relacionados a gerenciamento de recursos e apresenta um solução básica para o problema, que dependendo do caso pode precisar de muito mais funcionalidades, como suporte a multi-thread, carga em background, suporte a cache, etc.

Recursos

Vamos primeiramente definir o que são recursos no contexto deste artigo: É considerado um recurso todo o tipo de dado que que o jogo utiliza e não modifica, os exemplos clássicos são:

  • Texturas
  • Sons
  • Vídeos
  • Musicas
  • Modelos 3d

Nem todo jogo faz uso destes e existem jogos que podem vir adicionar muito mais itens a esta lista. O principal fato sobre um recurso é que este durante sua vida não sofre modificações, caso venha a sofrer, todos os objetos que compartilham um mesmo recurso vão ser afetados.

Cada recurso possui uma identidade única e no nosso artigo vamos considerar como identidade do recurso o nome do seu arquivo e caminho do mesmo, alguns exemplos:

  • data\textures\porta_madeira\porta.bmp
  • data\textures\porta_metal\porta.bmp
  • data\textures\monstro\pele_diabo.bmp

No exemplo acima temos três recursos, note que os dois primeiros possuem o mesmo nome de arquivo, mas como estão em diretórios diferentes são considerados recursos diferentes, caso os arquivos sejam os mesmos, cabe ao desenvolvedor referenciar os mesmos arquivos e não permitir que cópias sejam criadas na estrutura do jogo.

Visão Geral

Abaixo temos o diagrama de classes do sistema que vai nos ajudar a visualizar a construção do mesmo:

uml

As classes do sistema são listadas a seguir:

  • RefCounter: esta classe é utilizada para fazer o controle de referências do intrusive_ptr, usamos uma classe base para que não seja preciso implementar a contagem em todas as classes.
  • Resource: classe base de todo recurso que o sistema vai gerenciar, no nosso exemplo vamos implementar apenas a TextureResource.
  • TextureResource: esta classe gerencia uma única textura (ou SDL_Surface), para cada textura que o jogo precisa uma instância desta é criada.
  • SoundResource: apenas para ilustrar a flexibilidade do sistema, esta classe pode ser implementada para gerenciar sons.
  • ResourceManager: este é o gerenciador do recursos, ele mantém internamente uma lista dos recursos carregados e toda a carga de recursos deve ser feita através deste. Note que é um singleton.
  • Sprite: esta classe foi construída apenas para demonstrar como o sistema pode ser utlizado, ela representa um sprite em um jogo 2d e sempre que é criada requisita ao gerenciador de recursos uma textura para representar o sprite.

Agora que já temos uma idéia melhor do que será construído, mãos as obra!



Comentários (2)
  • Bruno Romano
    avatar

    Meus parabéns muito bom o exemplo, ilustra diversas coisas, inclusive exemplos bem práticos de assuntos ja revisados e explicados por vocês. Muito bom este site, tenho visitado sempre procurando aprender mais, alem das técnicas de jogos aprender mais sobre boost, templates, e técnicas de programação.

    Mas tenho uma sugestão dúvida a fazer.
    no método:
    void RefCounter_c::ReleaseRef()
    {
    //Reduzimos o contador
    //Note que jogamos o valor em um temporario, pois como tCount pode ser modificado por threads
    //confiamos apenas no retorno de --
    long count = --tCount;

    //ultima referencia? Entao suicidio!
    if(count == 0)
    delete this;
    }

    não pode criar um método virtual que faz o delete this ? e chamar ele quando for deletar o objeto.
    Assim caso alguem queira que esse objeto faça algo antes de morrer ele pode sobreescrever esse método. Igual acontece com as exception da MFC que vc chama o método Delete.

  • Bruno Crivelari Sanches
    avatar

    Obrigado Bruno.

    Poder criar o método virtual pode, só não vejo necessidade. Se é preciso fazer algo antes do objeto ser destruído basta fazer no destrutor, ele já é virtual para tratar essa situação.

    T+

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter