Using dynamic component dispatch
The C++ SDK provides two functions for type-safe manipulation of components when the component type is not known statically.
When using these, the complete set of possible components must be statically
provided using the worker::Components
template class.
These functions are defined as follows:
/**
* Invokes Accept<T>() on the provided handler for the component in the given
* list of components whose ID matches the given component ID.
*/
template <typename... T, typename Handler>
void ForComponent(const Components<T...>& components, ComponentId component_id, Handler&& handler);
/**
* Invokes Accept<T>() on the provided handler for each component in the given list of
* components.
*/
template <typename... T, typename Handler>
void ForEachComponent(const Components<T...>& components, Handler&& handler);
Example of usage
For example, you could use ForComponent
to copy the components of one entity to another without
knowledge of the types of the components. To do this, you would first define a class which
implements a handler to provide the desired copying functionality:
struct CopyFunc
{
const Entity& from;
Entity& to;
template <typename T>
void Accept<T>() {
to.Add<T>(*from.Get<T>());
}
}
You would then create an instance of the CopyFunc
class and call the static
methods worker::ForComponent
or
worker::ForEachComponent
to
apply the functionality defined in Accept
to the entity’s components:
// Probably defined elsewhere.
using MyComponents = worker::Components<my_schema::Foo, my_schema::Bar>;
// Copy all components from source_entity to target_entity.
CopyFunc copy_func{source_entity, target_entity};
for (auto component_id : source_entity.GetComponentIds()) {
worker::ForComponent(MyComponents{}, component_id, copy_func);
}
This functionality could also be used to implement a View
with custom semantics.