Jump to content
  • Advertisement
Sign in to follow this  
Amr0

Scene::CreateEntity() vs. Scene::InsertEntity()

This topic is 2516 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. Consider an extensible entity system for an engine. Using Entity* Scene::CreateEntity( unsigned EntityTypeID ) results in easier memory management. The engine creates all entities that it will use, and will delete them when appropriate. However, this requires an interface for registering entity factories for all entity types. In addition, it becomes nearly impossible without unsightly hacks to add and remove entities into and out of scenes for, say, streaming purposes and editor undo/redo functionality.

On the other hand, using VOID Scene::InsertEntity( Entity* ) and VOID Scene::RemoveEntity(Entity*) allows us to get rid of the EntityTypeID and factory stuff, but we're left with the problem of memory management for the entities. The first solution that comes to mind now is using smart pointers, but unfortunately template classes can not be used in an API for binary-distributed libraries like an engine. What are your thoughts?

Share this post


Link to post
Share on other sites
Advertisement
Why are templates unusable just because you have a binary distribution package? The compiled engine never needs to know the specifics about new template instances your game creates, since casting between pointer types will happen before it is passed to InsertEntity(), inside your game (not game engine) code.

Employ both CreateEntity() and InsertEntity(). One makes it easy to get a shared pointer to predefined entities and the other allows you to add custom entities.
If you are working with shared pointers, they can easily be mixed, as this is what I do in my engine.


L. Spiro

Share this post


Link to post
Share on other sites
I'm not sure I understand you well. I thought using something like VOID Scene::InsertEntity( shared_ptr<Entity> ) didn't work with binary interfaces since each compiler's version of intrusive_ptr differs from others.

Edit: Oops. Now that I read back, in the original post I used plain pointers with InsertEntity(). Using plane pointers with InsertEntity() results in the memory management issue that I mentioned.

Share this post


Link to post
Share on other sites
As YogurtEmperor, I suggest using both designs.

DO use the factory pattern you described for instantiating new Entities. But, ALSO allow for users to Insert and Remove entities form the scene. You don't need to use a shared_pointer, just use an internally managed reference count scheme. I tend to favor manual reference counting. I find smart pointers can encourage lazy design regarding object ownership. But maybe I'm just crazy. Not a big deal, use smart pointers if you like, just keep the Entity's lifetime model in mind.

So, anyway, your object's lifetime could look something like this:


Entity* p_entity = Scene::CreateEntity( someTypeID );
// p_entity has a ref count of 1, owned by the caller of this function
Scene::InsertEntity( p_entity );
// p_entity now has a ref count of 2. One by the user, one by the scene
// Do stuff
...
// We're done with this object
Scene::RemoveEntity( p_entity );
// The scene has either release its reference or has scheduled the release
// The user now releases
p_entity->Release();

Share this post


Link to post
Share on other sites
Thanks for answering. If I am to delegate entity lifetime management to ref-counting pointers, then what's the point of having Scene::CreateEntity()? The difference between Scene::CreateEntity() and Scene::InsertEntity() that I had in mind was that the scene was the unit which manages the lifetime of entities in the case of CreateEntity(), while with InsertEntity(), this management task can be moved to ref-counted pointers, which has the issue of binary incompatibility. I guess what I was indirectly asking is if there was a way to delegate object lifetime management to ref-counted pointers while still maintaining binary compatibility (I think this is what COM is all about), and whether such an approach was really the best way to go around this. Using a mixture of CreateScene() and InsertScene() doesn't really solve this issue.

Share this post


Link to post
Share on other sites
I imagine that Scene::CreateEntity() is the factory interface for instantiating the proper type Entity.

Just stuff the reference count within the entity class, and manipulate that count with a pair of Acquire() and Release() methods to avoid binary incompatibility. You can easily cook up a template pointer class to transparently call these methods if you like.

Share this post


Link to post
Share on other sites
What would Release() do when the reference count reaches 0? Going "delete this;" will not work because allocation and deallocation will then be on different sides of the binary line - allocated in the client, and deleted in the engine. I guess an EntityTypeID and allocation/deallocation object are necessary then. Thanks for your input.

Share this post


Link to post
Share on other sites

What would Release() do when the reference count reaches 0? Going "delete this;" will not work because allocation and deallocation will then be on different sides of the binary line - allocated in the client, and deleted in the engine. I guess an EntityTypeID and allocation/deallocation object are necessary then. Thanks for your input.


It would invoke whatever behavior that Scene::CreateEntity() wants. Perhaps, pass a on_unreferenced( RefCounted* ) function pointer to be called when the entity is unreferenced. Within this function you can enqueue the entity to a deletion queue, or whatever you need to do.

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!