Skip to content

Commands Legacy

fallahn edited this page Oct 5, 2017 · 1 revision

Unlike Messages commands are a method of inter-system communication which can target specific entities. In fact commands target only entities, and only those which are currently attached to the scene's node graph. Commands are made up of a target, be it a specific entity ID or a mask describing a group of entities, and an action in the form of a function. To send a command first create an instance of xy::Command, assign its target, and then give it an action.

xy::Command cmd;
cmd.entityID = 23;

or

cmd.category = MyNpcs;

targeting an entity via its unique ID means that only that entity will perform the command's action, should the entity be found in the scene graph. When an entity with the specified ID is found the command is discarded once the action is executed, meaning in some cases this is slightly (although usually negligibly) more performant. Targeting entities by category is more flexible however. xy::Command::category is simply a bit mask of user defined values, which you may declare in an enum for example:

enum CommandIds
{
    NPC = 0x1,
    Player = 0x2,
    LogicNode = 0x4
};

These IDs then need to be assigned to an entity when it is created, using addCommandCategories(). For example an entity may fall into two or more categories, the values of which can be OR'd together:

entity->addCommandCategories(CommandIds::NPC | CommandIds::LogicNode);

A similar mask is used to set the target of the command

cmd.category = CommandIds::Player | CommandIds::LogicNode;

when the command is sent down the scene graph any entities which are flagged with any of the target categories will then perform the action associated with the command.

To create a command action you can either use std::bind() to bind an existing function to the action, or you can use a lambda expression to define a function in-place (as well as capture any relevant variables). The function must have this signature:

void func(xy::Entity& entity, float time);

When the function is executed the targeted entity is passed in, along with the current frame time. Although commands only target entities, the entity class itself provides access to attached components, which allows modification from within an action.

cmd.action = [](xy::Entity& entity, float time)
{
    entity.getComponent<MyDrawable>()->setColour(sf::Color::Green);
};

The above lambda expression will attempt to call setColour() on any attached components of type MyDrawable. It is down to the user to ensure that this component is actually attached to the entity, and handle any errors which may occur. Finally, to send the command, use the sendCommand() function of xy::Scene.

m_scene.sendCommand(cmd);

Commands are placed in a queue, and are therefore not actually executed until the next frame. Be aware of this when capturing any variables in lambda expressions, as the state of those variables may have changed between frames.

Clone this wiki locally