SObjectizer 5.8
Loading...
Searching...
No Matches
so_5::state_t Class Referencefinal

Class for the representing agent state. More...

#include <state.hpp>

Classes

struct  time_limit_t
 

Public Types

enum class  history_t { none , shallow , deep }
 Type of history for state. More...
 
using path_t = std::array< const state_t *, max_deep >
 A type for representation of state's path.
 
using on_enter_handler_t = std::function< void() >
 Type of function to be called on enter to the state.
 
using on_exit_handler_t = std::function< void() >
 Type of function to be called on exit from the state.
 
using duration_t = std::chrono::high_resolution_clock::duration
 Alias for duration type.
 

Public Member Functions

 state_t (agent_t *agent)
 
 state_t (agent_t *agent, history_t state_history)
 
 state_t (agent_t *agent, std::string state_name)
 
 state_t (agent_t *agent, std::string state_name, history_t state_history)
 
 state_t (initial_substate_of parent)
 Constructor for the case when state is the initial substate of some parent state.
 
 state_t (initial_substate_of parent, history_t state_history)
 Constructor for the case when state is the initial substate of some parent state.
 
 state_t (initial_substate_of parent, std::string state_name)
 Constructor for the case when state is the initial substate of some parent state.
 
 state_t (initial_substate_of parent, std::string state_name, history_t state_history)
 Constructor for the case when state is the initial substate of some parent state.
 
 state_t (substate_of parent)
 Constructor for the case when state is a substate of some parent state.
 
 state_t (substate_of parent, history_t state_history)
 Constructor for the case when state is a substate of some parent state.
 
 state_t (substate_of parent, std::string state_name)
 Constructor for the case when state is a substate of some parent state.
 
 state_t (substate_of parent, std::string state_name, history_t state_history)
 Constructor for the case when state is a substate of some parent state.
 
 state_t (state_t &&other)
 Move constructor.
 
 ~state_t ()
 
bool operator== (const state_t &state) const noexcept
 
bool operator!= (const state_t &state) const noexcept
 
std::string query_name () const
 Get textual name of the state.
 
bool is_target (const agent_t *agent) const noexcept
 Is agent owner of this state?
 
void activate () const
 Switch agent to that state.
 
bool is_active () const noexcept
 Is this state or any of its substates activated?
 
void clear_history () noexcept
 Clear state history.
 
template<typename... Args>
const state_tevent (Args &&... args) const
 Helper for subscription of event handler in this state.
 
template<typename... Args>
state_tevent (Args &&... args)
 
template<typename... Args>
const state_tevent (mbox_t from, Args &&... args) const
 Helper for subscription of event handler in this state.
 
template<typename... Args>
state_tevent (mbox_t from, Args &&... args)
 
template<typename Msg >
bool has_subscription (const mbox_t &from) const
 Check the presence of a subscription.
 
template<typename Method_Pointer >
bool has_subscription (const mbox_t &from, Method_Pointer &&pfn) const
 Check the presence of a subscription.
 
template<typename Msg >
void drop_subscription (const mbox_t &from) const
 Drop subscription.
 
template<typename Method_Pointer >
void drop_subscription (const mbox_t &from, Method_Pointer &&pfn) const
 Drop subscription.
 
template<typename Msg >
const state_ttransfer_to_state (mbox_t from, const state_t &target_state) const
 An instruction for switching agent to the specified state and transfering event proceessing to new state.
 
template<typename Msg >
const state_ttransfer_to_state (const state_t &target_state) const
 An instruction for switching agent to the specified state and transfering event proceessing to new state.
 
template<typename Msg >
state_ttransfer_to_state (mbox_t from, const state_t &target_state)
 An instruction for switching agent to the specified state and transfering event proceessing to new state.
 
template<typename Msg >
state_ttransfer_to_state (const state_t &target_state)
 An instruction for switching agent to the specified state and transfering event proceessing to new state.
 
template<typename Msg >
const state_tjust_switch_to (mbox_t from, const state_t &target_state) const
 Define handler which only switches agent to the specified state.
 
template<typename Msg >
const state_tjust_switch_to (const state_t &target_state) const
 Define handler which only switches agent to the specified state.
 
template<typename Msg >
state_tjust_switch_to (mbox_t from, const state_t &target_state)
 Define handler which only switches agent to the specified state.
 
template<typename Msg >
state_tjust_switch_to (const state_t &target_state)
 Define handler which only switches agent to the specified state.
 
template<typename Msg >
const state_tsuppress () const
 Suppress processing of event in this state.
 
template<typename Msg >
const state_tsuppress (mbox_t from) const
 Suppress processing of event in this state.
 
template<typename Msg >
state_tsuppress ()
 Suppress processing of event in this state.
 
template<typename Msg >
state_tsuppress (mbox_t from)
 Suppress processing of event in this state.
 
Method for manupulation of enter/exit handlers.
state_ton_enter (on_enter_handler_t handler)
 Set on enter handler.
 
template<typename Method_Pointer >
std::enable_if< details::is_agent_method_pointer< details::method_arity::nullary, Method_Pointer >::value, state_t & >::type on_enter (Method_Pointer pfn)
 Set on enter handler.
 
const on_enter_handler_ton_enter () const
 Query on enter handler.
 
state_ton_exit (on_exit_handler_t handler)
 Set on exit handler.
 
template<typename Method_Pointer >
std::enable_if< details::is_agent_method_pointer< details::method_arity::nullary, Method_Pointer >::value, state_t & >::type on_exit (Method_Pointer pfn)
 Set on exit handler.
 
const on_exit_handler_ton_exit () const
 Query on enter handler.
 
Methods for dealing with state's time limit.
state_ttime_limit (duration_t timeout, const state_t &state_to_switch)
 Set up a time limit for the state.
 
state_tdrop_time_limit ()
 Drop time limit for the state if defined.
 

Static Public Attributes

static constexpr const std::size_t max_deep = 16
 Max deep of nested states.
 

Private Member Functions

 state_t (const state_t &)=delete
 
state_toperator= (const state_t &)=delete
 
 state_t (agent_t *target_agent, std::string state_name, state_t *parent_state, std::size_t nested_level, history_t state_history)
 Fully initialized constructor.
 
template<typename... Args>
const state_tsubscribe_message_handler (const mbox_t &from, Args &&... args) const
 A helper for handle-methods implementation.
 
Methods to be used by agents.
const state_tparent_state () const noexcept
 Get a parent state if exists.
 
const state_tactual_state_to_enter () const
 Find actual state to be activated for agent.
 
std::size_t nested_level () const noexcept
 Query nested level for the state.
 
void fill_path (path_t &path) const noexcept
 A helper method for building a path from top-level state to this state.
 
void update_history_in_parent_states () const
 A helper method which is used during state change for update state with history.
 
void handle_time_limit_on_enter () const
 A special handler of time limit to be used on entering into state.
 
void handle_time_limit_on_exit () const
 A special handler of time limit to be used on exiting from state.
 
void call_on_enter () const noexcept
 Call for on enter handler if defined.
 
void call_on_exit () const noexcept
 Call for on exit handler if defined.
 

Private Attributes

agent_t *const m_target_agent
 Owner of this state.
 
std::string m_state_name
 State name.
 
state_tm_parent_state
 Parent state.
 
const state_tm_initial_substate
 The initial substate.
 
history_t m_state_history
 Type of state history.
 
const state_tm_last_active_substate
 Last active substate.
 
std::size_t m_nested_level
 Nesting level for state.
 
size_t m_substate_count
 Number of substates.
 
on_enter_handler_t m_on_enter
 Handler for the enter to the state.
 
on_exit_handler_t m_on_exit
 Handler for the exit from the state.
 
std::unique_ptr< time_limit_tm_time_limit
 A definition of time limit for the state.
 

Friends

class agent_t
 

Detailed Description

Class for the representing agent state.

Attention
This class is not thread safe. It is designed to be used inside an owner agent only. For example:
class my_agent : public so_5::agent_t
{
state_t first_state{ this, "first" };
state_t second_state{ this, "second" };
...
public :
my_agent( context_t ctx ) : so_5::agent_t{ ctx }
{
// It is a safe usage of state.
first_state.on_enter( &my_agent::first_on_enter );
second_state.on_exit( &my_agent::second_on_exit );
...
}
virtual void so_define_agent() override
{
// It is a safe usage of state.
first_state.event( &my_agent::some_event_handler );
second_state.time_limit( std::chrono::seconds{20}, first_state );
second_state.event( [this]( const some_message & msg ) {
// It is also safe usage of state because event handler
// will be called on the context of agent's working thread.
second_state.drop_time_limit();
...
} );
}
void some_public_method()
{
// It is a safe usage if this method is called by the agent itself.
// This will be unsafe usage if this method is called from outside of
// the agent: a data damage or something like that can happen.
second_state.time_limit( std::chrono::seconds{30}, first_state );
}
...
};
A base class for agents.
Definition agent.hpp:673
virtual void so_define_agent()
Hook on define agent for SObjectizer.
Definition agent.cpp:841
agent_t(environment_t &env)
Constructor.
Definition agent.cpp:646
so_5::agent_context_t context_t
Short alias for agent_context.
Definition agent.hpp:692
Class for the representing agent state.
Definition state.hpp:148
Private part of message limit implementation.
Definition agent.cpp:33
Because of that be very careful during manipulation of agent's states outside of agent's event handlers.
Examples
so_5/chstate/main.cpp, and so_5/news_board/main.cpp.

Definition at line 147 of file state.hpp.

Member Typedef Documentation

◆ duration_t

using so_5::state_t::duration_t = std::chrono::high_resolution_clock::duration

Alias for duration type.

Since
v.5.5.15

Definition at line 220 of file state.hpp.

◆ on_enter_handler_t

using so_5::state_t::on_enter_handler_t = std::function< void() >

Type of function to be called on enter to the state.

Since
v.5.5.15
Attention
Handler must be noexcept function.

Definition at line 202 of file state.hpp.

◆ on_exit_handler_t

using so_5::state_t::on_exit_handler_t = std::function< void() >

Type of function to be called on exit from the state.

Since
v.5.5.15
Attention
Handler must be noexcept function.

Definition at line 212 of file state.hpp.

◆ path_t

using so_5::state_t::path_t = std::array< const state_t *, max_deep >

A type for representation of state's path.

Since
v.5.5.15
Note
Path contains pointer to the state itself (always the last item in the path) and pointers to all superstates. If state has no superstate the path will contains just one pointer to the state itself.

Definition at line 192 of file state.hpp.

Member Enumeration Documentation

◆ history_t

enum class so_5::state_t::history_t
strong

Type of history for state.

Since
v.5.5.15
Enumerator
none 

State has no history.

shallow 

State has shallow history.

deep 

State has deep history.

Definition at line 171 of file state.hpp.

Constructor & Destructor Documentation

◆ state_t() [1/15]

so_5::state_t::state_t ( const state_t & )
privatedelete

◆ state_t() [2/15]

so_5::state_t::state_t ( agent_t * agent)
Note
State name will be generated automaticaly.
Parameters
agentState owner.

Definition at line 301 of file agent.cpp.

◆ state_t() [3/15]

so_5::state_t::state_t ( agent_t * agent,
history_t state_history )
Since
v.5.5.15
Note
State name will be generated automaticaly.
Parameters
agentState owner.
state_historyType of state history.

Definition at line 307 of file agent.cpp.

◆ state_t() [4/15]

so_5::state_t::state_t ( agent_t * agent,
std::string state_name )
Parameters
agentState owner.
state_nameState name.

Definition at line 314 of file agent.cpp.

◆ state_t() [5/15]

so_5::state_t::state_t ( agent_t * agent,
std::string state_name,
history_t state_history )
Since
v.5.5.15
Parameters
agentState owner.
state_nameState name.
state_historyType of state history.

Definition at line 320 of file agent.cpp.

◆ state_t() [6/15]

so_5::state_t::state_t ( initial_substate_of parent)

Constructor for the case when state is the initial substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.

Definition at line 327 of file agent.cpp.

◆ state_t() [7/15]

so_5::state_t::state_t ( initial_substate_of parent,
history_t state_history )

Constructor for the case when state is the initial substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_historyType of state history.

◆ state_t() [8/15]

so_5::state_t::state_t ( initial_substate_of parent,
std::string state_name )

Constructor for the case when state is the initial substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_nameState name.

Definition at line 332 of file agent.cpp.

◆ state_t() [9/15]

so_5::state_t::state_t ( initial_substate_of parent,
std::string state_name,
history_t state_history )

Constructor for the case when state is the initial substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_nameState name.
state_historyType of state history.

Definition at line 338 of file agent.cpp.

◆ state_t() [10/15]

so_5::state_t::state_t ( substate_of parent)

Constructor for the case when state is a substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.

Definition at line 358 of file agent.cpp.

◆ state_t() [11/15]

so_5::state_t::state_t ( substate_of parent,
history_t state_history )

Constructor for the case when state is a substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_historyType of state history.

◆ state_t() [12/15]

so_5::state_t::state_t ( substate_of parent,
std::string state_name )

Constructor for the case when state is a substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_nameState name.

Definition at line 363 of file agent.cpp.

◆ state_t() [13/15]

so_5::state_t::state_t ( substate_of parent,
std::string state_name,
history_t state_history )

Constructor for the case when state is a substate of some parent state.

Since
v.5.5.15
Parameters
parentParent state.
state_nameState name.
state_historyType of state history.

Definition at line 369 of file agent.cpp.

◆ state_t() [14/15]

so_5::state_t::state_t ( state_t && other)

Move constructor.

Since
v.5.4.0

Definition at line 381 of file agent.cpp.

◆ ~state_t()

so_5::state_t::~state_t ( )

Definition at line 398 of file agent.cpp.

◆ state_t() [15/15]

so_5::state_t::state_t ( agent_t * target_agent,
std::string state_name,
state_t * parent_state,
std::size_t nested_level,
history_t state_history )
private

Fully initialized constructor.

Since
v.5.5.15
Parameters
target_agentOwner of this state.
state_nameName for this state.
parent_stateParent state. nullptr means that there is no parent state.
nested_levelNesting deep for this state. Value 0 means this state is a top-level state.
state_historyType of state history.

Definition at line 273 of file agent.cpp.

Member Function Documentation

◆ activate()

void so_5::state_t::activate ( ) const

Switch agent to that state.

Since
v.5.5.1

Definition at line 474 of file agent.cpp.

◆ actual_state_to_enter()

const state_t * so_5::state_t::actual_state_to_enter ( ) const
private

Find actual state to be activated for agent.

Since
v.5.5.15
Note
If (*this) is a composite state then actual state to enter will be its m_initial_substate (if m_initial_substate is a composite state then actual state to enter will be its m_initial_substate and so on).
If this state is a composite state with history then m_last_active_substate value will be used (if it is not nullptr).
Exceptions
exception_tif (*this) is a composite state but m_initial_substate is not defined.

Definition at line 526 of file agent.cpp.

◆ call_on_enter()

void so_5::state_t::call_on_enter ( ) const
inlineprivatenoexcept

Call for on enter handler if defined.

Since
v.5.5.15

Definition at line 1837 of file state.hpp.

◆ call_on_exit()

void so_5::state_t::call_on_exit ( ) const
inlineprivatenoexcept

Call for on exit handler if defined.

Since
v.5.5.15

Definition at line 1850 of file state.hpp.

◆ clear_history()

void so_5::state_t::clear_history ( )
inlinenoexcept

Clear state history.

Since
v.5.5.15
Note
Clears the history for this state only. History for any substates remains intact. For example:
class demo : public so_5::agent_t
{
state_t A{ this, "A", deep_history };
state_t C{ initial_substate_of{ B }, "C" };
state_t D{ substate_of{ B }, "D" };
state_t E{ this, "E" };
...
void some_event()
{
this >>= A; // The current state is "A.B.C"
// Because B is initial substate of A, and
// C is initial substate of B.
this >>= D; // The current state is "A.B.D".
this >>= E; // The current state is "E".
this >>= A; // The current state is "A.B.D" because deep history of A.
this >>= E;
this >>= A; // The current state is "A.B.D" because:
// B is the initial substate of A and B has shallow history;
// D is the last active substate of B.
}
};
so_5::substate_of substate_of
Short alias for so_5::substate_of.
Definition agent.hpp:724
static constexpr const state_t::history_t deep_history
Short alias for so_5::state_t::history_t::deep.
Definition agent.hpp:737
so_5::state_t state_t
Short alias for so_5::state_t.
Definition agent.hpp:698
static constexpr const state_t::history_t shallow_history
Short alias for so_5::state_t::history_t::shallow.
Definition agent.hpp:730
so_5::initial_substate_of initial_substate_of
Short alias for so_5::initial_substate_of.
Definition agent.hpp:718
void clear_history() noexcept
Clear state history.
Definition state.hpp:449
Helper for marking initial substate of composite state.
Definition state.hpp:57
Attention
This method is not thread safe. Be careful calling this method from outside of agent's working thread.

Definition at line 449 of file state.hpp.

◆ drop_subscription() [1/2]

template<typename Msg >
void so_5::state_t::drop_subscription ( const mbox_t & from) const

Drop subscription.

Drops the subscription for the message/signal of type Msg for the state (if this subscription is present). Do nothing if subscription is not exists.

Usage example:

class my_agent : public so_5::agent_t
{
state_t some_state{ this };
...
virtual void so_define_agent() override
{
some_state.event(some_mbox, &my_agent::some_handler);
...
}
...
void evt_some_another_handler()
{
// A subscription is no more needed.
some_state.drop_subscription<msg>(some_mbox);
}
};
const state_t & event(Args &&... args) const
Helper for subscription of event handler in this state.
Definition agent.hpp:3758
void drop_subscription(const mbox_t &from) const
Drop subscription.
Definition agent.hpp:3794
Note
This method should be called only from the working context of the agent.
Since
v.5.5.19.5

Definition at line 3794 of file agent.hpp.

◆ drop_subscription() [2/2]

template<typename Method_Pointer >
void so_5::state_t::drop_subscription ( const mbox_t & from,
Method_Pointer && pfn ) const

Drop subscription.

Drops the subscription for the message/signal for the state (if this subscription is present). Do nothing if subscription is not exists.

Type of a message is deduced from event handler signature.

Usage example:

class my_agent : public so_5::agent_t
{
state_t some_state{ this };
...
virtual void so_define_agent() override
{
some_state.event(some_mbox, &my_agent::some_handler);
...
}
...
void some_another_handler()
{
// A subscription is no more needed.
some_state.drop_subscription(some_mbox, &my_agent::some_handler);
}
void some_handler(mhood_t<msg> cmd)
{
...
}
};
so_5::mhood_t< T > mhood_t
Short alias for so_5::mhood_t.
Definition agent.hpp:705
Note
This method should be called only from the working context of the agent.
Since
v.5.5.19.5

Definition at line 3801 of file agent.hpp.

◆ drop_time_limit()

state_t & so_5::state_t::drop_time_limit ( )

Drop time limit for the state if defined.

Since
v.5.5.15
Note
Do nothing if a time limit is not defined.
This method can be useful if there is need to refine state defined in the parent class:
class parent : public so_5::agent_t
{
protected :
state_t dialog{ this, "dialog" };
state_t show_err{ this, "err" };
...
public :
virtual void so_define_agent() override
{
dialog
.on_enter( [this] { m_display.clear(); } )
.event( [this]( const user_input & msg ) {
try_handle_input( msg );
if( some_error() ) {
m_error = error_description();
this >>= show_err;
}
} )
...; // Other handlers.
show_err
.on_enter( [this] { m_display.show( m_error ); } )
.time_limit( std::chrono::seconds{2}, dialog );
}
...
protected :
display m_display;
std::string m_error;
...
};
class child : public parent
{
public :
virtual void so_define_agent() override
{
parent::so_define_agent();
show_err
// Switching from show_err to dialog must be done
// only by pressing "cancel" or "ok" buttons.
// Automatic switching after 2s must be disabled.
.drop_time_limit()
.just_switch_to< key_cancel >( dialog )
.just_switch_to< key_on >( dialog );
}
...
};
state_t & on_enter(on_enter_handler_t handler)
Set on enter handler.
Definition state.hpp:1209
This method can be called when agents is already in that state. Automatic switching will be disabled. To reenable automatic switching time_limit() method must be called again:
class demo : public so_5::agent_t
{
state_t dialog{ this, "dialog" };
state_t show_err{ this, "err" };
...
public :
virtual void so_define_agent() override
{
dialog
.on_enter( [this] { m_display.clear(); } )
.event( [this]( const user_input & msg ) {
try_handle_input( msg );
if( some_error() ) {
m_error = error_description();
this >>= show_err;
}
} )
...; // Other handlers.
show_err
.on_enter( [this] { m_display.show( m_error ); } )
// By default state will be switched after 2s.
.time_limit( std::chrono::seconds{2}, dialog )
.event< key_pause >( [this] {
// Disable automatic switching.
show_err.drop_time_limit();
} )
.event< key_continue >( [this] {
// Automatic switching is reenabled.
show_err.time_limit( std::chrono::seconds{2}, dialog );
...
} );
}
...
private :
display m_display;
std::string m_error;
...
};

Definition at line 514 of file agent.cpp.

◆ event() [1/4]

template<typename... Args>
state_t & so_5::state_t::event ( Args &&... args)
inline
Since
v.5.5.15

Definition at line 488 of file state.hpp.

◆ event() [2/4]

template<typename... Args>
const state_t & so_5::state_t::event ( Args &&... args) const

Helper for subscription of event handler in this state.

Since
v.5.5.1
Note
This method must be used for messages which are sent to agent's direct mbox.
Usage example
class my_agent : public so_5::agent_t
{
const so_5::state_t st_normal = so_make_state();
public :
...
virtual void so_define_agent() override {
st_normal.event( [=]( const msg_reconfig & evt ) { ... } );
st_normal.event( &my_agent::evt_shutdown );
...
}
};
Examples
so_5/chameneos_prealloc_msgs/main.cpp, so_5/chameneos_simple/main.cpp, so_5/chstate_msg_tracing/main.cpp, so_5/coop_notification/main.cpp, so_5/coop_user_resources/main.cpp, so_5/default_message_limits/main.cpp, so_5/dispatcher_for_children/main.cpp, so_5/dispatcher_for_children_2/main.cpp, so_5/dispatcher_hello/main.cpp, so_5/dispatcher_restarts/main.cpp, so_5/ping_pong_with_owner/main.cpp, so_5/queue_size_stats/main.cpp, so_5/redirect_and_transform/main.cpp, and so_5/simple_message_deadline/main.cpp.

Definition at line 3758 of file agent.hpp.

◆ event() [3/4]

template<typename... Args>
state_t & so_5::state_t::event ( mbox_t from,
Args &&... args )
inline
Since
v.5.5.15

Definition at line 531 of file state.hpp.

◆ event() [4/4]

template<typename... Args>
const state_t & so_5::state_t::event ( mbox_t from,
Args &&... args ) const

Helper for subscription of event handler in this state.

Since
v.5.5.1
Note
This method must be used for messages which are sent to from message-box.
Usage example
class my_agent : public so_5::agent_t
{
const so_5::state_t st_normal = so_make_state();
public :
...
virtual void so_define_agent() override {
st_normal.event( m_owner, [=]( const msg_reconfig & evt ) { ... } );
st_normal.event( m_owner, &my_agent::evt_shutdown );
...
}
private :
so_5::mbox_t m_owner;
};

Definition at line 3767 of file agent.hpp.

◆ fill_path()

void so_5::state_t::fill_path ( path_t & path) const
inlineprivatenoexcept

A helper method for building a path from top-level state to this state.

Since
v.5.5.15

Definition at line 1793 of file state.hpp.

◆ handle_time_limit_on_enter()

void so_5::state_t::handle_time_limit_on_enter ( ) const
private

A special handler of time limit to be used on entering into state.

Since
v.5.5.15
Attention
This method must be called only if m_time_limit is not null.

Definition at line 570 of file agent.cpp.

◆ handle_time_limit_on_exit()

void so_5::state_t::handle_time_limit_on_exit ( ) const
private

A special handler of time limit to be used on exiting from state.

Since
v.5.5.15
Attention
This method must be called only if m_time_limit is not null.

Definition at line 576 of file agent.cpp.

◆ has_subscription() [1/2]

template<typename Msg >
bool so_5::state_t::has_subscription ( const mbox_t & from) const

Check the presence of a subscription.

Returns
true if subscription is present.

Usage example:

void my_agent::evt_create_new_subscription(mhood_t<data_source> cmd)
{
// cmd can contain mbox we have already subscribed to.
// If we just call so_subscribe() then an exception can be thrown.
// Because of that check the presence of subscription first.
if(!some_state.has_subscription<some_message>(cmd->mbox()))
{
// There is no subscription yet. New subscription can be
// created.
some_state.event(cmd->mbox(), ...);
}
}
A message wrapped to be used as type of argument for event handlers.
Definition mhood.hpp:570
See also
so_5::agent_t::so_has_subscription
Since
v.5.5.19.5

Definition at line 3775 of file agent.hpp.

◆ has_subscription() [2/2]

template<typename Method_Pointer >
bool so_5::state_t::has_subscription ( const mbox_t & from,
Method_Pointer && pfn ) const

Check the presence of a subscription.

Type is deduced from the signature of event_handler.

Returns
true if subscription is present.

Usage example:

void my_agent::evt_create_new_subscription(mhood_t<data_source> cmd)
{
// cmd can contain mbox we have already subscribed to.
// If we just call so_subscribe() then an exception can be thrown.
// Because of that check the presence of subscription first.
if(!some_state.has_subscription(cmd->mbox(), &my_agent::some_event))
{
// There is no subscription yet. New subscription can be
// created.
some_state.event(cmd->mbox(), ...);
}
}
See also
so_5::agent_t::so_has_subscription
Since
v.5.5.19.5

Definition at line 3782 of file agent.hpp.

◆ is_active()

bool so_5::state_t::is_active ( ) const
inlinenoexcept

Is this state or any of its substates activated?

Since
v.5.5.15
Note
See so_5::agent_t::so_is_active_state() for more details. This method is just a thin wrapper around agent_t::so_is_active_state().

Definition at line 3751 of file agent.hpp.

◆ is_target()

bool so_5::state_t::is_target ( const agent_t * agent) const
noexcept

Is agent owner of this state?

Definition at line 463 of file agent.cpp.

◆ just_switch_to() [1/4]

template<typename Msg >
state_t & so_5::state_t::just_switch_to ( const state_t & target_state)
inline

Define handler which only switches agent to the specified state.

Since
v.5.5.15
Note
Defines a reaction to message/signal which is going from agent's direct mbox.
This method differes from transfer_to_state() method: just_switch_to() changes state of the agent, but there will not be a look for event handler for message/signal in the new state. It means that just_switch_to() is just a shorthand for:
virtual void demo::so_define_agent() override
{
some_state.event< some_signal >( [this]{ this >>= S2; } );
}
With just_switch_to() this code can looks like:
virtual void demo::so_define_agent() override
{
some_state.just_switch_to< some_signal >( S2 );
}

Definition at line 968 of file state.hpp.

◆ just_switch_to() [2/4]

template<typename Msg >
const state_t & so_5::state_t::just_switch_to ( const state_t & target_state) const

Define handler which only switches agent to the specified state.

Since
v.5.5.15
Note
Defines a reaction to message/signal which is going from agent's direct mbox.
This method differes from transfer_to_state() method: just_switch_to() changes state of the agent, but there will not be a look for event handler for message/signal in the new state. It means that just_switch_to() is just a shorthand for:
virtual void demo::so_define_agent() override
{
some_state.event< some_signal >( [this]{ this >>= S2; } );
}
With just_switch_to() this code can looks like:
virtual void demo::so_define_agent() override
{
some_state.just_switch_to< some_signal >( S2 );
}

Definition at line 3844 of file agent.hpp.

◆ just_switch_to() [3/4]

template<typename Msg >
state_t & so_5::state_t::just_switch_to ( mbox_t from,
const state_t & target_state )
inline

Define handler which only switches agent to the specified state.

Since
v.5.5.15
Note
Defines a reaction to message/signal which is going from message box from.
This method differes from transfer_to_state() method: just_switch_to() changes state of the agent, but there will not be a look for event handler for message/signal in the new state. It means that just_switch_to() is just a shorthand for:
virtual void demo::so_define_agent() override
{
some_state.event< some_signal >( from, [this]{ this >>= S2; } );
}
mchain_receive_params_t< mchain_props::msg_count_status_t::undefined > from(mchain_t chain)
A helper function for simplification of creation of mchain_receive_params instance.
Definition mchain.hpp:1540
With just_switch_to() this code can looks like:
virtual void demo::so_define_agent() override
{
some_state.just_switch_to< some_signal >( from, S2 );
}

Definition at line 931 of file state.hpp.

◆ just_switch_to() [4/4]

template<typename Msg >
const state_t & so_5::state_t::just_switch_to ( mbox_t from,
const state_t & target_state ) const

Define handler which only switches agent to the specified state.

Since
v.5.5.15
Note
Defines a reaction to message/signal which is going from message box from.
This method differes from transfer_to_state() method: just_switch_to() changes state of the agent, but there will not be a look for event handler for message/signal in the new state. It means that just_switch_to() is just a shorthand for:
virtual void demo::so_define_agent() override
{
some_state.event< some_signal >( from, [this]{ this >>= S2; } );
}
With just_switch_to() this code can looks like:
virtual void demo::so_define_agent() override
{
some_state.just_switch_to< some_signal >( from, S2 );
}

Definition at line 3833 of file agent.hpp.

◆ nested_level()

std::size_t so_5::state_t::nested_level ( ) const
inlineprivatenoexcept

Query nested level for the state.

Since
v.5.5.15

Definition at line 1780 of file state.hpp.

◆ on_enter() [1/3]

const on_enter_handler_t & so_5::state_t::on_enter ( ) const
inline

Query on enter handler.

Since
v.5.5.15
Note
This method can be useful if there is a need to refine handler defined in the base class:
class parent : public so_5::agent_t
{
protected :
state_t some_state{ this, ... };
public :
virtual void so_define_agent() override
{
some_state.on_enter( [this] {
... // Some action.
} );
}
...
};
class child : public parent
{
public :
virtual void so_define_agent() override
{
// Calling so_define_agent from base class.
parent::so_define_agent();
// Refine on_enter handler for state from parent class.
auto old_handler = some_state.on_enter();
some_state.on_enter( [this, old_handler] {
old_handler(); // Calling the old handler.
... // Some addition action.
} );
}
...
};

Definition at line 1303 of file state.hpp.

◆ on_enter() [2/3]

template<typename Method_Pointer >
std::enable_if< details::is_agent_method_pointer< details::method_arity::nullary, Method_Pointer >::value, state_t & >::type so_5::state_t::on_enter ( Method_Pointer pfn)

Set on enter handler.

Since
v.5.5.15
Attention
Handler must be noexcept function. If handler throws an exception the whole application will be aborted.
Usage example:
class demo : public so_5::agent_t
{
state_t number_accumulation{ this, "accumulation" };
...
public :
virtual void so_define_agent() override
{
number_accumulation
.on_enter( &demo::accumulation_on_enter )
.event( [this]( const next_digit & msg ) {
m_number += msg.m_digit;
} );
...
}
...
private :
std::string m_number;
...
void accumulation_on_enter()
{
m_number.clear();
...
}
};

Definition at line 3875 of file agent.hpp.

◆ on_enter() [3/3]

state_t & so_5::state_t::on_enter ( on_enter_handler_t handler)
inline

Set on enter handler.

Since
v.5.5.15
Attention
Handler must be noexcept function. If handler throws an exception the whole application will be aborted.
Usage example:
class demo : public so_5::agent_t
{
state_t number_accumulation{ this, "accumulation" };
...
public :
virtual void so_define_agent() override
{
number_accumulation
.on_enter( [this] { m_number.clear(); } )
.event( [this]( const next_digit & msg ) {
m_number += msg.m_digit;
} );
...
}
...
private :
std::string m_number;
};

Definition at line 1209 of file state.hpp.

◆ on_exit() [1/3]

const on_exit_handler_t & so_5::state_t::on_exit ( ) const
inline

Query on enter handler.

Since
v.5.5.15
Note
This method can be useful if there is a need to refine handler defined in the base class:
class parent : public so_5::agent_t
{
protected :
state_t some_state{ this, ... };
public :
virtual void so_define_agent() override
{
some_state.on_exit( [this] {
... // Some action.
} );
}
...
};
class child : public parent
{
public :
virtual void so_define_agent() override
{
// Calling so_define_agent from base class.
parent::so_define_agent();
// Refine on_enter handler for state from parent class.
auto old_handler = some_state.on_exit();
some_state.on_exit( [this, old_handler] {
... // Some addition action.
old_handler(); // Calling the old handler.
} );
}
...
};
state_t & on_exit(on_exit_handler_t handler)
Set on exit handler.
Definition state.hpp:1338

Definition at line 1430 of file state.hpp.

◆ on_exit() [2/3]

template<typename Method_Pointer >
std::enable_if< details::is_agent_method_pointer< details::method_arity::nullary, Method_Pointer >::value, state_t & >::type so_5::state_t::on_exit ( Method_Pointer pfn)

Set on exit handler.

Since
v.5.5.15
Attention
Handler must be noexcept function. If handler throws an exception the whole application will be aborted.
Usage example:
class demo : public so_5::agent_t
{
state_t dialog{ this, "dialog" };
...
public :
virtual void so_define_agent() override
{
dialog
.on_exit( &demo::dialog_on_exit )
.event( [this]( const user_input & msg ) {...} );
...
}
...
private :
display m_display;
...
void dialog_on_exit()
{
m_display.turn_off();
...
}
};

Definition at line 3897 of file agent.hpp.

◆ on_exit() [3/3]

state_t & so_5::state_t::on_exit ( on_exit_handler_t handler)
inline

Set on exit handler.

Since
v.5.5.15
Attention
Handler must be noexcept function. If handler throws an exception the whole application will be aborted.
Usage example:
class demo : public so_5::agent_t
{
state_t dialog{ this, "dialog" };
...
public :
virtual void so_define_agent() override
{
dialog
.on_exit( [this] { m_display.turn_off(); } )
.event( [this]( const user_input & msg ) {...} );
...
}
...
private :
display m_display;
};

Definition at line 1338 of file state.hpp.

◆ operator!=()

bool so_5::state_t::operator!= ( const state_t & state) const
inlinenoexcept
Since
v.5.5.20.1

Definition at line 372 of file state.hpp.

◆ operator=()

state_t & so_5::state_t::operator= ( const state_t & )
privatedelete

◆ operator==()

bool so_5::state_t::operator== ( const state_t & state) const
noexcept

Definition at line 403 of file agent.cpp.

◆ parent_state()

const state_t * so_5::state_t::parent_state ( ) const
inlineprivatenoexcept

Get a parent state if exists.

Since
v.5.5.15

Definition at line 1748 of file state.hpp.

◆ query_name()

std::string so_5::state_t::query_name ( ) const

Get textual name of the state.

Note
The return type is changed in v.5.5.15: now it is a std::string object, not a const reference to some value inside state_t object.

Definition at line 409 of file agent.cpp.

◆ subscribe_message_handler()

template<typename... Args>
const state_t & so_5::state_t::subscribe_message_handler ( const mbox_t & from,
Args &&... args ) const
private

A helper for handle-methods implementation.

Since
v.5.5.1

Definition at line 3915 of file agent.hpp.

◆ suppress() [1/4]

template<typename Msg >
state_t & so_5::state_t::suppress ( )
inline

Suppress processing of event in this state.

Since
v.5.5.15
Note
Suppresses message/signal which is going from agent's direct mbox.
This method allows to disable passing of event to event handlers from parent states. For example:
class demo : public so_5::agent_t
{
state_t S1{ this, "1" };
state_t S2{ initial_substate_of{ S1 }, "2" };
state_t S3{ initial_substate_of{ S2 }, "3" };
public :
virtual void so_define_agent() override
{
S1
// Default event handler which will be inherited by states S2 and S3.
.event< msg1 >(...)
.event< msg2 >(...)
.event< msg3 >(...);
S2
// A special handler for msg1.
// For msg2 and msg3 event handlers from state S1 will be used.
.event< msg1 >(...);
S3
// Message msg1 will be suppressed. It will be simply ignored.
// No events from states S1 and S2 will be called.
.suppress< msg1 >()
// The same for msg2.
.suppress< msg2 >()
// A special handler for msg3. Overrides handler from state S1.
.event< msg3 >(...);
}
};

Definition at line 1114 of file state.hpp.

◆ suppress() [2/4]

template<typename Msg >
const state_t & so_5::state_t::suppress ( ) const

Suppress processing of event in this state.

Since
v.5.5.15
Note
Suppresses message/signal which is going from agent's direct mbox.
This method allows to disable passing of event to event handlers from parent states. For example:
class demo : public so_5::agent_t
{
const state_t S1{ this, "1" };
const state_t S2{ initial_substate_of{ S1 }, "2" };
const state_t S3{ initial_substate_of{ S2 }, "3" };
public :
virtual void so_define_agent() override
{
S1
// Default event handler which will be inherited by states S2 and S3.
.event< msg1 >(...)
.event< msg2 >(...)
.event< msg3 >(...);
S2
// A special handler for msg1.
// For msg2 and msg3 event handlers from state S1 will be used.
.event< msg1 >(...);
S3
// Message msg1 will be suppressed. It will be simply ignored.
// No events from states S1 and S2 will be called.
.suppress< msg1 >()
// The same for msg2.
.suppress< msg2 >()
// A special handler for msg3. Overrides handler from state S1.
.event< msg3 >(...);
}
};

Definition at line 3853 of file agent.hpp.

◆ suppress() [3/4]

template<typename Msg >
state_t & so_5::state_t::suppress ( mbox_t from)
inline

Suppress processing of event in this state.

Since
v.5.5.15
Note
Suppresses message/signal which is going from message box from.
This method allows to disable passing of event to event handlers from parent states. For example:
class demo : public so_5::agent_t
{
state_t S1{ this, "1" };
state_t S2{ initial_substate_of{ S1 }, "2" };
state_t S3{ initial_substate_of{ S2 }, "3" };
public :
virtual void so_define_agent() override
{
S1
// Default event handler which will be inherited by states S2 and S3.
.event< msg1 >( some_mbox, ...)
.event< msg2 >( some_mbox, ...)
.event< msg3 >( some_mbox, ...);
S2
// A special handler for msg1.
// For msg2 and msg3 event handlers from state S1 will be used.
.event< msg1 >( some_mbox, ...);
S3
// Message msg1 will be suppressed. It will be simply ignored.
// No events from states S1 and S2 will be called.
.suppress< msg1 >( some_mbox )
// The same for msg2.
.suppress< msg2 >( some_mbox )
// A special handler for msg3. Overrides handler from state S1.
.event< msg3 >( some_mbox );
}
};

Definition at line 1166 of file state.hpp.

◆ suppress() [4/4]

template<typename Msg >
const state_t & so_5::state_t::suppress ( mbox_t from) const

Suppress processing of event in this state.

Since
v.5.5.15
Note
Suppresses message/signal which is going from message box from.
This method allows to disable passing of event to event handlers from parent states. For example:
class demo : public so_5::agent_t
{
const state_t S1{ this, "1" };
const state_t S2{ initial_substate_of{ S1 }, "2" };
const state_t S3{ initial_substate_of{ S2 }, "3" };
public :
virtual void so_define_agent() override
{
S1
// Default event handler which will be inherited by states S2 and S3.
.event< msg1 >( some_mbox, ...)
.event< msg2 >( some_mbox, ...)
.event< msg3 >( some_mbox, ...);
S2
// A special handler for msg1.
// For msg2 and msg3 event handlers from state S1 will be used.
.event< msg1 >( some_mbox, ...);
S3
// Message msg1 will be suppressed. It will be simply ignored.
// No events from states S1 and S2 will be called.
.suppress< msg1 >( some_mbox )
// The same for msg2.
.suppress< msg2 >( some_mbox )
// A special handler for msg3. Overrides handler from state S1.
.event< msg3 >( some_mbox );
}
};

Definition at line 3860 of file agent.hpp.

◆ time_limit()

state_t & so_5::state_t::time_limit ( duration_t timeout,
const state_t & state_to_switch )

Set up a time limit for the state.

Since
v.5.5.15
Note
Agent will automatically switched to state_to_switch after timeout spent in the current state.
Usage example:
class demo : public so_5::agent_t
{
state_t dialog{ this, "dialog" };
state_t show_err{ this, "err" };
...
public :
virtual void so_define_agent() override
{
dialog
.on_enter( [this] { m_display.clear(); } )
.event( [this]( const user_input & msg ) {
try_handle_input( msg );
if( some_error() ) {
m_error = error_description();
this >>= show_err;
}
} )
...; // Other handlers.
show_err
.on_enter( [this] { m_display.show( m_error ); } )
.time_limit( std::chrono::seconds{2}, dialog );
}
...
private :
display m_display;
std::string m_error;
...
};
Note
If S.time_limit() is called when S is active state then time_limit for that state will be reset and time for the state S will be counted from zero.
Parameters
timeoutMax duration of time for staying in this state.
state_to_switchA new state to be switched to.

Definition at line 480 of file agent.cpp.

◆ transfer_to_state() [1/4]

template<typename Msg >
state_t & so_5::state_t::transfer_to_state ( const state_t & target_state)
inline

An instruction for switching agent to the specified state and transfering event proceessing to new state.

Since
v.5.5.15
Note
Transfers processing of message/signal which is going from agent's direct mbox.
Usage example:
class device : public so_5::agent_t {
state_t off{ this, "off" };
state_t on{ this, "on" };
public :
virtual void so_define_agent() override {
.transfer_to_state< key_on >( on )
.transfer_to_state< key_info >( on );
...
}
...
};
const state_t & transfer_to_state(mbox_t from, const state_t &target_state) const
An instruction for switching agent to the specified state and transfering event proceessing to new st...
Definition agent.hpp:3813
Note
For more details see subscription_bind_t::transfer_to_state().
Since v.5.5.22.1 actual execution of transfer_to_state operation can raise so_5::exception_t with so_5::rc_transfer_to_state_loop error code if a loop in transfer_to_state is detected.

Definition at line 830 of file state.hpp.

◆ transfer_to_state() [2/4]

template<typename Msg >
const state_t & so_5::state_t::transfer_to_state ( const state_t & target_state) const

An instruction for switching agent to the specified state and transfering event proceessing to new state.

Since
v.5.5.15
Note
Transfers processing of message/signal which is going from agent's direct mbox.
Usage example:
class device : public so_5::agent_t {
const state_t off{ this, "off" };
const state_t on{ this, "on" };
public :
virtual void so_define_agent() override {
.transfer_to_state< key_on >( on )
.transfer_to_state< key_info >( on );
...
}
...
};
Note
For more details see subscription_bind_t::transfer_to_state().
Since v.5.5.22.1 actual execution of transfer_to_state operation can raise so_5::exception_t with so_5::rc_transfer_to_state_loop error code if a loop in transfer_to_state is detected.

Definition at line 3824 of file agent.hpp.

◆ transfer_to_state() [3/4]

template<typename Msg >
state_t & so_5::state_t::transfer_to_state ( mbox_t from,
const state_t & target_state )
inline

An instruction for switching agent to the specified state and transfering event proceessing to new state.

Since
v.5.5.15
Note
Transfers processing of message/signal which is going from message box from.
Usage example:
class device : public so_5::agent_t {
state_t off{ this, "off" };
state_t on{ this, "on" };
public :
virtual void so_define_agent() override {
.transfer_to_state< key_on >( some_mbox, on )
.transfer_to_state< key_info >( some_mbox, on );
...
}
...
};
Note
For more details see subscription_bind_t::transfer_to_state().
Since v.5.5.22.1 actual execution of transfer_to_state operation can raise so_5::exception_t with so_5::rc_transfer_to_state_loop error code if a loop in transfer_to_state is detected.

Definition at line 789 of file state.hpp.

◆ transfer_to_state() [4/4]

template<typename Msg >
const state_t & so_5::state_t::transfer_to_state ( mbox_t from,
const state_t & target_state ) const

An instruction for switching agent to the specified state and transfering event proceessing to new state.

Since
v.5.5.15
Note
Transfers processing of message/signal which is going from message box from.
Usage example:
class device : public so_5::agent_t {
const state_t off{ this, "off" };
const state_t on{ this, "on" };
public :
virtual void so_define_agent() override {
.transfer_to_state< key_on >( some_mbox, on )
.transfer_to_state< key_info >( some_mbox, on );
...
}
...
};
Note
For more details see subscription_bind_t::transfer_to_state().
Since v.5.5.22.1 actual execution of transfer_to_state operation can raise so_5::exception_t with so_5::rc_transfer_to_state_loop error code if a loop in transfer_to_state is detected.

Definition at line 3813 of file agent.hpp.

◆ update_history_in_parent_states()

void so_5::state_t::update_history_in_parent_states ( ) const
private

A helper method which is used during state change for update state with history.

Since
v.5.5.15

Definition at line 549 of file agent.cpp.

Friends And Related Symbol Documentation

◆ agent_t

friend class agent_t
friend

Definition at line 151 of file state.hpp.

Member Data Documentation

◆ m_initial_substate

const state_t* so_5::state_t::m_initial_substate
private

The initial substate.

Since
v.5.5.15
Note
Value nullptr means that state has no initial substate. If m_substate_count == 0 it is normal. It means that state is not a composite state. But if m_substate_count != 0 the value nullptr means that state description is incorrect.

Definition at line 1656 of file state.hpp.

◆ m_last_active_substate

const state_t* so_5::state_t::m_last_active_substate
private

Last active substate.

Since
v.5.5.15
Note
This attribute is used only if m_state_history != history_t::none. It holds a pointer to last active substate of this composite state.

Definition at line 1676 of file state.hpp.

◆ m_nested_level

std::size_t so_5::state_t::m_nested_level
private

Nesting level for state.

Since
v.5.5.15
Note
Value 0 means that state is a top-level state.

Definition at line 1686 of file state.hpp.

◆ m_on_enter

on_enter_handler_t so_5::state_t::m_on_enter
private

Handler for the enter to the state.

Since
v.5.5.15

Definition at line 1705 of file state.hpp.

◆ m_on_exit

on_exit_handler_t so_5::state_t::m_on_exit
private

Handler for the exit from the state.

Since
v.5.5.15

Definition at line 1713 of file state.hpp.

◆ m_parent_state

state_t* so_5::state_t::m_parent_state
private

Parent state.

Since
v.5.5.15
Note
Value nullptr means that state is a top-level state and has no parent state.
This pointer is not const because some modification of parent state must be performed via that pointer.

Definition at line 1643 of file state.hpp.

◆ m_state_history

history_t so_5::state_t::m_state_history
private

Type of state history.

Since
v.5.5.15

Definition at line 1664 of file state.hpp.

◆ m_state_name

std::string so_5::state_t::m_state_name
private

State name.

Note
Since v.5.5.15 has empty value for anonymous state.

Definition at line 1629 of file state.hpp.

◆ m_substate_count

size_t so_5::state_t::m_substate_count
private

Number of substates.

Since
v.5.5.15
Note
Value 0 means that state is not composite state and has no any substates.

Definition at line 1697 of file state.hpp.

◆ m_target_agent

agent_t* const so_5::state_t::m_target_agent
private

Owner of this state.

Definition at line 1623 of file state.hpp.

◆ m_time_limit

std::unique_ptr< time_limit_t > so_5::state_t::m_time_limit
private

A definition of time limit for the state.

Since
v.5.5.15
Note
Value nullptr means that time limit is not set.

Definition at line 1723 of file state.hpp.

◆ max_deep

const std::size_t so_5::state_t::max_deep = 16
staticconstexpr

Max deep of nested states.

Since
v.5.5.15

Definition at line 163 of file state.hpp.


The documentation for this class was generated from the following files: