To start create two files system_example_plugin.hpp and system_example_plugin.cpp
system_example_plugin.hpp
#include<shiva/entt/entt.hpp>#include<shiva/ecs/system.hpp>namespace my_game::plugins{ //! Depending on the system_type, the inheritance can be different.classsystem_examplefinal:public shiva::ecs::post_update_system<system_example> {public: //! Destructor~system_example() noexceptfinal=default; /* Only this constructor is allowed in plugins */ //! Constructorsystem_example(shiva::entt::dispatcher&dispatcher, shiva::entt::entity_registry®istry,constfloat&fixed_delta_time) noexcept; //! The creator function (entry point of your plugins) //! Return should always be a unique_ptr on base_system in pluginsstatic std::unique_ptr<shiva::ecs::base_system> system_creator(entt::dispatcher&dispatcher, entt::entity_registry®istry,constfloat&fixed_delta_time) noexcept; //! override from base_system //! The logic of the system will be inside this functionvoidupdate() noexceptfinal; //! Reflection (mandatory by a type_traits)reflect_class(render_system)staticconstexprautoreflected_functions() noexcept; static constexpr auto reflected_members() noexcept;
private: //! You can have additional data here }}
system_example_plugin.cpp
#include<boost/dll.hpp>//! For BOOST_DLL_ALIAS#include"system_example_plugin.hpp"namespace my_game::plugins{ //! Implementation of the constructor system_example::system_example(shiva::entt::dispatcher &dispatcher, shiva::entt::entity_registry ®istry,constfloat&fixed_delta_time) noexcept :system(dispatcher, registry, fixed_delta_time,true) //! true means im_a_plugin { //! You can set user data here if you want to share data betweens plugins user_data_ = /* whatever you want */; //! Also if you need to initialize some things for the system is here. } //! The creator factory implementation std::unique_ptr<shiva::ecs::base_system> example_system::system_creator(shiva::entt::dispatcher&dispatcher, shiva::entt::entity_registry®istry,constfloat&fixed_delta_time) noexcept {return std::make_unique<my_game::plugins::system_example>(dispatcher, registry, fixed_delta_time); } //! override from base systemvoid system_example::update() noexcept { /* Write your code here. */ } //! Reflectionconstexprauto system_example::reflected_functions() noexcept {return meta::makeMap(reflect_function(&system_example::update)); }constexprauto system_example::reflected_members() noexcept {return meta::makeMap(); }}BOOST_DLL_ALIAS( my_game::plugins::system_example::system_creator, // <-- this function is exported with... (from boost) create_plugin // <-- ...this alias name (from boost))
How to share data between plugins (without the dispatcher)
We assume here that you have set the user_data as shown in the example above
In the example you see above which is directly derived from the shiva code for the shiva-sfml module, I needed to share the SFML window in several different modules, for input and rendering, for example. through functions like set_user_data && get_user_data, I'm able to transfer data that only concerns plugins.
How to subscribe/emit event from a system plugin (or header-only)
Here's an example of how you could do it
//! system_example.hppclasssystem_example{public: /* ... other class things */ //! Callback (you will receive the event in this function)voidreceive(const shiva::event::key_pressed&evt);};//! system_example.cpp system_example::system_example(shiva::entt::dispatcher &dispatcher, shiva::entt::entity_registry ®istry,constfloat&fixed_delta_time) noexcept :system(dispatcher, registry, fixed_delta_time,true) //! true means im_a_plugin{ //! You can set user data here if you want to share data betweens plugins user_data_ = /* whatever you want */; //! Also if you need to initialize some things for the system is here. //! Subscribe to an eventthis->dispatcher_.sink<shiva::event::key_pressed>().connect(this); //! emit an eventthis->dispatcher_.trigger<shiva::event::key_pressed>(shiva::input::keyboard::TKey::A);}void system_example::receive(const shiva::event::key_pressed&evt){ //! Treat your event here}
CMake
Here are two examples of CMake possible for the implementation of a plugin with shiva, one in the project directly if you are contributors, one externally if you make plugins for shiva in another repository