• Create Account

## Advice on Component Based System

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

3 replies to this topic

### #1Irlan Robson  Members

3956
Like
0Likes
Like

Posted 07 February 2014 - 12:25 PM

Well I've read probably most of the Component Based Architeture articles but I need to know if I'm getting somewhere.
The Sync Struct is the data needed for the System works. When a new entity is created the method adds the specific components to the
corresponding system. The System (logically) operates one and modifies other (on that specific case).

class Actor;
class RigidBody;

struct PhysicsSync {
Actor* actor;
RigidBody* body;
};

class PhysicsSystem {
public:

void Update(float dt)
{
this->CheckCollisions();
for (size_t i = 0; i < sync.size(); ++i) {
sync[i].actor->SetTransform(sync[i].body->BuildTransform()); //temp (not builds itself)
}
}
void PushSync(Actor* _actor, RigidBody* _body)
{
PhysicsSync target;
target.actor = _actor;
target.body = _body;
sync.push_back(target);
}

void RemoveSync(Actor* actor, RigidBody* _body)
{
//...
}

void ClearSync() { sync.clear(); }

private:
void CheckCollisions();
std::vector<PhysicsSync> sync;
};



If I'm correct the trickiest part now It's find some way of implementing a flexible and simple event/messaging system.

I think that with this approach one of the things that I can do is...

struct ResponseSync { //collision response
Entity* entity; //assuming that component holds a owner pointer
RigidBody*
}

Basically the ResponseSync takes the form of a Event/Message.

Edited by irlanrobson, 07 February 2014 - 12:34 PM.

### #2phil_t  Members

7649
Like
0Likes
Like

Posted 07 February 2014 - 02:02 PM

What are Actor and RigidBody? Are those components?

This means that there is some outside code that knows specifically about a PhysicsSystem, and more importantly that entities with Actor and RigidBody should be added via PhysicsSystem.PushSync.

Instead, I would think this logic would exist in the PhysicsSystem. e.g. systems in general implement a common interface that has methods for adding/removing entities. When it's called, the PhysicsSystem itself knows that it's interested in entities with Actor and Rigid body, and can then add them to some internal list. That way you don't need outside logic that knows about the PhysicsSystem (other than a single line of code that says, "create a PhysicsSystem and add it to the list of systems") and that it depends on Actor & RigidBody.

### #3Irlan Robson  Members

3956
Like
1Likes
Like

Posted 07 February 2014 - 02:14 PM

What are Actor and RigidBody? Are those components?

This means that there is some outside code that knows specifically about a PhysicsSystem, and more importantly that entities with Actor and RigidBody should be added via PhysicsSystem.PushSync.

Instead, I would think this logic would exist in the PhysicsSystem. e.g. systems in general implement a common interface that has methods for adding/removing entities. When it's called, the PhysicsSystem itself knows that it's interested in entities with Actor and Rigid body, and can then add them to some internal list. That way you don't need outside logic that knows about the PhysicsSystem (other than a single line of code that says, "create a PhysicsSystem and add it to the list of systems") and that it depends on Actor & RigidBody.

1. Yes

2. Was just a simple way of saying...

3. I completely agree with you in that case. Now, following your method, becomes:

class Entity {
public:
template <class T>
T* GetComponent(const std::string& _id)
{
std::map<std::string, Component*>::iterator it = component.find(_id);
if (it != component.end()) {
return static_cast<T>(it->second);
} else {
return 0;
}
}
};
class PhysicsSystem {
public:
PushComponent(Entity* _entity)
{
Actor* actor = _entity->GetComponent<Actor*>("Actor");
RigidBody* rbody = _entity->GetComponent<RigidBody*>("RigidBody");

if (rbody && actor)  {
PhysicsSync sync(actor, body);
sync.push_back(sync);
}
}
};

Edited by irlanrobson, 07 February 2014 - 02:15 PM.

### #4Irlan Robson  Members

3956
Like
0Likes
Like

Posted 08 February 2014 - 02:54 PM

Now I'm looking for a way to handle messages (the communication between components)...

Eg.:

AIAgent inherits a Component Interface.
Inside that agent a script runs and tells that a bullet needs to be spawned with some properties.
In my Point of VIew:

The Entity holds a Reference of the EntityFactory (an EntityManager in that case) and the Component holds a Reference to the Entity. Then I get a component from some Entity that satisfy the message and create a Bullet in the EntityFactory. If I'm correct, the EntityFactory will notify the subsystems for the Entity and those take the correct components.

When an Entity is invalidated from a component condition, hard work it's required to find his components and remove those from the Systems.

Passing Messages to the Components (for me) doesn't help a lot. If a Bullet needs to be spawned, the interaction isn't with the component itself but, instead, with the EntityFactory and the Systems.

In my actual implementation I don't use many Components so I'm just passing a reference directly...

class RigidBody : public Component {
public:
SceneNode* snode; //sends a world transform to the component when updated
};

Both approaches leads to a insane class dependency that I think should be avoided. Someone got other approaches that fits better for the component model?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.