Jump to content
  • Advertisement
Sign in to follow this  
AgustinAlvarez

Component based system

This topic is 2118 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, so i'm designing a entity component based system for my engine (Based of Artemis design).

Most of the example code i watched, has static containers and static stuff. My question is, is that a good idea?, my design is an hybrid approach of both dynamic and static implementation since i can add and remove system from my plugins dynamic.

My current design is:

Component
  -> isActive(), setActive(bool) [this is when the entity owner is sleeping]
  -> isValid(), setInvalid()         [When the entity owner removes the component or the entity is destroyed]
  -> getId()                              [ID of the component class]

Componentable<T> : Component
  -> static ID                            [This is for mapping]
  -> Component::m_Id = typeid(T).hash_code() [Get ID of the class at compile time]

ComponentCollection<T>
  -> addComponent, getComponents, disposeComponent [Store contiguous each component of the same type] for CPU cache.

ComponentManager (Map ComponentID To ComponentCollection)
  -> addCollection<T>           [Add a collection of components into a map]
  -> getCollection<T>            [Get a collection of components from a map]

ComponentHolder
  -> addComponent<T>, getComponent<T>, hasComponent<T>, invalid(), removeComponent<T>

  -> Holders contain a pointer to the components owned.
 

System<T>

  -> Logic part of the component
  -> Iterate over each component of the same type, those components invalidated will be removed from the collection, and those sleeping
      will not be executed.

SystemManager
  -> Contains every system registered

World
  -> Contains a system manager and creates an entity (Component holder + ID)


How it works?
 

struct LifeManaComponent : Componentable<LifeManaComponent>
{
    uint32_t m_Life, m_Mana;
};   

struct DefenseComponent : Componentable<DefenseComponent>
{
   uint32_t m_Defense, m_Attack, m_RecvDamage;
}

class AttackSystem : public System<LifeManaComponent, DefenseComponent>
{
    void OnExecute(Entity & entity)
    {
           ....
    }
};
//////////////////////////////////////////////// Code /////////////////////////////////////////////////////////////////
    World->AddComponentCollection<LifeManaComponent>();
    World->AddComponentCollection<DefenseComponent>();
    World->AddSystem<AttackSystem>();

    auto & pHolder = World->CreateEntity();
    pHolder.addComponent<LifeManaComponent>(30 /* Life */, 0 /* Mana */);
    pHolder.addComponent<DefenseComponent>(0, 0, 0); // Now the entity will be eligable for attackSystem.
    pHolder.hasComponent<LifeManaComponent>(); // Return true
    pHolder.getComponent<LifeManaComponent>(); // Return attack component reference.
    pHolder.invalidate(); // Invalid all components
        

    World->RemoveSystem<AttackSystem();
    World->RemoveComponentCollection<DefenseComponent>();

UPDATE: CODE

Edited by Wolftein

Share this post


Link to post
Share on other sites
Advertisement

https://github.com/UFNHGGI/CBGE

 

try it wink.png

 

sample :

///////////////////FreeMove.h
#pragma once
#include <Engine.h>

class CFreeMove : CComponent
{
	SVec2 moveSpeed;

	COMPONENT_REG_BEGIN(CFreeMove, true)
	COMPONENT_REG_VAR(moveSpeed, true)	//automatic registration :O
	COMPONENT_REG_END()

	void onCreate()
	{
		moveSpeed = SVec2(RandRange(1, 5));
	}
	void onUpdate()
	{
		if(CInput::KeyDown('D'))
			owner()->position.x += moveSpeed.x;
		else if(CInput::KeyDown('A'))
			owner()->position.x -= moveSpeed.x;

		if(CInput::KeyDown('W'))
			owner()->position.y -= moveSpeed.y;
		else if(CInput::KeyDown('S'))
			owner()->position.y += moveSpeed.y;
	}
};

///////////////FreeMove.cpp
#include "FreeMove.h"
COMPONENT_IMPL(CFreeMove);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!