Table of Contents
Making a module can be done through the following steps:
You can easily modify any parts later; take it easy!
The header skyai/skyai.h is needed:
#include <skyai/skyai.h>
//=========================================================================================== class TXxConfigurations //=========================================================================================== { public: TReal TestC; TXxConfigurations (var_space::TVariableMap &mmap) : TestC (0.0l) { Register(mmap); } void Register (var_space::TVariableMap &mmap) { #define ADD(x_member) AddToVarMap(mmap, #x_member, x_member) ADD( TestC ); #undef ADD } }; //-------------------------------------------------------------------------------------------
#include <lora/variable_space_impl.h>
//=========================================================================================== class TXxMemory //=========================================================================================== { public: TReal TestM; TXxMemory (var_space::TVariableMap &mmap) : TestM (0.0l) { Register(mmap); } void Register (var_space::TVariableMap &mmap) { #define ADD(x_member) AddToVarMap(mmap, #x_member, x_member) ADD( TestM ); #undef ADD } }; //-------------------------------------------------------------------------------------------
//=========================================================================================== //!\brief XX module class MXxModule : public MParentModule //=========================================================================================== { public: typedef MParentModule TParent; typedef MXxModule TThis; SKYAI_MODULE_NAMES(MXxModule) MXxModule (const std::string &v_instance_name) : TParent (v_instance_name), conf_ (TParent::param_box_config_map()), mem_ (TParent::param_box_memory_map()) { } protected: TXxConfigurations conf_; TXxMemory mem_; }; // end of MXxModule //-------------------------------------------------------------------------------------------Verbose template:
//=========================================================================================== //!\brief XX module class MXxModule : public MParentModule //=========================================================================================== { public: typedef MParentModule TParent; // optional typedef MXxModule TThis; // optional SKYAI_MODULE_NAMES(MXxModule) // mandatory MXxModule (const std::string &v_instance_name) : TParent (v_instance_name), // mandatory conf_ (TParent::param_box_config_map()), mem_ (TParent::param_box_memory_map()), slot_slot1 (*this), // optional signal_signal1 (*this), // optional out_out1 (*this), // optional in_in1 (*this) // optional { add_slot_port (slot_slot1); // optional add_signal_port (signal_signal1); // optional add_out_port (out_out1); // optional add_in_port (in_in1); // optional } protected: TXxConfigurations conf_; // optional TXxMemory mem_; // optional MAKE_SLOT_PORT(slot_slot1, TOutType, (const TInType &x), (x), TThis); // optional MAKE_SIGNAL_PORT(signal_signal1, const TOutType& (const TInType &), TThis); // optional MAKE_OUT_PORT(out_out1, const TOutType&, (const TInType &x), (x), TThis); // optional MAKE_IN_PORT(in_in1, const TOutType& (const TInType &), TThis); // optional virtual TOutType slot_slot1_exec (const TInType &x) // optional { ... } virtual const TOutType& out_out1_get (const TInType &x) const // optional { ... } }; // end of MXxModule //-------------------------------------------------------------------------------------------
MAKE_SLOT_PORT(slot_slot1, TOutType, (const TInType &x), (x), TThis); // change slot1 to the name of the slot port // change TOutType to the return type of the callback function // change const TInType &x to the parameter list of the callback function // change x to the argument list of the callback function // e.g. MAKE_SLOT_PORT(slot_action, void, (const TReal &x,const TReal &y), (x,y), TThis);
MXxModule (const std::string &v_instance_name) : ... slot_slot1 (*this), // like this ...
add_slot_port (slot_slot1);
// change slot1 to the name of the slot port virtual TOutType slot_slot1_exec (const TInType &x) { ... }
MAKE_SIGNAL_PORT(signal_signal1, const TOutType& (const TInType &), TThis); // change signal1 to the name of the signal port // change TOutType to the return type of the callback function // change const TInType & to the parameter list of the callback function // e.g. MAKE_SIGNAL_PORT(signal_action, void (const TReal &x,const TReal &y), TThis)
MXxModule (const std::string &v_instance_name) : ... signal_signal1 (*this), // like this ...
add_signal_port (signal_signal1);
MAKE_OUT_PORT(out_out1, const TOutType&, (const TInType &x), (x), TThis); // change out1 to the name of the out port // change TOutType to the return type of the function // change const TInType &x to the parameter list of the function // change x to the argument list of the function // e.g. MAKE_OUT_PORT(out_state, const TRealVector&, (void), (), TThis);
MXxModule (const std::string &v_instance_name) : ... out_out1 (*this), // like this ...
add_out_port (out_out1);
// change out1 to the name of the out port virtual const TOutType& out_out1_get (const TInType &x) const { ... }
MAKE_IN_PORT(in_in1, const TOutType& (const TInType &), TThis); // change in1 to the name of the in port // change TOutType to the return type of the function // change const TInType &x to the parameter list of the function // e.g. MAKE_IN_PORT(in_state, const TRealVector& (void), TThis);
MXxModule (const std::string &v_instance_name) : ... in_in1 (*this), // like this ...
add_in_port (in_in1);
SKYAI_ADD_MODULE(MXxModule)
In the member functions of a module including the callbacks of slot ports and the functions of out ports, the following elements are important:
In order to emit a signal at a signal port, write as follows:
signal_signal1.ExecAll(x,y);
The member function ExecAll emits a signal to every slot ports connected to the signal port. The return values are ignored. If no slot port is connected, nothing happens.
In order to use a function connected to an in port, write as follows:
TRealVector y= in_in1.GetFirst(x);
Here, the member function GetFirst execute the function of the first out port connected to the in port with an argument x, whose return is stored in y. Recall that in default, only one out port can be connected to an in port.
If no out port is connected, GetFirst causes an error. In order to avoid the error, you need to check the size of connections by:
in_in1.ConnectionSize()
this returns the number of connected out ports.
We suggest to wrap the GetFirst by using a macro as follows:
MAKE_IN_PORT(in_state, const TRealVector& (void), TThis); MAKE_IN_PORT(in_func, const TReal& (const TReal &x), TThis); #define GET_FROM_IN_PORT(x_in,x_return_type,x_arg_list,x_param_list) \ x_return_type get_##x_in x_arg_list const \ { \ if (in_##x_in.ConnectionSize()==0) \ {LERROR("in "<<ModuleUniqueCode()<<", in_" #x_in " must be connected."); lexit(df);} \ return in_##x_in.GetFirst x_param_list; \ } GET_FROM_IN_PORT(state, const TRealVector&, (void), ()) GET_FROM_IN_PORT(func, const TReal&, (const TReal &x), (x)) #undef GET_FROM_IN_PORT
Then, we can use get_state and get_func like a normal function; e.g.
TRealVector x= get_state(); TReal y= get_func(1.2);
The macro GET_FROM_IN_PORT is generic, so you can copy and paste it in your code as is. Do not forget to un-define it (i.e. #undef GET_FROM_IN_PORT).