2
3
6
7
8
9
10
11
13#include <so_5/impl/subscription_storage_iface.hpp>
17#include <unordered_map>
20#include <so_5/details/rollback_on_exception.hpp>
29
30
31
32
33
58 std::type_index msg_type )
67 std::type_index msg_type,
68 const state_t & state )
110
111
112
113
114
129 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
131 return h2 ^ (std::hash<
const state_t * >()(
133 0x9e3779b9 + (h2 << 6) + (h2 >> 2));
141
142
143
144
145
163 typename S::iterator it )
165 if( it != s.begin() )
167 typename S::iterator prev = it;
169 if( it->first.is_same_mbox_msg_pair( prev->first ) )
173 typename S::iterator next = it;
175 if( next != s.end() )
176 return it->first.is_same_mbox_msg_pair( next->first );
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
215 const mbox_t & mbox_ref,
216 const std::type_index & type_index,
218 const state_t & target_state,
219 const event_handler_method_t & method,
225 const mbox_t & mbox_ref,
226 const std::type_index & type_index,
227 const state_t & target_state )
noexcept override;
231 const mbox_t & mbox_ref,
232 const std::type_index & type_index )
noexcept override;
240 const std::type_index & msg_type,
241 const state_t & current_state )
const noexcept override;
244 debug_dump( std::ostream & to )
const override;
273
274
275
276
280 using hash_table_t = std::unordered_map<
304 const std::type_index & type_index,
306 const state_t & target_state,
307 const event_handler_method_t & method,
315 auto insertion_result =
m_map.emplace(
319 if( !insertion_result.second )
322 "agent is already subscribed to message, " +
330 [&] {
m_map.erase( insertion_result.first ); }
);
333 m_map, insertion_result.first
);
334 if( !mbox_msg_known )
340 type_index
, message_sink
);
344 m_map.erase( insertion_result.first );
351 const mbox_t & mbox_ref,
352 const std::type_index & type_index,
353 const state_t & target_state )
noexcept
357 auto it =
m_map.find( key );
359 if(
m_map.end() != it )
370 if( !mbox_msg_known )
379 const mbox_t & mbox_ref,
380 const std::type_index & type_index )
noexcept
384 auto it =
m_map.lower_bound( key );
385 auto need_erase = [&] {
386 return it !=
m_map.end() &&
389 const bool found = need_erase();
402 while( need_erase() );
417 const std::type_index & msg_type,
418 const state_t & current_state )
const noexcept
420 key_t k
( mbox_id
, msg_type
, current_state
);
423 return &(it->second);
431 for(
const auto & v :
m_map )
442 const map_t::value_type * previous =
nullptr;
443 for(
auto & i :
m_map )
477 subscr_info_vector_t events;
484 back_inserter(events),
485 [
this](
const hash_table_t::value_type & i )
487 auto map_item =
m_map.find( *(i.first) );
512 hash_table_t fresh_table;
514 for_each( begin(info), end(info),
519 auto ins_result = fresh_map.emplace(
526 fresh_table.emplace( &(ins_result.first->first), i
.m_handler );
529 swap(
m_map, fresh_map );
547 return impl::subscription_storage_unique_ptr_t(
virtual void unsubscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber) noexcept=0
Remove all message handlers.
virtual void subscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber)=0
Add the message handler.
virtual mbox_id_t id() const =0
Unique ID of this mbox.
Interface for message sink.
A storage for agent's subscriptions information.
void drop_subscription_for_all_states(const mbox_t &mbox_ref, const std::type_index &type_index) noexcept override
hash_table_t m_hash_table
Hash table of event handlers.
void setup_content(subscription_storage_common::subscr_info_vector_t &&info) override
Setup content from information from another storage object.
void drop_content() noexcept override
Drop all content.
virtual void create_event_subscription(const mbox_t &mbox_ref, const std::type_index &type_index, abstract_message_sink_t &message_sink, const state_t &target_state, const event_handler_method_t &method, thread_safety_t thread_safety, event_handler_kind_t handler_kind) override
const event_handler_data_t * find_handler(mbox_id_t mbox_id, const std::type_index &msg_type, const state_t ¤t_state) const noexcept override
void destroy_all_subscriptions() noexcept
void debug_dump(std::ostream &to) const override
virtual void drop_subscription(const mbox_t &mbox_ref, const std::type_index &type_index, const state_t &target_state) noexcept override
std::size_t query_subscriptions_count() const override
Count of subscriptions in the storage.
map_t m_map
Map of subscriptions.
subscription_storage_common::subscr_info_vector_t query_content() const override
void drop_all_subscriptions() noexcept override
Drop all subscriptions.
An interface of subscription storage.
T * operator->() const noexcept
std::string query_name() const
Get textual name of the state.
#define SO_5_THROW_EXCEPTION(error_code, desc)
Some reusable and low-level classes/functions which can be used in public header files.
auto do_with_rollback_on_exception(Main_Action main_action, Rollback_Action rollback_action) -> decltype(main_action())
Helper function for do some action with rollback in the case of an exception.
bool is_known_mbox_msg_pair(S &s, typename S::iterator it)
A hash_table-based storage for agent's subscriptions information.
Common stuff for various subscription storage implementations.
std::string make_subscription_description(const mbox_t &mbox_ref, std::type_index msg_type, const state_t &state)
A helper function for creating subscription description.
Details of SObjectizer run-time implementations.
Private part of message limit implementation.
thread_safety_t
Thread safety indicator.
SO_5_FUNC subscription_storage_factory_t hash_table_based_subscription_storage_factory()
Factory for default subscription storage based on std::unordered_map.
mbox_id_t null_mbox_id()
Default value for null mbox_id.
const int rc_evt_handler_already_provided
A handler for that event/mbox/state is already registered.
event_handler_kind_t
Kind of an event handler.
Information about event_handler and its properties.
thread_safety_t m_thread_safety
Is event handler thread safe or not.
event_handler_method_t m_method
Method for handling event.
event_handler_data_t(event_handler_method_t method, thread_safety_t thread_safety, event_handler_kind_t kind)
event_handler_kind_t m_kind
Kind of this event handler.
A special class for checking equality via pointer to key.
bool operator()(const key_t *a, const key_t *b) const
A special class for calculating hash value via pointer to key.
std::size_t operator()(const key_t *ptr) const noexcept
key_t(mbox_id_t mbox_id, std::type_index msg_type, const state_t &state)
Initializing constructor.
std::type_index m_msg_type
Message type.
bool is_same_mbox_msg_pair(const key_t &o) const noexcept
mbox_id_t m_mbox_id
Unique ID of mbox.
const state_t * m_state
State of agent.
bool operator==(const key_t &o) const noexcept
key_t()
Default constructor.
bool operator<(const key_t &o) const noexcept
key_t(mbox_id_t mbox_id, std::type_index msg_type)
std::reference_wrapper< abstract_message_sink_t > m_message_sink
An information about one subscription.
event_handler_data_t m_handler
std::reference_wrapper< abstract_message_sink_t > m_message_sink
Message sink used for subscription.
subscr_info_t(mbox_t mbox, std::type_index msg_type, abstract_message_sink_t &message_sink, const state_t &state, const event_handler_method_t &method, thread_safety_t thread_safety, event_handler_kind_t handler_kind)
mbox_t m_mbox
Reference to mbox.
std::type_index m_msg_type