Skip to content
Arthur Paim Arnold edited this page Jun 14, 2017 · 8 revisions

Variante ECS DOO

Versão 1

  • Entidade: id, flag de ativa, lista de componentes.
  • Componente: deriva de base_component, que é vazia.
  • ID do componente: número incremental que identifica a subclasse do componente. Provém de função estática para evitar uso de singleton.
  • As posições na lista de componentes da entidade são dadas pelo ID do tipo do componente.

Versão 2

  • Componentes sem comportamento.
  • Introdução de sistemas. -- Primeiro sistema: Health

Variante ECS DOD

Sistemas

Não possuem estado, logo não precisam constituir structs: tornam-se simples procedimentos.

Entidades

É apenas um uint64_t que, assim como o identificador de sua contraparte orientada a objetos, é dividido em índice e versão.

Componentes

Deixam de existir como estruturas individuais. Agora, temos estruturas que gerenciam todos os componentes de um dado tipo, armazenando cada propriedade do componente em um array dedicado. Isso traz algumas considerações:

  • Um dado índice (size_t) é usado para acessar as propriedades de um mesmo componente. Assim, para o componente de ataque, por exemplo, range[i] é o raio do ataque cujo dano é damage[i]. Um array especial, owner, é criado para associar o índice de um componente ao identificador da entidade que o possui. Reciprocamente, o unordered_map<uint64_t,size_t> owned mapeia o identificador de uma entidade ao índice do componente que possui, se houver.
  • Quando um componente é criado em seu gerenciador, seus arrays são redimensionados, se necessário, para comportar a nova posição. Essa inserção é sempre feita no final do array.
  • Quando um componente é removido de seu gerenciador, exceto se já ocupar a última posição dos arrays, o último componente dos arrays será copiado para a posição removida, sobrescrevendo-a. Isso elimina a necessidade de mover todos os dados posteriores ao removido, mas, por outro lado, elimina a garantia de ordem dos arrays.
  • As funcionalidades dos gerenciadores de componentes possuem muitos pontos comuns. Para reduzir a replicação de código, é utilizada a struct helper, definida no cabeçalho soa_utils.hpp, para reunir todo o gerenciamento de memória, de movimentação de dados e de indexação em owner e owned.
  • Para auxiliar na declaração de um gerenciador de componentes, foi criada a macro de pré-processador SOA_COMPONENT_BASE(D), que declara todas as propriedades comuns aos gerenciadores:
    • size_t len, cap: o tamanho e a capacidade dos arrays, em número de elementos;
    • soa::helper<D> helper: o helper utilizado pelo gerenciador de componentes para gerenciar seus arrays;
    • o mapa std::unordered_map<uint64_t, size_t> owned de entidades para índices;
    • o array uint64_t * owner de índices para entidades;
    • as funções-membro create, destroy e size.
  • O gerenciador de componentes é encarregado de, em seu construtor, prover ao seu helper os endereços de seus arrays específicos. Entende-se por array específico aquele que pertence ao domínio do gerenciador de componentes, ou seja, aquele que é definido fora da macro SOA_COMPONENT_BASE. Os endereços são armazenados pelo helper e utilizados na inserção e remoção de componentes, isentando o gerenciador da tarefa repetitiva de realocação e cópia de cada um dos seus arrays.

Considerações

Exceções: se usadas (DOO), trariam ainda maior overhead.

Clone this wiki locally