Jump to content
  • Advertisement
Sign in to follow this  
crancran

Event Handling in Entity/Component Design

This topic is 2601 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

In my component-based entity system, I am facing problems with how to adequately wire up the event communication between various aspects of the framework.

Some programmers have added methods on their entity class so that a particular component can be retrieved by name. I can certainly see the value in such an approach as it truly reduces the complexity needed with an event system allowing the programmer to do something like:


void CRenderSystem::update(float timeSinceLastFrame) {
ComponentIt it = m_components.begin();
for(; it != m_components.end(); ++it) {
CRenderComponent* pComponent = *i;
CPositionComponent* pPosition = pComponent->getEntity()->getComponent<CPositionComponent>();
pComponent->getSceneNode()->setPosition(pPosition);
}
}



The downside is that now the rendering system is tightly coupled with the position system and I think that defeats the notion of aggregation, right?

When these subsystems such as the rendering subsystem is created, it automatically hooks into the event subsystem. There are typical application-level events that each subsystem in the game framework wants to be notified about. When a subsystem instantiates a specific component, the component notifies the subsystem that it wants to be notified when additional events fire. If the subsystem hasn't already requested those events from the main engine's event system, the subsystem hooks into those events as well.

One could implement a simple event map where each event is mapped to a list of registered handlers so that when that event fires; all those interested are notified. But this doesn't seem like it would work well in a situation where the position component of entity A fires an event and the render component of entity A cares about it. If there is another entity, the render component of that entity cares about that event, but only if the event fired from this other entity's position component and not from entity A's components.

Could anyone point me in the right direction on how to layout the structure for these requirements?

Share this post


Link to post
Share on other sites
Advertisement
So after reading a post here by slayemin, a few things dawned on me. There are likely two different event message systems.

The most obvious event system is one which is entity-specific which could be internally managed by the entity managed. The idea here is that each entity manages the relationship between a list of events and the callback handlers for each of those events. Since each component has a reference to it's owning entity instance, the entity's message queue can be easily accessed both inside the attached components or by the subsystem that is managing that particular component during it's update loop.


void CRenderSystem::update(float delta) {
ComponentIterator i = m_activeComponents.begin();
for(; i != m_activeComponents.end(); ++i) {
CRenderComponent* rc = (*i);
if(!rc->getSceneNode()) {
// need to initialize the scene node
Vector3 position;
if(rc->getEntity()->sendEvent(GameEvents::E_QUERY_POSITION, &position)) {
// a component answered the event request and updated the position variable
SceneNode* pNode = m_pRenderEngine->getRootSceneNode()->createChildSceneNode();
Entity* pEntity = m_pRenderEngine->createEntity(rc->getEntity()->getId());
Mesh* pMesh = m_pRenderEngine->loadMeshFile(rc->getMeshFileName());
pEntity->setMesh(pMesh);
pNode->attachObject(pEntity);
pNode->setPosition(position);
rc->setSceneNode(pNode);
// no need to have position in the component since the scene node uses it.
}
}
}
}


The flexibility here is that an event can be triggered by the subsystem that is doing it's internal update routine or can be triggered by a component directly. I read in one article where someone stated that events should be triggered only by the subsystems themselves and not components. I suppose if every component attached to an entity is at some point examined by a subsystem during a game loop iteration, this makes sense. But would there ever be cases where a component may not be iterated over each game loop and exists purely to trigger another event based on a specific condition? Sticking to the components are only data bags and subsystems are our logical behavior, a system would need to exist and perform the update :)

The second would be more of a global game engine message system where the recipients would be the subsystems and not the entities or components. This is where I have a hard time understanding the purpose of such a system. I suppose one subsystem may need to send events/requests to other subsystems just as components do with one another through their parent entity; however, what would that likely consist of exactly?

In the referenced article, the physics system was one situation where inter-entity communication may be necessary; however, since the physics system would be doing the collision tests and would have a reference to all physics components and their parent entities, events could be dispatched by the physics system to each affected entity directly. So what messages would truly go upstream that I may be overlooking here?

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!