2727#include " comms/util/Tuple.h"
2828#include " comms/util/alloc.h"
2929#include " details/MsgFactoryOptionsParser.h"
30- #include " details/MsgFactorySelector .h"
30+ #include " details/MsgFactoryBase .h"
3131
3232namespace comms
3333{
@@ -39,8 +39,7 @@ namespace comms
3939// / embedded environment.@n
4040// / The types of all messages provided in @b TAllMessages are analysed at
4141// / compile time and best "id to message object" mapping strategy is chosen,
42- // / whether it is direct access array (with O(1) time complexity) or
43- // / sorted array with binary search (with O(log(n)) time complexity).
42+ // / unless the "dispatch" type forcing options are used (see description below).
4443// / @tparam TMsgBase Common base class for all the messages, smart pointer to
4544// / this type is returned when allocation of specify message is requested.
4645// / @tparam TAllMessages All custom message types, that this factory is capable
@@ -72,60 +71,88 @@ namespace comms
7271// / the base class of @ref comms::GenericMessage type (first template
7372// / parameter) must be equal to @b TMsgBase (first template parameter)
7473// / of @b this class.
74+ // / @li @ref comms::option::ForceDispatchPolymorphic,
75+ // / @ref comms::option::ForceDispatchStaticBinSearch, or
76+ // / @ref comms::option::ForceDispatchLinearSwitch - Force a particular
77+ // / dispatch way when creating message object given the numeric ID
78+ // / (see @ref comms::MsgFactory::createMsg()). The dispatch methods
79+ // / are properly described in @ref page_dispatch tutorial page.
80+ // / If none of these options are provided, then the MsgFactory
81+ // / used a default way, which is equivalent to calling
82+ // / @ref comms::dispatchMsgType() (see also @ref page_dispatch_message_type_default).
83+ // / To inquire what actual dispatch type is used, please use one
84+ // / of the following constexpr member functions:
85+ // / @ref comms::MsgFactory::isDispatchPolymorphic(),
86+ // / @ref comms::MsgFactory::isDispatchStaticBinSearch(), and
87+ // / @ref comms::MsgFactory::isDispatchLinearSwitch()
7588// / @pre TMsgBase is a base class for all the messages in TAllMessages.
7689// / @pre Message type is TAllMessages must be sorted based on their IDs.
7790// / @pre If comms::option::InPlaceAllocation option is provided, only one custom
7891// / message can be allocated. The next one can be allocated only after previous
7992// / message has been destructed.
8093// / @headerfile comms/MsgFactory.h
8194template <typename TMsgBase, typename TAllMessages, typename ... TOptions>
82- class MsgFactory
95+ class MsgFactory : private details ::MsgFactoryBase<TMsgBase, TAllMessages, TOptions...>
8396{
97+ using Base = details::MsgFactoryBase<TMsgBase, TAllMessages, TOptions...>;
8498 static_assert (TMsgBase::InterfaceOptions::HasMsgIdType,
8599 " Usage of MsgFactory requires Message interface to provide ID type. "
86100 " Use comms::option::MsgIdType option in message interface type definition." );
87101
88- using Factory = typename
89- details::MsgFactorySelector<TMsgBase, TAllMessages, TOptions...>::Type;
90-
91102public:
92103 // / @brief Parsed options
93- using ParsedOptions = typename Factory ::ParsedOptions;
104+ using ParsedOptions = typename Base ::ParsedOptions;
94105
95106 // / @brief Type of the common base class of all the messages.
96- using Message = TMsgBase ;
107+ using Message = typename Base::Message ;
97108
98109 // / @brief Type of the message ID when passed as a parameter.
99- using MsgIdParamType = typename Message ::MsgIdParamType;
110+ using MsgIdParamType = typename Base ::MsgIdParamType;
100111
101112 // / @brief Type of the message ID.
102- using MsgIdType = typename Message ::MsgIdType;
113+ using MsgIdType = typename Base ::MsgIdType;
103114
104115 // / @brief Smart pointer to @ref Message which holds allocated message object.
105116 // / @details It is a variant of std::unique_ptr, based on whether
106117 // / comms::option::InPlaceAllocation option was used.
107- using MsgPtr = typename Factory ::MsgPtr;
118+ using MsgPtr = typename Base ::MsgPtr;
108119
109120 // / @brief All messages provided as template parameter to this class.
110- using AllMessages = TAllMessages;
121+ using AllMessages = typename Base::AllMessages;
122+
123+ #ifdef FOR_DOXYGEN_DOC_ONLY
124+ // @brief Reason for message creation failure
125+ enum class CreateFailureReason
126+ {
127+ None, // /< No reason
128+ InvalidId, // /< Invalid message id
129+ AllocFailure, // /< Allocation of the object has failied
130+ NumOfValues // /< Number of available values, must be last
131+ };
132+ #else // #ifdef FOR_DOXYGEN_DOC_ONLY
133+ using CreateFailureReason = typename Base::CreateFailureReason;
134+ #endif // #ifdef FOR_DOXYGEN_DOC_ONLY
111135
112136 // / @brief Create message object given the ID of the message.
137+ // / @details The id to mapping is performed using the chosen (or default)
138+ // / @b dispatch policy described in the class options.
113139 // / @param id ID of the message.
114- // / @param idx Relative index of the message with the same ID. In case
140+ // / @param idx Relative index (or offset) of the message with the same ID. In case
115141 // / protocol implementation contains multiple distinct message types
116142 // / that report same ID value, it must be possible to choose the
117143 // / relative index of such message from the first message type reporting
118144 // / the same ID. This parameter provides such an ability. However,
119145 // / most protocols will implement single message class for single ID.
120146 // / For such implementations, use default value of this parameter.
147+ // / @param[out] reason Failure reason in case creation has failed. May be nullptr.
121148 // / @return Smart pointer (variant of std::unique_ptr) to @ref Message type,
122149 // / which is a common base class of all the messages (provided as
123150 // / first template parameter to this class). If comms::option::InPlaceAllocation
124151 // / option was used and previously allocated message wasn't de-allocated
125152 // / yet, the empty (null) pointer will be returned.
126- MsgPtr createMsg (MsgIdParamType id, unsigned idx = 0 ) const
153+ MsgPtr createMsg (MsgIdParamType id, unsigned idx = 0 , CreateFailureReason* reason = nullptr ) const
127154 {
128- return factory_. createMsg (id, idx);
155+ return Base:: createMsg (id, idx, reason );
129156 }
130157
131158 // / @brief Allocate and initialise @ref comms::GenericMessage object.
@@ -136,26 +163,59 @@ class MsgFactory
136163 // / constructor of the @ref comms::GenericMessage class
137164 MsgPtr createGenericMsg (MsgIdParamType id) const
138165 {
139- return factory_. createGenericMsg (id);
166+ return Base:: createGenericMsg (id);
140167 }
141168
169+ // / @brief Inquiry whether allocation is possible
170+ bool canAllocate () const
171+ {
172+ return Base::canAllocate ();
173+ }
142174 // / @brief Get number of message types from @ref AllMessages, that have the specified ID.
143175 // / @param id ID of the message.
144176 // / @return Number of message classes that report same ID.
145177 std::size_t msgCount (MsgIdParamType id) const
146178 {
147- return factory_. msgCount (id);
179+ return Base:: msgCount (id);
148180 }
149181
150- // / @brief Compile time knowldege inquiry whether all the message classes in the
182+ // / @brief Compile time inquiry whether all the message classes in the
151183 // / @b TAllMessages bundle have unique IDs.
152184 static constexpr bool hasUniqueIds ()
153185 {
154- return Factory::hasUniqueIds ();
186+ return Base::hasUniqueIds ();
187+ }
188+
189+ // / @brief Compile time inquiry whether polymorphic dispatch tables are
190+ // / generated internally to map message ID to actual type.
191+ // / @see @ref page_dispatch
192+ // / @see @ref comms::MsgFactory::isDispatchStaticBinSearch()
193+ // / @see @ref comms::MsgFactory::isDispatchLinearSwitch()
194+ static constexpr bool isDispatchPolymorphic ()
195+ {
196+ return Base::isDispatchPolymorphic ();
197+ }
198+
199+ // / @brief Compile time inquiry whether static binary search dispatch is
200+ // / generated internally to map message ID to actual type.
201+ // / @see @ref page_dispatch
202+ // / @see @ref comms::MsgFactory::isDispatchPolymorphic()
203+ // / @see @ref comms::MsgFactory::isDispatchLinearSwitch()
204+ static constexpr bool isDispatchStaticBinSearch ()
205+ {
206+ return Base::isDispatchStaticBinSearch ();
207+ }
208+
209+ // / @brief Compile time inquiry whether linear switch dispatch is
210+ // / generated internally to map message ID to actual type.
211+ // / @see @ref page_dispatch
212+ // / @see @ref comms::MsgFactory::isDispatchStaticBinSearch()
213+ // / @see @ref comms::MsgFactory::isDispatchLinearSwitch()
214+ static constexpr bool isDispatchLinearSwitch ()
215+ {
216+ return Base::isDispatchLinearSwitch ();
155217 }
156218
157- private:
158- Factory factory_;
159219};
160220
161221
0 commit comments