Sign in to follow this  

Component Initialisation question

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

Hi,
Am working on an Entity component system similar to the outboard system described [url="http://www.gamedev.net/topic/463508-outboard-component-based-entity-system-architecture/"]here[/url] and other places.

I have subsystems like Renderer, Physisc, AI etc that hook into events that trigger in the scene.

One such event is EntityAddedEvent which triggers when a new entity is created.

The subsystems get this event and create their own type of component (Renderer -> RenderComponent, Physics -> PhysicsComonent) for the entity.

I'd like to be able to pass initialisation data to the subsystems for use in setting up there component eg. Mesh data, initial positiion etc

At the moment, I have created an EntityParameter object which gets passed to each subsystem.
The EntityParameter object hold a table of values per each component type it wants created eg.
table ["Renderer"] = <Mesh, "Cube.obj">
table ["Physics"] = <Scale, "1.0, 2.0, 3.0">
table ["Physics"] = <Rotation, "45.0, 0.0, 0.0">

So each subsystem can then issues commands like - EntityParameter->GetValue ("Renderer", "Mesh") and uses that data to initialise its component.

Is this a good approach?

How do you guys handle this issues of passing data to subsystem for use during their component creation and initialisation?

Thanks.

Share this post


Link to post
Share on other sites
[quote name='Andrew Kabakwu' timestamp='1313145418' post='4848154']
Hi,
Am working on an Entity component system similar to the outboard system described [url="http://www.gamedev.net/topic/463508-outboard-component-based-entity-system-architecture/"]here[/url] and other places.

I have subsystems like Renderer, Physisc, AI etc that hook into events that trigger in the scene.

One such event is EntityAddedEvent which triggers when a new entity is created.

The subsystems get this event and create their own type of component (Renderer -> RenderComponent, Physics -> PhysicsComonent) for the entity.

I'd like to be able to pass initialisation data to the subsystems for use in setting up there component eg. Mesh data, initial positiion etc

At the moment, I have created an EntityParameter object which gets passed to each subsystem.
The EntityParameter object hold a table of values per each component type it wants created eg.
table ["Renderer"] = <Mesh, "Cube.obj">
table ["Physics"] = <Scale, "1.0, 2.0, 3.0">
table ["Physics"] = <Rotation, "45.0, 0.0, 0.0">

So each subsystem can then issues commands like - EntityParameter->GetValue ("Renderer", "Mesh") and uses that data to initialise its component.

Is this a good approach?

How do you guys handle this issues of passing data to subsystem for use during their component creation and initialisation?

Thanks.
[/quote]

I'm using c# right now, so my method of handling this might be somewhat different, because I lack the ability to use RAII.

Regarding attributes, I don't store attributes at the entity level, instead I use the public interface of my components.

My entities undergo the following lifecycle:

1) The constructor for the individual entity is called. There are two types of constructor contents - some are remnants from my older class heirarchy stuff. New ones add components to the entity. Following this stage, the entity has instances of all its components but nothing is linked up.
2) The entity is told to "link references" and it is at this point that components cache local references to other components they are interested in on that entity, and components of the world. (The world has a dedicated entity for all its components, and this is where the physics, ballistics, and scripting interface lie)
3) The entity is added to the world, and enterWorld is called. This call is passed to all components.
4) The entity is updated every frame.
5) The entity may be de-activated at some point, and then re-activated, in order to achieve LOD in world behaviour.
6) The entity is told to remove itself from the world. This is also delegated to components.
7) The entity might be reinserted into the world again later. I do this to recycle transient entities and avoid the overheads of a new initialization, or allocation.

Because I am using a garbage collector, I have to be very cautious of resource leaks, and I do this by ensuring that the world is the only bridge to anything outside of the entity system - entities can occasionally reference things external to the world, but things outside the world storing references to entities is strictly forbidden. Thus, when I delete the world at the end of a level, it becomes a single big island which can be collected.


So, in summary, this call sequence happens:

At initialization time:
constructor for Entity, and constructors for Components
link references

At runtime:
add to world
activate
update
update
update
possible deactivate
<entity is now idle and not updated, but can respond to events still which may wake it>
activate
update
update
leaveWorld

From here it may be recycled.

Share this post


Link to post
Share on other sites
[quote name='speciesUnknown' timestamp='1313179924' post='4848396']
I'm using c# right now, so my method of handling this might be somewhat different, because I lack the ability to use RAII.

Regarding attributes, I don't store attributes at the entity level, instead I use the public interface of my components.

My entities undergo the following lifecycle:

1) The constructor for the individual entity is called. There are two types of constructor contents - some are remnants from my older class heirarchy stuff. New ones add components to the entity. Following this stage, the entity has instances of all its components but nothing is linked up.
2) The entity is told to "link references" and it is at this point that components cache local references to other components they are interested in on that entity, and components of the world. (The world has a dedicated entity for all its components, and this is where the physics, ballistics, and scripting interface lie)
3) The entity is added to the world, and enterWorld is called. This call is passed to all components.
4) The entity is updated every frame.
5) The entity may be de-activated at some point, and then re-activated, in order to achieve LOD in world behaviour.
6) The entity is told to remove itself from the world. This is also delegated to components.
7) The entity might be reinserted into the world again later. I do this to recycle transient entities and avoid the overheads of a new initialization, or allocation.

Because I am using a garbage collector, I have to be very cautious of resource leaks, and I do this by ensuring that the world is the only bridge to anything outside of the entity system - entities can occasionally reference things external to the world, but things outside the world storing references to entities is strictly forbidden. Thus, when I delete the world at the end of a level, it becomes a single big island which can be collected.


So, in summary, this call sequence happens:

At initialization time:
constructor for Entity, and constructors for Components
link references

At runtime:
add to world
activate
update
update
update
possible deactivate
<entity is now idle and not updated, but can respond to events still which may wake it>
activate
update
update
leaveWorld

From here it may be recycled.
[/quote]

Sorry for delay in responding, been away for the weekend.

Thanks for your response.
I don't have a base Component class so there is not public interface. Your approach is totally different from what am planning, but can help with some ideas.

Am sure other people have their own methods for initialise components by subsystems at creation time.
Please share.

Share this post


Link to post
Share on other sites
I think your EntityParameter idea is good and data driven.

But what's the reason that you don't have a base class for your components?
A single-root hierarchy will make your life easier.

Share this post


Link to post
Share on other sites
[quote name='wqking' timestamp='1313462334' post='4849675']
But what's the reason that you don't have a base class for your components?
A single-root hierarchy will make your life easier.
[/quote]

Am doing this to avoid issues raised in the topic linked to above.
I dont have a base Component class because in general, components have little in common. There is also NO component type enum/string. Also as am not going to be using one system to process all components, there is little to be gained.
Adding new component "types" is easy, as each component "type" is managed by its corresponding subsystem.

I was expecting more discussion on this topic.....

Share this post


Link to post
Share on other sites

This topic is 2312 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this