-
Notifications
You must be signed in to change notification settings - Fork 19
Components Legacy
Current Wiki index can be found here
Components are used to define the behaviour of entities. Entities can have multiple components attached to them, providing a flexible method of creating new behaviours or graphics. xygine includes a few stock components, but the real power of an ECS system is expressed through creating custom components.
Custom components can easily be created by inheriting from xy::Component
and implementing its pure virtual functions.
Component::Type type() const;
must return either xy::Component::Type::Drawable
or xy::Component::Type::Script
(or possibly xy::Component::Type::Physics
, although this is currently reserved for components using Box2D) to indicate the general use of the component. Returning a drawable type allows xygine to add the component to the rendering list, whereas script type components are used to define some kind of logic or behaviour.
void entityUpdate(Entity& entity, float dt);
is called once a frame passing in the component's parent entity and current frame time. This allows the component to either update its internal logic, update its parent's transform (or other components via Entity::getComponent<T>()
) or both.
void onStart(Entity& entity)
is optionally overridible, and is called when the component is first attached to its parent entity. A reference to the entity is passed in, but be aware that the entity itself may not yet be in a ready state and possibly not behave in the way that is expected.
void onDelayedStart(Entity& entity);
Similarly to onStart()
this function is optionally overridible. It's is called later than onStart()
but offers better assurance that the parent entity is in a ready state.
void destroy();
is optionally overridible if the custom component requires any cleanup code to be executed before it is destroyed. If you override this you MUST call Component::destroy()
from within it to ensure components are properly destroyed.
sf::FloatRect localBounds() const;
sf::FloatRect globalBounds() const;
are optionally overridible for objects which contribute to the parent Entity
s spatial volume, such as custom collision components that share an entity with a QuadTree
component (see Quad Tree). These should also be implemented for any drawable components, as they are required for render culling. If a custom drawable is not being rendered correctly check that localBounds returns the drawable's AABB in local coordinates, and that globalBounds returns localBounds, usually transformed by the component's transform (assuming it also inherits sf::Transformable
). Local and global AABBs can be visualised by enabling drawDebug()
in the Scene
class.
When creating a new custom component the derived class must pass a reference to the xygine message bus to the Component
constructor, as well as a reference to the derived class's this
pointer. The latter is important because it allows the custom component to derive its unique type ID.
MyComponent::MyComponent(xy::MessageBus& mb)
: xy::Component(mb, this){}
######Message Handlers
System messages are passed to every component, and can be handled by providing custom callbacks using the Component::MessageHandler
struct. Callbacks can be created in the constructor of custom components so that all instances of that component carry the callback, and can also be added externally so that any one particular component may have its own message handler.
xy::Component::MessageHandler handler;
handler.id = xy::Message::Type::PhysicsMessage;
handler.action = [](xy::Component* c, const xy::Message& msg)
{
auto& msgData = msg.getData<xy::PhysicsEvent>();
auto component = dynamic_cast<MyComponent*>(c);
//do stuff to component with msgData
};
myComponent->addMessageHandler(handler);
Messages can also be sent from within a component by using the
xy::Message* sendMessage<T>(Message::Id);
function. For more details on messaging see messages.