shiva
Search…
shiva::ecs
In this page you will find all the information you need on the ecs part of shiva, the api of the different classes, the game loop architecture.

How do the system works ?

Systems

Shiva has 3 different kinds of systems:
  • PreUpdate: These systems are the first to be updated in the game loop, they are generally used to retrieve user input, or manage network events for example.
  • LogicUpdate: These systems are the second to be updated in the game loop, they are generally used for game logic such as movement or collisions for example.
  • PostUpdate: These systems are the last to be updated in the game loop, they are generally used for rendering or interpolation for example.
The pseudo code look like this:
function update()
{
user defined;
}
function update_systems_type(system_type)
{
for_each_systems;
call update();
}
function update_systems()
{
call update_systems_type(pre_logic);
while (frame_rate) {
call update_systems_type(logic);
}
call update_systems_type(post_logic);
return nb_systems_updated
}
GameLoop;
while (game_running) {
call update_systems
}
return game_return_value;
This game loop is based on the gafferon on games tutorial: Fix your timestep.

Diagram

complete diagram
simple diagram

system_type

Description

This file contains an enum representing the different types of systems presented previously, and three strong types, later used in template parameter by the system class.

system_type API

Enum
Typedefs
enum system_type
{
pre_update = 0,
logic_update = 1,
post_update = 2,
size = 3,
};
using system_pre_update = NamedType<system_type,struct system_pre_update_tag>;
using system_post_update = NamedType<system_type, struct system_post_update_tag>;
using system_logic_update = NamedType<system_type, struct system_logic_update_tag>;

system_manager

Description

This class manage the systems of the entity component system. You are able to add, remove, retrieve , update or delete systems through it.

Diagram

system_manager

system_manager API

Signature
Constructor
Functions
class system_manager;
explicit system_manager(entt::dispatcher &dispatcher,
entt::entity_registry &registry,
plugins_registry_t &plugins_registry) noexcept;
Parameters
  • entt::dispatcher The dispatcher will be provided to the system when it is created.
  • entt::entity_registry The entity_registry will be provided to the system when it is created.
  • plugins_registry registry of the plugged systems
Function Name
Description
update
update the systems
get a single system
get multiple systems
check if a system is present
check if multiple systems are present
mark a single system
mark multiple systems
enable a single system
enable multiple systems
disable a single system
disable multiple systems
create a single system
create multiple systems
get the number of systems
load plugins and add it as systems
get a single system by his name

update

size_t update() noexcept
Return value
Possible Name
Description
nb_systems_updated
size_t
  • number of systems successfully updated
Example
size_t nb_systems_updated = system_manager.update();
if (nb_systems_updated != 5) {
/* Oh no, i was expected 5 systems to be executed in this game loop tick */
}
Notes
This is the function that updates your systems. Based on the logic of the different kinds of shiva systems, this function take care of updating your systems in the right order.
If you have not loaded any system into the system_manager the function return 0.
If you decide to mark a system, it will be automatically deleted at the next loop tick through this function.

get_system

template <typename TSystem>
const TSystem &get_system() const noexcept;
template <typename TSystem>
TSystem &get_system() noexcept;
Template parameters
Name
Description
TSystem
TSystem
  • represents the type of system to get
Return value
Possible name
Description
render_system, log_system
TSystem &
  • a reference to the system obtained
const TSystem &
  • a const reference to the system obtained
Example
//! Non const version
auto& render_system = system_manager.get_system<game::render_system>();
//! const version
const auto& log_system = system_manager.get_system<game::log_system>();

get_systems

template <typename ...TSystems>
std::tuple<std::add_lvalue_reference_t<TSystems>...> get_systems() noexcept;
template <typename ...TSystems>
std::tuple<std::add_lvalue_reference_t<std::add_const_t<TSystems>>...> get_systems() const noexcept;
Template parameters
Name
Description
TSystems
TSystems
  • represents a list of systems to get
Return value
Possible name
Description
tuple_systems, [system_foo, system_bar]
Tuple<TSystems &>
  • Tuple of systems obtained.
Tuple<const TSystems &>
  • Tuple of systems obtained (const ref)
Example
// Called from a const context
auto[system_foo, system_bar] = system_manager.get_systems<system_foo, system_bar>();
// Called from a non const context
auto[system_foo_nc, system_bar_nc] = system_manager.get_systems<system_foo, system_bar>();
// Get it as a tuple
auto tuple_systems = system_manager.get_systems<system_foo, system_bar>();
This function recursively calls the get_system function

has_system

template <typename TSystem>
bool has_system() const noexcept;
Template parameters
Name
Description
TSystem
TSystem
  • represents the system that needs to be verified
Return value
Possible name
Description
result
boolean
  • true if the system has been loaded
  • false otherwise
Example
bool result = system_manager.has_system<my_game::render_system>();
if (!result) {
//! Oh no, i don't have a rendering system.
}

has_systems

template <typename ... TSystems>
bool has_systems() const noexcept
Template parameters
Name
Description
TSystems
TSystems
  • represents a list of systems that needs to be verified
Return value
Possible name
Description
result
boolean
  • true if the list of systems has been loaded
  • false otherwise
Example
bool result = system_manager.has_systems<my_game::render_system,
my_game::audio_system>();
if (!result) {
//! Oh no, atleast one of the systems is not present
}
This function recursively calls the has_system function

mark_system

template <typename TSystem>
bool mark_system() noexcept
Template parameters
Name
Description
TSystem
TSystem
  • represents the system that needs to be marked
Return value
Possible name
Description
result
boolean
  • true if the system has been marked
  • false otherwise
Example
bool result = system_manager.mark_system<my_game::render>();
if (!result) {
//! Oh no the system has not been marked.
//! Did you mark a system that is not present in the system_manager?
}
This function marks a system that will be destroyed at the next tick of the game loop.

mark_systems

template <typename ... TSystems>
bool mark_systems() noexcept
Template parameters
Name
Description
TSystems
TSystems
  • represents a list of systems that needs to be marked
Return value
Possible name
Description
result
boolean
  • true if the list of systems has been marked
  • false otherwise
Example
bool result = system_manager.mark_systems<my_game::render, my_game::audio>();
if (!result) {
//! Oh no, atleast one of the system has not been marked.
}
This function recursively calls the mark_system function

enable_system

template <typename TSystem>
bool enable_system() noexcept
Template parameters
Name
Description
TSystem
TSystem
  • represents the system that needs to be enabled
Return value
Possible name
Description
result
boolean
  • true if the system has been enabled
  • false otherwise
Example
bool result = system_manager.enable_system<my_game::render>();
if (!result) {
//! Oh no, this system cannot be enabled.
//! Did you enable a system that is not present in the system_manager?
}
by default, a system is enabled.

enable_systems

template <typename ... TSystems>
bool enable_systems() noexcept
Template parameters
Name
Description
TSystems
TSystems
  • represents a list of systems that needs to be enabled
Return value
Possible name
Description
result
boolean
  • true if the list of systems has been enabled
  • false otherwise
bool result = system_manager.enable_systems<my_game::render, my_game::audio>();
if (!result) {
//! Oh no, atleast one of the requested systems cannot be enabled.
}
This function recursively calls the enable_system function

disable_system

template <typename TSystem>
bool disable_system() noexcept
Template parameters
Name
Description
TSystem
TSystem
  • represents the system that needs to be disabled
Return value
Possible name
Description
result
boolean
  • true if the the system has been disabled
  • false otherwise
Example
bool result = system_manager.disable_system<my_game::render>();
if (!result) {
//! Oh no the system_manager cannot disable this system.
}
If you deactivate a system, it will not be destroyed but simply ignore during the game loop

disable_systems

template <typename ... TSystems>
bool disable_systems() noexcept

Template parameters

Name
Description
TSystems
TSystems
  • represents a list of systems that needs to be disabled
Return value
Possible name
Description
result
boolean
  • true if the list of systems has been disabled
  • false otherwise
Example
bool result = system_manager.disable_systems<my_game::render, my_game::audio>();
if (!result) {
//! Oh no, atleast one of the requested systems cannot be disabled.
}
This function recursively calls the disable_system function

create_system

template <typename TSystem, typename ... TSystemArgs>
TSystem &create_system(TSystemArgs &&...args)

Template parameters

Name
Description
TSystem
TSystem
  • represents the type of system to create
args
TSystemArgs
  • represents the arguments needed to construct the system to create

Return value

Possible name
Description
render_system
TSystem &
  • a reference to the created system
Example
auto& render_system = system_manager.create_system<my_game::render>(/* args */);

load_systems

template <typename ...TSystems>
std::tuple<std::add_lvalue_reference_t<TSystems>...> load_systems() noexcept;
Template parameters
Name
Description
TSystems
TSystems
  • represents a list of systems to be loaded
Return value
Possible name
Description
tuple_systems, [system_foo, system_bar]
Tuple<TSystem &>
  • Tuple of systems loaded.
Example
// Tuple packed
auto tuple_systems = system_manager.load_systems<system_foo, system_bar>();
// Tuple unpacked
auto [system_foo, system_bar] = system_manager.load_systems<system_foo, system_bar>();

nb_systems

size_t nb_systems() const noexcept;
size_t nb_systems(system_type sys_type) const noexcept;

Parameters

Name
Description
sys_type
  • represent the type of systems

Return value

Possible name
Description
nb_systems
size_t
  • (first overload) number of systems
  • (second overload) number of systems of a specific type
Example
//! Retrieve the number of systems.
size_t nb_systems = system_manager.nb_systems();
//! Retrieve the number of systems by a specific system_type.
size_t nb_systems_logic = system_manager.nb_systems(shiva::ecs::system_type::logic_update);

load_plugins

bool load_plugins() noexcept;

Return value

Possible name
Description
result
boolean
  • true if all the plugins has been successfully loaded
  • false otherwise
Example
bool result = system_manager.load_plugins();
if (!result) {
// Oh no, atleast one of the plugins could not be loaded.
}

Notes

This function allow you to load the plugins of the plugins_registry and create systems with the creator function of each plugins.

get_system_by_name

const base_system *get_system_by_name(std::string system_name,
shiva::ecs::system_type type) const noexcept;
base_system *get_system_by_name(std::string system_name,
shiva::ecs::system_type type) noexcept;

Parameters

Name
Description
system_name
string
  • name of the system to get
type
  • system_type of the system to get
Return value
Possible name
Description
render_system
base_system *
  • pointer to the base system which match this name, nullptr otherwise.
Example
base_system* render_system = system_manager.get_system_by_name("render_system", shiva::ecs::system_type::post_update);
if (render_system == nullptr) {
//! Oh no, could not get the system properly.
}
Notes
  • This function allow you to get a system by his name, used for get a specific plugin for example.

base_system

This class is an abstract class, it is documented but is present only to make type-erasure of the class system which is templated
This class can be manipulated when using plugins to share data between them.

Description

base class of shiva systems

Diagram

base_system

base_system API

Signature
Constructor
Functions
class base_system;
explicit base_system(entt::dispatcher &dispatcher,
entt::entity_registry &entity_registry,
const float &fixed_delta_time) noexcept
Function Name
Description
update
Pure virtual function, must be overriden by the client. update the system.
get_name
Pure virtual function, must be overriden by the client. get the system name.
get_system_type_RTTI
Pure virtual function, override by the system class. get the system type at runtime (for plugins).
mark
mark the system
unmark
unmark the system
is_marked
check if the system is marked.
enable
enable the system
disable
disable the system
check if the system is enabled.
defines the system as a plugin.
check if the system is a plugin.
retrieve a user data previously set by set_user_data
set a user data for the system

mark

void mark() noexcept
Example
auto& render_system = system_manager.get_system<my_game::render>();
render_system.mark();
This function marks the system, it will be destroyed in the next tick of the game loop by the system_manager.

unmark

void unmark() noexcept
Example
auto& render_system = system_manager.get_system<my_game::render>();
render_system.unmark();
This function unmark the system, allows the prevention of a destruction in the next tick of the game loop by the system_manager.

is_marked

bool is_marked() const noexcept
Return value
Possible name
Description
result
boolean
  • true if the system is marked
  • false otherwise
Example
auto& render_system = system_manager.get_system<my_game::render>();
bool result = render_system.is_marked();
if (!result) {
//! render_system is not marked
}

enable

void enable() noexcept
Example
auto& render_system = system_manager.get_system<my_game::render>();
render_system.enable();

disable

void disable() noexcept
Example
auto& render_system = system_manager.get_system<my_game::render>();
render_system.disable();
Take a look @ disable_system

is_enabled

bool is_enabled() const noexcept
Return value
Possible name
Description
result
boolean
  • true if the system is enabled
  • false otherwise
Example
auto& render_system = system_manager.get_system<my_game::render>();
bool result = render_system.is_enabled();
if (!result) {
//! render_system is not enable
}

im_a_plugin

void im_a_plugin() noexcept
Example
auto& render_system = system_manager.get_system<my_game::render>();
render_system.im_a_plugin();
This function defines the system as a plugin, and therefore use more feature in runtime to work properly
By default this function is called on plugins.

is_a_plugin

bool is_a_plugin() const noexcept
Return value
Possible name
Description
result
boolean
  • true if the system is a plugin
  • false otherwise
Example
auto& render_system = system_manager.get_system<my_game::render>();
bool result = render_system.is_a_plugin();
if (!result) {
//! render_system is not a plugin
}

get_user_data

void *get_user_data() noexcept;
Return value
Possible name
Description
data
void *
  • user data of a system (nullptr by default)

Example

auto render_system = system_manager_.get_system_by_name("render_system", shiva::ecs::system_type::post_update);
auto input_system = system_manager_.get_system_by_name("input_system", shiva::ecs::system_type::pre_update);
input_system->set_user_data(render_system->get_user_data());
  • This function retrieve a user data previously set by set_user_data
  • by default a user_data is a void pointer equal to nullptr.

set_user_data

void set_user_data(void *data) noexcept;

Parameters

Name
Description
data
void *
  • a void pointer representing the user data
Example
See the example above.
  • This function set a user data for this system
  • This function is very useful to transfer (with get_user_data) data between plugins since they are base_class.
  • This function wcall on_set_user_data callback at the epilogue, by default on_set_user_data is empty and you need to override it if you need it.
  • user should be aware here, that's manipulating void pointer is as your own risk.

system

Description

This class is the class that you have to inherit to create your systems