Jump to content

  • Log In with Google      Sign In   
  • Create Account

#Actualpinebanana

Posted 08 December 2012 - 09:41 AM

EDIT:
I solved my own problem, and I am going to use an observer pattern but I am going to re-code some parts of my ES, thanks.

At the moment I'm designing an Entity System, in C++, which is some-what based off of the Java Artemis Entity System. Now I'm not 100% sure about the design of my Entity System, mostly handling events. I have multiple choices on what I should do, BUT I just don't know what to do!

Currently I have my code hosted on BitBucket, however, it's incomplete and going to most likely be redesigned.

Here is the basic classes of my Entity System:
  • Entity - An Id (and some methods to add/remove/get/etc Components)
  • Component - An empty abstract class
  • ComponentManager - Manages ALL components for ALL entities within a Scene
  • EntitySystem - Processes entities with specific components
  • Aspect - The class that is used to help determine what Components an Entity must contain so a specific EntitySystem can process it
  • EntitySystemManager - Manages all EntitySystems within a Scene
  • EntityManager - Manages entities (i.e. holds all Entities, used to determine whether an Entity has been changed, enables/disables them, etc.)
  • EntityFactory - Creates (and destroys) entities and assigns an ID to them
  • Scene - Contains an EntityManager, EntityFactory, EntitySystemManager and ComponentManager. Has functions to update and initialise the scene.
Now with the current design, here's a brief of what it does/will look like:
Scene scene;
EntityPtr entity = scene.getEntityFactory().createEntity(); // create an Entity
entity.addComponent(new VelocityComponent(1, 1, 1)); // add a component to the Entity

// add an EntitySystem to the Scene
scene.getSystemManager().addSystem(new MovementSystem());

// activate the Entity (this method wraps the method: scene.activate(EntityPtr entity)), however
// This tells the SystemManager to determine if the systems in the SystemManager object should process an Entity
entity.activate();

// init the scene
scene.initialize();

// Example of a game loop...
while(isRunning)
{
	 // poll our input, etc, etc

	 // update the scene
	 scene.update();
}

Now here's my issue, it is to do with event, as I am not sure how to implement them. Whenever I activatean Entity, the EntitySystemManager (or EntitySystems within the manager) require to be notified when this occurs, to check if the Entity is valid for processing. The ways I am currently thinking of doing this is:

1. Having different Listener objects (or an EntityObserver class), e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}


void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)
	
	  // pseudo code
	  for(each entityManagerListener)
	  {
			// notify the listener object
			entityManagerListener->onActivate(entity);
	  }
}

// overridden method from an EntityManagerListener class
void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
2. Calling explicitly these functions in other classes, e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}

void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)

	  // tell the system manager we activated an object
	  getScene()->getSystemManager().onActivate(entity);
}

void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
3. Just about duplicating the Artemis framework with EntityObserver (with this I have to rewrite some code)
4. Another way of handling these events?
5. All of the above and see which one "feels" better?

Also, is it better to send out events before an update or after an Entity, i.e.
void Scene::update()
{
	 handleEvents(); // handle the events that occurred first, i.e. this will fire out methods to listener/observer objects
	 updateEverythingNecessary(); // then update everything
}
I was told that this would be better, as there are "less" loops?


NOTE:
I just realised I shouldn't really be going
EntityPtr e = scene.getEntityFactory().createEntity();
Instead.. I should be doing
EntityPtr e = scene.createEntity();
... And so on...
That way I can implement the scene in various ways, without the interface depending on those objects.

#2pinebanana

Posted 08 December 2012 - 07:31 AM

At the moment I'm designing an Entity System, in C++, which is some-what based off of the Java Artemis Entity System. Now I'm not 100% sure about the design of my Entity System, mostly handling events. I have multiple choices on what I should do, BUT I just don't know what to do!

Currently I have my code hosted on BitBucket, however, it's incomplete and going to most likely be redesigned.

Here is the basic classes of my Entity System:
  • Entity - An Id (and some methods to add/remove/get/etc Components)
  • Component - An empty abstract class
  • ComponentManager - Manages ALL components for ALL entities within a Scene
  • EntitySystem - Processes entities with specific components
  • Aspect - The class that is used to help determine what Components an Entity must contain so a specific EntitySystem can process it
  • EntitySystemManager - Manages all EntitySystems within a Scene
  • EntityManager - Manages entities (i.e. holds all Entities, used to determine whether an Entity has been changed, enables/disables them, etc.)
  • EntityFactory - Creates (and destroys) entities and assigns an ID to them
  • Scene - Contains an EntityManager, EntityFactory, EntitySystemManager and ComponentManager. Has functions to update and initialise the scene.
Now with the current design, here's a brief of what it does/will look like:
Scene scene;
EntityPtr entity = scene.getEntityFactory().createEntity(); // create an Entity
entity.addComponent(new VelocityComponent(1, 1, 1)); // add a component to the Entity

// add an EntitySystem to the Scene
scene.getSystemManager().addSystem(new MovementSystem());

// activate the Entity (this method wraps the method: scene.activate(EntityPtr entity)), however
// This tells the SystemManager to determine if the systems in the SystemManager object should process an Entity
entity.activate();

// init the scene
scene.initialize();

// Example of a game loop...
while(isRunning)
{
	 // poll our input, etc, etc

	 // update the scene
	 scene.update();
}

Now here's my issue, it is to do with event, as I am not sure how to implement them. Whenever I activatean Entity, the EntitySystemManager (or EntitySystems within the manager) require to be notified when this occurs, to check if the Entity is valid for processing. The ways I am currently thinking of doing this is:

1. Having different Listener objects (or an EntityObserver class), e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}


void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)
	
	  // pseudo code
	  for(each entityManagerListener)
	  {
			// notify the listener object
			entityManagerListener->onActivate(entity);
	  }
}

// overridden method from an EntityManagerListener class
void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
2. Calling explicitly these functions in other classes, e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}

void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)

	  // tell the system manager we activated an object
	  getScene()->getSystemManager().onActivate(entity);
}

void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
3. Just about duplicating the Artemis framework with EntityObserver (with this I have to rewrite some code)
4. Another way of handling these events?
5. All of the above and see which one "feels" better?

Also, is it better to send out events before an update or after an Entity, i.e.
void Scene::update()
{
	 handleEvents(); // handle the events that occurred first, i.e. this will fire out methods to listener/observer objects
	 updateEverythingNecessary(); // then update everything
}
I was told that this would be better, as there are "less" loops?


NOTE:
I just realised I shouldn't really be going
EntityPtr e = scene.getEntityFactory().createEntity();
Instead.. I should be doing
EntityPtr e = scene.createEntity();
... And so on...
That way I can implement the scene in various ways, without the interface depending on those objects.

#1pinebanana

Posted 08 December 2012 - 07:30 AM

At the moment I'm designing an Entity System, in C++, which is some-what based off of the Java Artemis Entity System. Now I'm not 100% sure about the design of my Entity System, mostly handling events. I have multiple choices on what I should do, BUT I just don't know what to do!

Currently I have my code hosted on BitBucket, however, it's incomplete and going to most likely be redesigned.

Here is the basic classes of my Entity System:
  • Entity - An Id (and some methods to add/remove/get/etc Components)
  • Component - An empty abstract class
  • ComponentManager - Manages ALL components for ALL entities within a Scene
  • EntitySystem - Processes entities with specific components
  • Aspect - The class that is used to help determine what Components an Entity must contain so a specific EntitySystem can process it
  • EntitySystemManager - Manages all EntitySystems within a Scene
  • EntityManager - Manages entities (i.e. holds all Entities, used to determine whether an Entity has been changed, enables/disables them, etc.)
  • EntityFactory - Creates (and destroys) entities and assigns an ID to them
  • Scene - Contains an EntityManager, EntityFactory, EntitySystemManager and ComponentManager. Has functions to update and initialise the scene.
Now with the current design, here's a brief of what it does/will look like:
Scene scene;
EntityPtr entity = scene.getEntityFactory().createEntity(); // create an Entity
entity.addComponent(new VelocityComponent(1, 1, 1)); // add a component to the Entity

// add an EntitySystem to the Scene
scene.getSystemManager().addSystem(new MovementSystem());

// activate the Entity (this method wraps the method: scene.activate(EntityPtr entity)), however
// This tells the SystemManager to determine if the systems in the SystemManager object should process an Entity
entity.activate();

// init the scene
scene.initialize();

// Example of a game loop...
while(isRunning)
{
	 // poll our input, etc, etc

	 // update the scene
	 scene.update();
}

Now here's my issue, it is to do with event, as I am not sure how to implement them. Whenever I activatean Entity, the EntitySystemManager (or EntitySystems within the manager) require to be notified when this occurs, to check if the Entity is valid for processing. The ways I am currently thinking of doing this is:

1. Having different Listener objects (or an EntityObserver class), e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}


void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)
	
	  // pseudo code
	  for(each entityManagerListener)
	  {
			// notify the listener object
			entityManagerListener->onActivate(entity);
	  }
}

// overridden method from an EntityManagerListener class
void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
2. Calling explicitly these functions in other classes, e.g.
void Entity::activate()
{
	  getScene()->getEntityManager().activate(this);
}

void EntityManager::activate(EntityPtr entity)
{
	  // register the entity
	  register(entity); // (simply adds it to an array of entities, for storage)

	  // tell the system manager we activated an object
	  getScene()->getSystemManager().onActivate(entity);
}

void EntitySystemManager::onActivate(EntityPtr entity)
{
	  // pseudo code
	  for(each system)
	  {
			// check the entity
			system.check(entity);
	  }
}
3. Just about duplicating the Artemis framework with EntityObserver (with this I have to rewrite some code)
4. Another way of handling these events?
5. All of the above and see which one "feels" better?

Also, is it better to send out events before an update or after an Entity, i.e.
void Scene::update()
{
	 handleEvents(); // handle the events that occurred first, i.e. this will fire out methods to listener/observer objects
	 updateEverythingNecessary(); // then update everything
}
I was told that this would be better, as there are "less" loops?


NOTE:
I just realised I shouldn't really be going
EntityPtr e = scene.getEntityFactory().createEntity();
Instead.. I should be doing
EntityPtr e = scene.createEntity();
... And so on...
That way I can implement the scene in various ways, without the interface depending on those objects.

PARTNERS