Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
message_router.h
00001 /****************************************************************************** 00002 The MIT License(MIT) 00003 00004 Embedded Template Library. 00005 https://github.com/ETLCPP/etl 00006 https://www.etlcpp.com 00007 00008 Copyright(c) 2017 jwellbelove 00009 00010 Permission is hereby granted, free of charge, to any person obtaining a copy 00011 of this software and associated documentation files(the "Software"), to deal 00012 in the Software without restriction, including without limitation the rights 00013 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00014 copies of the Software, and to permit persons to whom the Software is 00015 furnished to do so, subject to the following conditions : 00016 00017 The above copyright notice and this permission notice shall be included in all 00018 copies or substantial portions of the Software. 00019 00020 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00021 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00022 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00023 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00024 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00025 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00026 SOFTWARE. 00027 ******************************************************************************/ 00028 00029 #if 0 00030 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. 00031 #endif 00032 00033 //*************************************************************************** 00034 // This file has been auto generated. Do not edit this file. 00035 //*************************************************************************** 00036 00037 //*************************************************************************** 00038 // To generate to header file, run this at the command line. 00039 // Note: You will need Python and COG installed. 00040 // 00041 // python -m cogapp -d -e -omessage_router.h -DHandlers=<n> message_router_generator.h 00042 // Where <n> is the number of messages to support. 00043 // 00044 // e.g. 00045 // To generate handlers for up to 16 messages... 00046 // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h 00047 // 00048 // See generate.bat 00049 //*************************************************************************** 00050 00051 #ifndef __ETL_MESSAGE_ROUTER__ 00052 #define __ETL_MESSAGE_ROUTER__ 00053 00054 #include <stdint.h> 00055 00056 #include "platform.h " 00057 #include "message.h" 00058 #include "message_types.h" 00059 #include "alignment.h " 00060 #include "error_handler.h " 00061 #include "exception.h " 00062 #include "largest.h " 00063 #include "nullptr.h " 00064 00065 #undef ETL_FILE 00066 #define ETL_FILE "35" 00067 00068 namespace etl 00069 { 00070 //*************************************************************************** 00071 /// Base exception class for message router 00072 //*************************************************************************** 00073 class message_router_exception : public etl::exception 00074 { 00075 public: 00076 00077 message_router_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00078 : etl::exception(reason_, file_name_, line_number_) 00079 { 00080 } 00081 }; 00082 00083 //*************************************************************************** 00084 /// Router id is out of the legal range. 00085 //*************************************************************************** 00086 class message_router_illegal_id : public etl::message_router_exception 00087 { 00088 public: 00089 00090 message_router_illegal_id(string_type file_name_, numeric_type line_number_) 00091 : message_router_exception(ETL_ERROR_TEXT("message router:illegal id", ETL_FILE"A"), file_name_, line_number_) 00092 { 00093 } 00094 }; 00095 00096 //*************************************************************************** 00097 class imessage_router 00098 { 00099 public: 00100 00101 virtual ~imessage_router() {} 00102 virtual void receive(const etl::imessage& message) = 0; 00103 virtual void receive(imessage_router& source, const etl::imessage& message) = 0; 00104 virtual bool accepts(etl::message_id_t id) const = 0; 00105 00106 //******************************************** 00107 bool accepts(const etl::imessage& msg) const 00108 { 00109 return accepts(msg.message_id); 00110 } 00111 00112 //******************************************** 00113 etl::message_router_id_t get_message_router_id() const 00114 { 00115 return message_router_id; 00116 } 00117 00118 //******************************************** 00119 bool is_null_router() const 00120 { 00121 return (message_router_id == NULL_MESSAGE_ROUTER); 00122 } 00123 00124 //******************************************** 00125 bool is_bus() const 00126 { 00127 return (message_router_id == MESSAGE_BUS); 00128 } 00129 00130 //******************************************** 00131 void set_successor(imessage_router& successor_) 00132 { 00133 successor = &successor_; 00134 } 00135 00136 //******************************************** 00137 imessage_router& get_successor() const 00138 { 00139 return *successor; 00140 } 00141 00142 //******************************************** 00143 bool has_successor() const 00144 { 00145 return (successor != nullptr); 00146 } 00147 00148 enum 00149 { 00150 NULL_MESSAGE_ROUTER = 255, 00151 MESSAGE_BUS = 254, 00152 ALL_MESSAGE_ROUTERS = 253, 00153 MAX_MESSAGE_ROUTER = 249 00154 }; 00155 00156 protected: 00157 00158 imessage_router(etl::message_router_id_t id_) 00159 : successor(nullptr), 00160 message_router_id(id_) 00161 { 00162 } 00163 00164 imessage_router(etl::message_router_id_t id_, 00165 imessage_router& successor_) 00166 : successor(&successor_), 00167 message_router_id(id_) 00168 { 00169 } 00170 00171 private: 00172 00173 // Disabled. 00174 imessage_router(const imessage_router&); 00175 imessage_router& operator =(const imessage_router&); 00176 00177 etl::imessage_router* successor; 00178 00179 etl::message_router_id_t message_router_id; 00180 }; 00181 00182 //*************************************************************************** 00183 /// This router can be used either as a sink for messages 00184 /// or as a producer-only of messages such an interrupt routine. 00185 //*************************************************************************** 00186 class null_message_router : public imessage_router 00187 { 00188 public: 00189 00190 null_message_router() 00191 : imessage_router(imessage_router::NULL_MESSAGE_ROUTER) 00192 { 00193 } 00194 00195 //******************************************** 00196 void receive(const etl::imessage&) 00197 { 00198 } 00199 00200 //******************************************** 00201 void receive(etl::imessage_router&, const etl::imessage&) 00202 { 00203 } 00204 00205 //******************************************** 00206 bool accepts(etl::message_id_t) const 00207 { 00208 return false; 00209 } 00210 00211 //******************************************** 00212 static null_message_router& instance() 00213 { 00214 static null_message_router nmr; 00215 return nmr; 00216 } 00217 }; 00218 00219 //*************************************************************************** 00220 /// Send a message to a router. 00221 /// Sets the 'sender' to etl::null_message_router type. 00222 //*************************************************************************** 00223 inline static void send_message(etl::imessage_router& destination, 00224 const etl::imessage& message) 00225 { 00226 destination.receive(message); 00227 } 00228 00229 //*************************************************************************** 00230 /// Send a message to a router. 00231 //*************************************************************************** 00232 inline static void send_message(etl::imessage_router& source, 00233 etl::imessage_router& destination, 00234 const etl::imessage& message) 00235 { 00236 destination.receive(source, message); 00237 } 00238 00239 //*************************************************************************** 00240 // The definition for all 16 message types. 00241 //*************************************************************************** 00242 template <typename TDerived, 00243 typename T1, typename T2 = void, typename T3 = void, typename T4 = void, 00244 typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void, 00245 typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void, 00246 typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void> 00247 class message_router : public imessage_router 00248 { 00249 public: 00250 00251 //********************************************** 00252 class message_packet 00253 { 00254 public: 00255 00256 //******************************************** 00257 explicit message_packet(const etl::imessage& msg) 00258 { 00259 const size_t id = msg.message_id; 00260 00261 void* p = data; 00262 00263 switch (id) 00264 { 00265 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 00266 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 00267 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 00268 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 00269 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 00270 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 00271 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 00272 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 00273 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 00274 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 00275 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 00276 case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break; 00277 case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break; 00278 case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break; 00279 case T15::ID: ::new (p) T15(static_cast<const T15&>(msg)); break; 00280 case T16::ID: ::new (p) T16(static_cast<const T16&>(msg)); break; 00281 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 00282 } 00283 } 00284 00285 //******************************************** 00286 template <typename T> 00287 explicit message_packet(const T& msg) 00288 { 00289 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type for this message packet"); 00290 00291 void* p = data; 00292 ::new (p) T(static_cast<const T&>(msg)); 00293 } 00294 00295 //******************************************** 00296 ~message_packet() 00297 { 00298 static_cast<etl::imessage*>(data)->~imessage(); 00299 } 00300 00301 //******************************************** 00302 etl::imessage& get() 00303 { 00304 return *static_cast<etl::imessage*>(data); 00305 } 00306 00307 //******************************************** 00308 const etl::imessage& get() const 00309 { 00310 return *static_cast<const etl::imessage*>(data); 00311 } 00312 00313 enum 00314 { 00315 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size, 00316 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment 00317 }; 00318 00319 private: 00320 00321 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 00322 }; 00323 00324 //********************************************** 00325 message_router(etl::message_router_id_t id_) 00326 : imessage_router(id_) 00327 { 00328 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00329 } 00330 00331 //********************************************** 00332 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 00333 : imessage_router(id_, successor_) 00334 { 00335 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00336 } 00337 00338 //********************************************** 00339 void receive(const etl::imessage& msg) 00340 { 00341 receive(etl::null_message_router::instance(), msg); 00342 } 00343 00344 //********************************************** 00345 void receive(etl::imessage_router& source, const etl::imessage& msg) 00346 { 00347 const etl::message_id_t id = msg.message_id; 00348 00349 switch (id) 00350 { 00351 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 00352 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 00353 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 00354 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 00355 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 00356 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 00357 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 00358 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 00359 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 00360 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 00361 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 00362 case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break; 00363 case T13::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T13&>(msg)); break; 00364 case T14::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T14&>(msg)); break; 00365 case T15::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T15&>(msg)); break; 00366 case T16::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T16&>(msg)); break; 00367 default: 00368 { 00369 if (has_successor()) 00370 { 00371 get_successor().receive(source, msg); 00372 } 00373 else 00374 { 00375 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 00376 } 00377 break; 00378 } 00379 } 00380 } 00381 00382 using imessage_router::accepts; 00383 00384 //********************************************** 00385 bool accepts(etl::message_id_t id) const 00386 { 00387 switch (id) 00388 { 00389 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 00390 case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: case T15::ID: case T16::ID: 00391 return true; break; 00392 default: 00393 return false; break; 00394 } 00395 } 00396 }; 00397 00398 //*************************************************************************** 00399 // Specialisation for 15 message types. 00400 //*************************************************************************** 00401 template <typename TDerived, 00402 typename T1, typename T2, typename T3, typename T4, 00403 typename T5, typename T6, typename T7, typename T8, 00404 typename T9, typename T10, typename T11, typename T12, 00405 typename T13, typename T14, typename T15> 00406 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, void> 00407 : public imessage_router 00408 { 00409 public: 00410 00411 //********************************************** 00412 class message_packet 00413 { 00414 public: 00415 00416 //******************************************** 00417 explicit message_packet(const etl::imessage& msg) 00418 { 00419 const size_t id = msg.message_id; 00420 00421 void* p = data; 00422 00423 switch (id) 00424 { 00425 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 00426 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 00427 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 00428 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 00429 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 00430 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 00431 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 00432 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 00433 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 00434 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 00435 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 00436 case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break; 00437 case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break; 00438 case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break; 00439 case T15::ID: ::new (p) T15(static_cast<const T15&>(msg)); break; 00440 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 00441 } 00442 } 00443 00444 //******************************************** 00445 template <typename T> 00446 explicit message_packet(const T& msg) 00447 { 00448 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::value), "Unsupported type for this message packet"); 00449 00450 void* p = data; 00451 ::new (p) T(static_cast<const T&>(msg)); 00452 } 00453 00454 //******************************************** 00455 ~message_packet() 00456 { 00457 static_cast<etl::imessage*>(data)->~imessage(); 00458 } 00459 00460 //******************************************** 00461 etl::imessage& get() 00462 { 00463 return *static_cast<etl::imessage*>(data); 00464 } 00465 00466 //******************************************** 00467 const etl::imessage& get() const 00468 { 00469 return *static_cast<const etl::imessage*>(data); 00470 } 00471 00472 enum 00473 { 00474 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::size, 00475 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::alignment 00476 }; 00477 00478 private: 00479 00480 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 00481 }; 00482 00483 //********************************************** 00484 message_router(etl::message_router_id_t id_) 00485 : imessage_router(id_) 00486 { 00487 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00488 } 00489 00490 //********************************************** 00491 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 00492 : imessage_router(id_, successor_) 00493 { 00494 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00495 } 00496 00497 //********************************************** 00498 void receive(const etl::imessage& msg) 00499 { 00500 receive(etl::null_message_router::instance(), msg); 00501 } 00502 00503 //********************************************** 00504 void receive(etl::imessage_router& source, const etl::imessage& msg) 00505 { 00506 const size_t id = msg.message_id; 00507 00508 switch (id) 00509 { 00510 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 00511 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 00512 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 00513 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 00514 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 00515 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 00516 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 00517 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 00518 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 00519 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 00520 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 00521 case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break; 00522 case T13::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T13&>(msg)); break; 00523 case T14::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T14&>(msg)); break; 00524 case T15::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T15&>(msg)); break; 00525 default: 00526 { 00527 if (has_successor()) 00528 { 00529 get_successor().receive(source, msg); 00530 } 00531 else 00532 { 00533 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 00534 } 00535 break; 00536 } 00537 } 00538 } 00539 00540 using imessage_router::accepts; 00541 00542 //********************************************** 00543 bool accepts(etl::message_id_t id) const 00544 { 00545 switch (id) 00546 { 00547 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 00548 case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: case T15::ID: 00549 return true; break; 00550 default: 00551 return false; break; 00552 } 00553 } 00554 }; 00555 00556 //*************************************************************************** 00557 // Specialisation for 14 message types. 00558 //*************************************************************************** 00559 template <typename TDerived, 00560 typename T1, typename T2, typename T3, typename T4, 00561 typename T5, typename T6, typename T7, typename T8, 00562 typename T9, typename T10, typename T11, typename T12, 00563 typename T13, typename T14> 00564 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, void, void> 00565 : public imessage_router 00566 { 00567 public: 00568 00569 //********************************************** 00570 class message_packet 00571 { 00572 public: 00573 00574 //******************************************** 00575 explicit message_packet(const etl::imessage& msg) 00576 { 00577 const size_t id = msg.message_id; 00578 00579 void* p = data; 00580 00581 switch (id) 00582 { 00583 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 00584 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 00585 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 00586 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 00587 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 00588 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 00589 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 00590 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 00591 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 00592 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 00593 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 00594 case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break; 00595 case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break; 00596 case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break; 00597 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 00598 } 00599 } 00600 00601 //******************************************** 00602 template <typename T> 00603 explicit message_packet(const T& msg) 00604 { 00605 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::value), "Unsupported type for this message packet"); 00606 00607 void* p = data; 00608 ::new (p) T(static_cast<const T&>(msg)); 00609 } 00610 00611 //******************************************** 00612 ~message_packet() 00613 { 00614 static_cast<etl::imessage*>(data)->~imessage(); 00615 } 00616 00617 //******************************************** 00618 etl::imessage& get() 00619 { 00620 return *static_cast<etl::imessage*>(data); 00621 } 00622 00623 //******************************************** 00624 const etl::imessage& get() const 00625 { 00626 return *static_cast<const etl::imessage*>(data); 00627 } 00628 00629 enum 00630 { 00631 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::size, 00632 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::alignment 00633 }; 00634 00635 private: 00636 00637 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 00638 }; 00639 00640 //********************************************** 00641 message_router(etl::message_router_id_t id_) 00642 : imessage_router(id_) 00643 { 00644 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00645 } 00646 00647 //********************************************** 00648 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 00649 : imessage_router(id_, successor_) 00650 { 00651 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00652 } 00653 00654 //********************************************** 00655 void receive(const etl::imessage& msg) 00656 { 00657 receive(etl::null_message_router::instance(), msg); 00658 } 00659 00660 //********************************************** 00661 void receive(etl::imessage_router& source, const etl::imessage& msg) 00662 { 00663 const size_t id = msg.message_id; 00664 00665 switch (id) 00666 { 00667 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 00668 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 00669 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 00670 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 00671 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 00672 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 00673 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 00674 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 00675 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 00676 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 00677 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 00678 case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break; 00679 case T13::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T13&>(msg)); break; 00680 case T14::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T14&>(msg)); break; 00681 default: 00682 { 00683 if (has_successor()) 00684 { 00685 get_successor().receive(source, msg); 00686 } 00687 else 00688 { 00689 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 00690 } 00691 break; 00692 } 00693 } 00694 } 00695 00696 using imessage_router::accepts; 00697 00698 //********************************************** 00699 bool accepts(etl::message_id_t id) const 00700 { 00701 switch (id) 00702 { 00703 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 00704 case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: 00705 return true; break; 00706 default: 00707 return false; break; 00708 } 00709 } 00710 }; 00711 00712 //*************************************************************************** 00713 // Specialisation for 13 message types. 00714 //*************************************************************************** 00715 template <typename TDerived, 00716 typename T1, typename T2, typename T3, typename T4, 00717 typename T5, typename T6, typename T7, typename T8, 00718 typename T9, typename T10, typename T11, typename T12, 00719 typename T13> 00720 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, void, void, void> 00721 : public imessage_router 00722 { 00723 public: 00724 00725 //********************************************** 00726 class message_packet 00727 { 00728 public: 00729 00730 //******************************************** 00731 explicit message_packet(const etl::imessage& msg) 00732 { 00733 const size_t id = msg.message_id; 00734 00735 void* p = data; 00736 00737 switch (id) 00738 { 00739 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 00740 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 00741 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 00742 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 00743 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 00744 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 00745 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 00746 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 00747 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 00748 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 00749 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 00750 case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break; 00751 case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break; 00752 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 00753 } 00754 } 00755 00756 //******************************************** 00757 template <typename T> 00758 explicit message_packet(const T& msg) 00759 { 00760 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::value), "Unsupported type for this message packet"); 00761 00762 void* p = data; 00763 ::new (p) T(static_cast<const T&>(msg)); 00764 } 00765 00766 //******************************************** 00767 ~message_packet() 00768 { 00769 static_cast<etl::imessage*>(data)->~imessage(); 00770 } 00771 00772 //******************************************** 00773 etl::imessage& get() 00774 { 00775 return *static_cast<etl::imessage*>(data); 00776 } 00777 00778 //******************************************** 00779 const etl::imessage& get() const 00780 { 00781 return *static_cast<const etl::imessage*>(data); 00782 } 00783 00784 enum 00785 { 00786 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::size, 00787 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::alignment 00788 }; 00789 00790 private: 00791 00792 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 00793 }; 00794 00795 //********************************************** 00796 message_router(etl::message_router_id_t id_) 00797 : imessage_router(id_) 00798 { 00799 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00800 } 00801 00802 //********************************************** 00803 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 00804 : imessage_router(id_, successor_) 00805 { 00806 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00807 } 00808 00809 //********************************************** 00810 void receive(const etl::imessage& msg) 00811 { 00812 receive(etl::null_message_router::instance(), msg); 00813 } 00814 00815 //********************************************** 00816 void receive(etl::imessage_router& source, const etl::imessage& msg) 00817 { 00818 const size_t id = msg.message_id; 00819 00820 switch (id) 00821 { 00822 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 00823 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 00824 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 00825 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 00826 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 00827 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 00828 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 00829 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 00830 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 00831 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 00832 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 00833 case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break; 00834 case T13::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T13&>(msg)); break; 00835 default: 00836 { 00837 if (has_successor()) 00838 { 00839 get_successor().receive(source, msg); 00840 } 00841 else 00842 { 00843 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 00844 } 00845 break; 00846 } 00847 } 00848 } 00849 00850 using imessage_router::accepts; 00851 00852 //********************************************** 00853 bool accepts(etl::message_id_t id) const 00854 { 00855 switch (id) 00856 { 00857 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 00858 case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: 00859 return true; break; 00860 default: 00861 return false; break; 00862 } 00863 } 00864 }; 00865 00866 //*************************************************************************** 00867 // Specialisation for 12 message types. 00868 //*************************************************************************** 00869 template <typename TDerived, 00870 typename T1, typename T2, typename T3, typename T4, 00871 typename T5, typename T6, typename T7, typename T8, 00872 typename T9, typename T10, typename T11, typename T12> 00873 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, void, void, void, void> 00874 : public imessage_router 00875 { 00876 public: 00877 00878 //********************************************** 00879 class message_packet 00880 { 00881 public: 00882 00883 //******************************************** 00884 explicit message_packet(const etl::imessage& msg) 00885 { 00886 const size_t id = msg.message_id; 00887 00888 void* p = data; 00889 00890 switch (id) 00891 { 00892 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 00893 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 00894 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 00895 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 00896 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 00897 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 00898 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 00899 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 00900 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 00901 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 00902 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 00903 case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break; 00904 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 00905 } 00906 } 00907 00908 //******************************************** 00909 template <typename T> 00910 explicit message_packet(const T& msg) 00911 { 00912 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::value), "Unsupported type for this message packet"); 00913 00914 void* p = data; 00915 ::new (p) T(static_cast<const T&>(msg)); 00916 } 00917 00918 //******************************************** 00919 ~message_packet() 00920 { 00921 static_cast<etl::imessage*>(data)->~imessage(); 00922 } 00923 00924 //******************************************** 00925 etl::imessage& get() 00926 { 00927 return *static_cast<etl::imessage*>(data); 00928 } 00929 00930 //******************************************** 00931 const etl::imessage& get() const 00932 { 00933 return *static_cast<const etl::imessage*>(data); 00934 } 00935 00936 enum 00937 { 00938 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::size, 00939 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::alignment 00940 }; 00941 00942 private: 00943 00944 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 00945 }; 00946 00947 //********************************************** 00948 message_router(etl::message_router_id_t id_) 00949 : imessage_router(id_) 00950 { 00951 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00952 } 00953 00954 //********************************************** 00955 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 00956 : imessage_router(id_, successor_) 00957 { 00958 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 00959 } 00960 00961 //********************************************** 00962 void receive(const etl::imessage& msg) 00963 { 00964 receive(etl::null_message_router::instance(), msg); 00965 } 00966 00967 //********************************************** 00968 void receive(etl::imessage_router& source, const etl::imessage& msg) 00969 { 00970 const size_t id = msg.message_id; 00971 00972 switch (id) 00973 { 00974 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 00975 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 00976 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 00977 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 00978 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 00979 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 00980 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 00981 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 00982 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 00983 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 00984 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 00985 case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break; 00986 default: 00987 { 00988 if (has_successor()) 00989 { 00990 get_successor().receive(source, msg); 00991 } 00992 else 00993 { 00994 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 00995 } 00996 break; 00997 } 00998 } 00999 } 01000 01001 using imessage_router::accepts; 01002 01003 //********************************************** 01004 bool accepts(etl::message_id_t id) const 01005 { 01006 switch (id) 01007 { 01008 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 01009 case T9::ID: case T10::ID: case T11::ID: case T12::ID: 01010 return true; break; 01011 default: 01012 return false; break; 01013 } 01014 } 01015 }; 01016 01017 //*************************************************************************** 01018 // Specialisation for 11 message types. 01019 //*************************************************************************** 01020 template <typename TDerived, 01021 typename T1, typename T2, typename T3, typename T4, 01022 typename T5, typename T6, typename T7, typename T8, 01023 typename T9, typename T10, typename T11> 01024 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, void, void, void, void, void> 01025 : public imessage_router 01026 { 01027 public: 01028 01029 //********************************************** 01030 class message_packet 01031 { 01032 public: 01033 01034 //******************************************** 01035 explicit message_packet(const etl::imessage& msg) 01036 { 01037 const size_t id = msg.message_id; 01038 01039 void* p = data; 01040 01041 switch (id) 01042 { 01043 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01044 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01045 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01046 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01047 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01048 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01049 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 01050 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 01051 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 01052 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 01053 case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break; 01054 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01055 } 01056 } 01057 01058 //******************************************** 01059 template <typename T> 01060 explicit message_packet(const T& msg) 01061 { 01062 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::value), "Unsupported type for this message packet"); 01063 01064 void* p = data; 01065 ::new (p) T(static_cast<const T&>(msg)); 01066 } 01067 01068 //******************************************** 01069 ~message_packet() 01070 { 01071 static_cast<etl::imessage*>(data)->~imessage(); 01072 } 01073 01074 //******************************************** 01075 etl::imessage& get() 01076 { 01077 return *static_cast<etl::imessage*>(data); 01078 } 01079 01080 //******************************************** 01081 const etl::imessage& get() const 01082 { 01083 return *static_cast<const etl::imessage*>(data); 01084 } 01085 01086 enum 01087 { 01088 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::size, 01089 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::alignment 01090 }; 01091 01092 private: 01093 01094 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01095 }; 01096 01097 //********************************************** 01098 message_router(etl::message_router_id_t id_) 01099 : imessage_router(id_) 01100 { 01101 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01102 } 01103 01104 //********************************************** 01105 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01106 : imessage_router(id_, successor_) 01107 { 01108 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01109 } 01110 01111 //********************************************** 01112 void receive(const etl::imessage& msg) 01113 { 01114 receive(etl::null_message_router::instance(), msg); 01115 } 01116 01117 //********************************************** 01118 void receive(etl::imessage_router& source, const etl::imessage& msg) 01119 { 01120 const size_t id = msg.message_id; 01121 01122 switch (id) 01123 { 01124 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01125 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01126 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01127 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01128 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01129 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01130 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 01131 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 01132 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 01133 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 01134 case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break; 01135 default: 01136 { 01137 if (has_successor()) 01138 { 01139 get_successor().receive(source, msg); 01140 } 01141 else 01142 { 01143 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01144 } 01145 break; 01146 } 01147 } 01148 } 01149 01150 using imessage_router::accepts; 01151 01152 //********************************************** 01153 bool accepts(etl::message_id_t id) const 01154 { 01155 switch (id) 01156 { 01157 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 01158 case T9::ID: case T10::ID: case T11::ID: 01159 return true; break; 01160 default: 01161 return false; break; 01162 } 01163 } 01164 }; 01165 01166 //*************************************************************************** 01167 // Specialisation for 10 message types. 01168 //*************************************************************************** 01169 template <typename TDerived, 01170 typename T1, typename T2, typename T3, typename T4, 01171 typename T5, typename T6, typename T7, typename T8, 01172 typename T9, typename T10> 01173 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, void, void, void, void, void, void> 01174 : public imessage_router 01175 { 01176 public: 01177 01178 //********************************************** 01179 class message_packet 01180 { 01181 public: 01182 01183 //******************************************** 01184 explicit message_packet(const etl::imessage& msg) 01185 { 01186 const size_t id = msg.message_id; 01187 01188 void* p = data; 01189 01190 switch (id) 01191 { 01192 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01193 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01194 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01195 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01196 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01197 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01198 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 01199 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 01200 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 01201 case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break; 01202 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01203 } 01204 } 01205 01206 //******************************************** 01207 template <typename T> 01208 explicit message_packet(const T& msg) 01209 { 01210 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value), "Unsupported type for this message packet"); 01211 01212 void* p = data; 01213 ::new (p) T(static_cast<const T&>(msg)); 01214 } 01215 01216 //******************************************** 01217 ~message_packet() 01218 { 01219 static_cast<etl::imessage*>(data)->~imessage(); 01220 } 01221 01222 //******************************************** 01223 etl::imessage& get() 01224 { 01225 return *static_cast<etl::imessage*>(data); 01226 } 01227 01228 //******************************************** 01229 const etl::imessage& get() const 01230 { 01231 return *static_cast<const etl::imessage*>(data); 01232 } 01233 01234 enum 01235 { 01236 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::size, 01237 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::alignment 01238 }; 01239 01240 private: 01241 01242 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01243 }; 01244 01245 //********************************************** 01246 message_router(etl::message_router_id_t id_) 01247 : imessage_router(id_) 01248 { 01249 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01250 } 01251 01252 //********************************************** 01253 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01254 : imessage_router(id_, successor_) 01255 { 01256 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01257 } 01258 01259 //********************************************** 01260 void receive(const etl::imessage& msg) 01261 { 01262 receive(etl::null_message_router::instance(), msg); 01263 } 01264 01265 //********************************************** 01266 void receive(etl::imessage_router& source, const etl::imessage& msg) 01267 { 01268 const size_t id = msg.message_id; 01269 01270 switch (id) 01271 { 01272 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01273 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01274 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01275 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01276 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01277 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01278 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 01279 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 01280 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 01281 case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break; 01282 default: 01283 { 01284 if (has_successor()) 01285 { 01286 get_successor().receive(source, msg); 01287 } 01288 else 01289 { 01290 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01291 } 01292 break; 01293 } 01294 } 01295 } 01296 01297 using imessage_router::accepts; 01298 01299 //********************************************** 01300 bool accepts(etl::message_id_t id) const 01301 { 01302 switch (id) 01303 { 01304 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 01305 case T9::ID: case T10::ID: 01306 return true; break; 01307 default: 01308 return false; break; 01309 } 01310 } 01311 }; 01312 01313 //*************************************************************************** 01314 // Specialisation for 9 message types. 01315 //*************************************************************************** 01316 template <typename TDerived, 01317 typename T1, typename T2, typename T3, typename T4, 01318 typename T5, typename T6, typename T7, typename T8, 01319 typename T9> 01320 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, T9, void, void, void, void, void, void, void> 01321 : public imessage_router 01322 { 01323 public: 01324 01325 //********************************************** 01326 class message_packet 01327 { 01328 public: 01329 01330 //******************************************** 01331 explicit message_packet(const etl::imessage& msg) 01332 { 01333 const size_t id = msg.message_id; 01334 01335 void* p = data; 01336 01337 switch (id) 01338 { 01339 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01340 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01341 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01342 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01343 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01344 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01345 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 01346 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 01347 case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break; 01348 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01349 } 01350 } 01351 01352 //******************************************** 01353 template <typename T> 01354 explicit message_packet(const T& msg) 01355 { 01356 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9>::value), "Unsupported type for this message packet"); 01357 01358 void* p = data; 01359 ::new (p) T(static_cast<const T&>(msg)); 01360 } 01361 01362 //******************************************** 01363 ~message_packet() 01364 { 01365 static_cast<etl::imessage*>(data)->~imessage(); 01366 } 01367 01368 //******************************************** 01369 etl::imessage& get() 01370 { 01371 return *static_cast<etl::imessage*>(data); 01372 } 01373 01374 //******************************************** 01375 const etl::imessage& get() const 01376 { 01377 return *static_cast<const etl::imessage*>(data); 01378 } 01379 01380 enum 01381 { 01382 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9>::size, 01383 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9>::alignment 01384 }; 01385 01386 private: 01387 01388 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01389 }; 01390 01391 //********************************************** 01392 message_router(etl::message_router_id_t id_) 01393 : imessage_router(id_) 01394 { 01395 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01396 } 01397 01398 //********************************************** 01399 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01400 : imessage_router(id_, successor_) 01401 { 01402 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01403 } 01404 01405 //********************************************** 01406 void receive(const etl::imessage& msg) 01407 { 01408 receive(etl::null_message_router::instance(), msg); 01409 } 01410 01411 //********************************************** 01412 void receive(etl::imessage_router& source, const etl::imessage& msg) 01413 { 01414 const size_t id = msg.message_id; 01415 01416 switch (id) 01417 { 01418 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01419 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01420 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01421 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01422 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01423 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01424 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 01425 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 01426 case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break; 01427 default: 01428 { 01429 if (has_successor()) 01430 { 01431 get_successor().receive(source, msg); 01432 } 01433 else 01434 { 01435 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01436 } 01437 break; 01438 } 01439 } 01440 } 01441 01442 using imessage_router::accepts; 01443 01444 //********************************************** 01445 bool accepts(etl::message_id_t id) const 01446 { 01447 switch (id) 01448 { 01449 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 01450 case T9::ID: 01451 return true; break; 01452 default: 01453 return false; break; 01454 } 01455 } 01456 }; 01457 01458 //*************************************************************************** 01459 // Specialisation for 8 message types. 01460 //*************************************************************************** 01461 template <typename TDerived, 01462 typename T1, typename T2, typename T3, typename T4, 01463 typename T5, typename T6, typename T7, typename T8> 01464 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, T8, void, void, void, void, void, void, void, void> 01465 : public imessage_router 01466 { 01467 public: 01468 01469 //********************************************** 01470 class message_packet 01471 { 01472 public: 01473 01474 //******************************************** 01475 explicit message_packet(const etl::imessage& msg) 01476 { 01477 const size_t id = msg.message_id; 01478 01479 void* p = data; 01480 01481 switch (id) 01482 { 01483 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01484 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01485 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01486 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01487 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01488 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01489 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 01490 case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break; 01491 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01492 } 01493 } 01494 01495 //******************************************** 01496 template <typename T> 01497 explicit message_packet(const T& msg) 01498 { 01499 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8>::value), "Unsupported type for this message packet"); 01500 01501 void* p = data; 01502 ::new (p) T(static_cast<const T&>(msg)); 01503 } 01504 01505 //******************************************** 01506 ~message_packet() 01507 { 01508 static_cast<etl::imessage*>(data)->~imessage(); 01509 } 01510 01511 //******************************************** 01512 etl::imessage& get() 01513 { 01514 return *static_cast<etl::imessage*>(data); 01515 } 01516 01517 //******************************************** 01518 const etl::imessage& get() const 01519 { 01520 return *static_cast<const etl::imessage*>(data); 01521 } 01522 01523 enum 01524 { 01525 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8>::size, 01526 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7, T8>::alignment 01527 }; 01528 01529 private: 01530 01531 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01532 }; 01533 01534 //********************************************** 01535 message_router(etl::message_router_id_t id_) 01536 : imessage_router(id_) 01537 { 01538 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01539 } 01540 01541 //********************************************** 01542 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01543 : imessage_router(id_, successor_) 01544 { 01545 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01546 } 01547 01548 //********************************************** 01549 void receive(const etl::imessage& msg) 01550 { 01551 receive(etl::null_message_router::instance(), msg); 01552 } 01553 01554 //********************************************** 01555 void receive(etl::imessage_router& source, const etl::imessage& msg) 01556 { 01557 const size_t id = msg.message_id; 01558 01559 switch (id) 01560 { 01561 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01562 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01563 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01564 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01565 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01566 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01567 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 01568 case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break; 01569 default: 01570 { 01571 if (has_successor()) 01572 { 01573 get_successor().receive(source, msg); 01574 } 01575 else 01576 { 01577 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01578 } 01579 break; 01580 } 01581 } 01582 } 01583 01584 using imessage_router::accepts; 01585 01586 //********************************************** 01587 bool accepts(etl::message_id_t id) const 01588 { 01589 switch (id) 01590 { 01591 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: 01592 01593 return true; break; 01594 default: 01595 return false; break; 01596 } 01597 } 01598 }; 01599 01600 //*************************************************************************** 01601 // Specialisation for 7 message types. 01602 //*************************************************************************** 01603 template <typename TDerived, 01604 typename T1, typename T2, typename T3, typename T4, 01605 typename T5, typename T6, typename T7> 01606 class message_router<TDerived, T1, T2, T3, T4, T5, T6, T7, void, void, void, void, void, void, void, void, void> 01607 : public imessage_router 01608 { 01609 public: 01610 01611 //********************************************** 01612 class message_packet 01613 { 01614 public: 01615 01616 //******************************************** 01617 explicit message_packet(const etl::imessage& msg) 01618 { 01619 const size_t id = msg.message_id; 01620 01621 void* p = data; 01622 01623 switch (id) 01624 { 01625 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01626 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01627 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01628 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01629 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01630 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01631 case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break; 01632 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01633 } 01634 } 01635 01636 //******************************************** 01637 template <typename T> 01638 explicit message_packet(const T& msg) 01639 { 01640 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7>::value), "Unsupported type for this message packet"); 01641 01642 void* p = data; 01643 ::new (p) T(static_cast<const T&>(msg)); 01644 } 01645 01646 //******************************************** 01647 ~message_packet() 01648 { 01649 static_cast<etl::imessage*>(data)->~imessage(); 01650 } 01651 01652 //******************************************** 01653 etl::imessage& get() 01654 { 01655 return *static_cast<etl::imessage*>(data); 01656 } 01657 01658 //******************************************** 01659 const etl::imessage& get() const 01660 { 01661 return *static_cast<const etl::imessage*>(data); 01662 } 01663 01664 enum 01665 { 01666 SIZE = etl::largest<T1, T2, T3, T4, T5, T6, T7>::size, 01667 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6, T7>::alignment 01668 }; 01669 01670 private: 01671 01672 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01673 }; 01674 01675 //********************************************** 01676 message_router(etl::message_router_id_t id_) 01677 : imessage_router(id_) 01678 { 01679 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01680 } 01681 01682 //********************************************** 01683 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01684 : imessage_router(id_, successor_) 01685 { 01686 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01687 } 01688 01689 //********************************************** 01690 void receive(const etl::imessage& msg) 01691 { 01692 receive(etl::null_message_router::instance(), msg); 01693 } 01694 01695 //********************************************** 01696 void receive(etl::imessage_router& source, const etl::imessage& msg) 01697 { 01698 const size_t id = msg.message_id; 01699 01700 switch (id) 01701 { 01702 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01703 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01704 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01705 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01706 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01707 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01708 case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break; 01709 default: 01710 { 01711 if (has_successor()) 01712 { 01713 get_successor().receive(source, msg); 01714 } 01715 else 01716 { 01717 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01718 } 01719 break; 01720 } 01721 } 01722 } 01723 01724 using imessage_router::accepts; 01725 01726 //********************************************** 01727 bool accepts(etl::message_id_t id) const 01728 { 01729 switch (id) 01730 { 01731 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: 01732 return true; break; 01733 default: 01734 return false; break; 01735 } 01736 } 01737 }; 01738 01739 //*************************************************************************** 01740 // Specialisation for 6 message types. 01741 //*************************************************************************** 01742 template <typename TDerived, 01743 typename T1, typename T2, typename T3, typename T4, 01744 typename T5, typename T6> 01745 class message_router<TDerived, T1, T2, T3, T4, T5, T6, void, void, void, void, void, void, void, void, void, void> 01746 : public imessage_router 01747 { 01748 public: 01749 01750 //********************************************** 01751 class message_packet 01752 { 01753 public: 01754 01755 //******************************************** 01756 explicit message_packet(const etl::imessage& msg) 01757 { 01758 const size_t id = msg.message_id; 01759 01760 void* p = data; 01761 01762 switch (id) 01763 { 01764 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01765 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01766 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01767 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01768 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01769 case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break; 01770 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01771 } 01772 } 01773 01774 //******************************************** 01775 template <typename T> 01776 explicit message_packet(const T& msg) 01777 { 01778 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6>::value), "Unsupported type for this message packet"); 01779 01780 void* p = data; 01781 ::new (p) T(static_cast<const T&>(msg)); 01782 } 01783 01784 //******************************************** 01785 ~message_packet() 01786 { 01787 static_cast<etl::imessage*>(data)->~imessage(); 01788 } 01789 01790 //******************************************** 01791 etl::imessage& get() 01792 { 01793 return *static_cast<etl::imessage*>(data); 01794 } 01795 01796 //******************************************** 01797 const etl::imessage& get() const 01798 { 01799 return *static_cast<const etl::imessage*>(data); 01800 } 01801 01802 enum 01803 { 01804 SIZE = etl::largest<T1, T2, T3, T4, T5, T6>::size, 01805 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5, T6>::alignment 01806 }; 01807 01808 private: 01809 01810 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01811 }; 01812 01813 //********************************************** 01814 message_router(etl::message_router_id_t id_) 01815 : imessage_router(id_) 01816 { 01817 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01818 } 01819 01820 //********************************************** 01821 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01822 : imessage_router(id_, successor_) 01823 { 01824 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01825 } 01826 01827 //********************************************** 01828 void receive(const etl::imessage& msg) 01829 { 01830 receive(etl::null_message_router::instance(), msg); 01831 } 01832 01833 //********************************************** 01834 void receive(etl::imessage_router& source, const etl::imessage& msg) 01835 { 01836 const size_t id = msg.message_id; 01837 01838 switch (id) 01839 { 01840 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01841 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01842 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01843 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01844 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01845 case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break; 01846 default: 01847 { 01848 if (has_successor()) 01849 { 01850 get_successor().receive(source, msg); 01851 } 01852 else 01853 { 01854 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01855 } 01856 break; 01857 } 01858 } 01859 } 01860 01861 using imessage_router::accepts; 01862 01863 //********************************************** 01864 bool accepts(etl::message_id_t id) const 01865 { 01866 switch (id) 01867 { 01868 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: 01869 return true; break; 01870 default: 01871 return false; break; 01872 } 01873 } 01874 }; 01875 01876 //*************************************************************************** 01877 // Specialisation for 5 message types. 01878 //*************************************************************************** 01879 template <typename TDerived, 01880 typename T1, typename T2, typename T3, typename T4, 01881 typename T5> 01882 class message_router<TDerived, T1, T2, T3, T4, T5, void, void, void, void, void, void, void, void, void, void, void> 01883 : public imessage_router 01884 { 01885 public: 01886 01887 //********************************************** 01888 class message_packet 01889 { 01890 public: 01891 01892 //******************************************** 01893 explicit message_packet(const etl::imessage& msg) 01894 { 01895 const size_t id = msg.message_id; 01896 01897 void* p = data; 01898 01899 switch (id) 01900 { 01901 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 01902 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 01903 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 01904 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 01905 case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break; 01906 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 01907 } 01908 } 01909 01910 //******************************************** 01911 template <typename T> 01912 explicit message_packet(const T& msg) 01913 { 01914 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5>::value), "Unsupported type for this message packet"); 01915 01916 void* p = data; 01917 ::new (p) T(static_cast<const T&>(msg)); 01918 } 01919 01920 //******************************************** 01921 ~message_packet() 01922 { 01923 static_cast<etl::imessage*>(data)->~imessage(); 01924 } 01925 01926 //******************************************** 01927 etl::imessage& get() 01928 { 01929 return *static_cast<etl::imessage*>(data); 01930 } 01931 01932 //******************************************** 01933 const etl::imessage& get() const 01934 { 01935 return *static_cast<const etl::imessage*>(data); 01936 } 01937 01938 enum 01939 { 01940 SIZE = etl::largest<T1, T2, T3, T4, T5>::size, 01941 ALIGNMENT = etl::largest<T1, T2, T3, T4, T5>::alignment 01942 }; 01943 01944 private: 01945 01946 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 01947 }; 01948 01949 //********************************************** 01950 message_router(etl::message_router_id_t id_) 01951 : imessage_router(id_) 01952 { 01953 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01954 } 01955 01956 //********************************************** 01957 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 01958 : imessage_router(id_, successor_) 01959 { 01960 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 01961 } 01962 01963 //********************************************** 01964 void receive(const etl::imessage& msg) 01965 { 01966 receive(etl::null_message_router::instance(), msg); 01967 } 01968 01969 //********************************************** 01970 void receive(etl::imessage_router& source, const etl::imessage& msg) 01971 { 01972 const size_t id = msg.message_id; 01973 01974 switch (id) 01975 { 01976 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 01977 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 01978 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 01979 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 01980 case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break; 01981 default: 01982 { 01983 if (has_successor()) 01984 { 01985 get_successor().receive(source, msg); 01986 } 01987 else 01988 { 01989 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 01990 } 01991 break; 01992 } 01993 } 01994 } 01995 01996 using imessage_router::accepts; 01997 01998 //********************************************** 01999 bool accepts(etl::message_id_t id) const 02000 { 02001 switch (id) 02002 { 02003 case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: 02004 return true; break; 02005 default: 02006 return false; break; 02007 } 02008 } 02009 }; 02010 02011 //*************************************************************************** 02012 // Specialisation for 4 message types. 02013 //*************************************************************************** 02014 template <typename TDerived, 02015 typename T1, typename T2, typename T3, typename T4> 02016 class message_router<TDerived, T1, T2, T3, T4, void, void, void, void, void, void, void, void, void, void, void, void> 02017 : public imessage_router 02018 { 02019 public: 02020 02021 //********************************************** 02022 class message_packet 02023 { 02024 public: 02025 02026 //******************************************** 02027 explicit message_packet(const etl::imessage& msg) 02028 { 02029 const size_t id = msg.message_id; 02030 02031 void* p = data; 02032 02033 switch (id) 02034 { 02035 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 02036 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 02037 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 02038 case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break; 02039 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 02040 } 02041 } 02042 02043 //******************************************** 02044 template <typename T> 02045 explicit message_packet(const T& msg) 02046 { 02047 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4>::value), "Unsupported type for this message packet"); 02048 02049 void* p = data; 02050 ::new (p) T(static_cast<const T&>(msg)); 02051 } 02052 02053 //******************************************** 02054 ~message_packet() 02055 { 02056 static_cast<etl::imessage*>(data)->~imessage(); 02057 } 02058 02059 //******************************************** 02060 etl::imessage& get() 02061 { 02062 return *static_cast<etl::imessage*>(data); 02063 } 02064 02065 //******************************************** 02066 const etl::imessage& get() const 02067 { 02068 return *static_cast<const etl::imessage*>(data); 02069 } 02070 02071 enum 02072 { 02073 SIZE = etl::largest<T1, T2, T3, T4>::size, 02074 ALIGNMENT = etl::largest<T1, T2, T3, T4>::alignment 02075 }; 02076 02077 private: 02078 02079 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 02080 }; 02081 02082 //********************************************** 02083 message_router(etl::message_router_id_t id_) 02084 : imessage_router(id_) 02085 { 02086 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02087 } 02088 02089 //********************************************** 02090 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 02091 : imessage_router(id_, successor_) 02092 { 02093 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02094 } 02095 02096 //********************************************** 02097 void receive(const etl::imessage& msg) 02098 { 02099 receive(etl::null_message_router::instance(), msg); 02100 } 02101 02102 //********************************************** 02103 void receive(etl::imessage_router& source, const etl::imessage& msg) 02104 { 02105 const size_t id = msg.message_id; 02106 02107 switch (id) 02108 { 02109 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 02110 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 02111 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 02112 case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break; 02113 default: 02114 { 02115 if (has_successor()) 02116 { 02117 get_successor().receive(source, msg); 02118 } 02119 else 02120 { 02121 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 02122 } 02123 break; 02124 } 02125 } 02126 } 02127 02128 using imessage_router::accepts; 02129 02130 //********************************************** 02131 bool accepts(etl::message_id_t id) const 02132 { 02133 switch (id) 02134 { 02135 case T1::ID: case T2::ID: case T3::ID: case T4::ID: 02136 return true; break; 02137 default: 02138 return false; break; 02139 } 02140 } 02141 }; 02142 02143 //*************************************************************************** 02144 // Specialisation for 3 message types. 02145 //*************************************************************************** 02146 template <typename TDerived, 02147 typename T1, typename T2, typename T3> 02148 class message_router<TDerived, T1, T2, T3, void, void, void, void, void, void, void, void, void, void, void, void, void> 02149 : public imessage_router 02150 { 02151 public: 02152 02153 //********************************************** 02154 class message_packet 02155 { 02156 public: 02157 02158 //******************************************** 02159 explicit message_packet(const etl::imessage& msg) 02160 { 02161 const size_t id = msg.message_id; 02162 02163 void* p = data; 02164 02165 switch (id) 02166 { 02167 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 02168 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 02169 case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break; 02170 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 02171 } 02172 } 02173 02174 //******************************************** 02175 template <typename T> 02176 explicit message_packet(const T& msg) 02177 { 02178 STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3>::value), "Unsupported type for this message packet"); 02179 02180 void* p = data; 02181 ::new (p) T(static_cast<const T&>(msg)); 02182 } 02183 02184 //******************************************** 02185 ~message_packet() 02186 { 02187 static_cast<etl::imessage*>(data)->~imessage(); 02188 } 02189 02190 //******************************************** 02191 etl::imessage& get() 02192 { 02193 return *static_cast<etl::imessage*>(data); 02194 } 02195 02196 //******************************************** 02197 const etl::imessage& get() const 02198 { 02199 return *static_cast<const etl::imessage*>(data); 02200 } 02201 02202 enum 02203 { 02204 SIZE = etl::largest<T1, T2, T3>::size, 02205 ALIGNMENT = etl::largest<T1, T2, T3>::alignment 02206 }; 02207 02208 private: 02209 02210 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 02211 }; 02212 02213 //********************************************** 02214 message_router(etl::message_router_id_t id_) 02215 : imessage_router(id_) 02216 { 02217 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02218 } 02219 02220 //********************************************** 02221 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 02222 : imessage_router(id_, successor_) 02223 { 02224 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02225 } 02226 02227 //********************************************** 02228 void receive(const etl::imessage& msg) 02229 { 02230 receive(etl::null_message_router::instance(), msg); 02231 } 02232 02233 //********************************************** 02234 void receive(etl::imessage_router& source, const etl::imessage& msg) 02235 { 02236 const size_t id = msg.message_id; 02237 02238 switch (id) 02239 { 02240 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 02241 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 02242 case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break; 02243 default: 02244 { 02245 if (has_successor()) 02246 { 02247 get_successor().receive(source, msg); 02248 } 02249 else 02250 { 02251 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 02252 } 02253 break; 02254 } 02255 } 02256 } 02257 02258 using imessage_router::accepts; 02259 02260 //********************************************** 02261 bool accepts(etl::message_id_t id) const 02262 { 02263 switch (id) 02264 { 02265 case T1::ID: case T2::ID: case T3::ID: 02266 return true; break; 02267 default: 02268 return false; break; 02269 } 02270 } 02271 }; 02272 02273 //*************************************************************************** 02274 // Specialisation for 2 message types. 02275 //*************************************************************************** 02276 template <typename TDerived, 02277 typename T1, typename T2> 02278 class message_router<TDerived, T1, T2, void, void, void, void, void, void, void, void, void, void, void, void, void, void> 02279 : public imessage_router 02280 { 02281 public: 02282 02283 //********************************************** 02284 class message_packet 02285 { 02286 public: 02287 02288 //******************************************** 02289 explicit message_packet(const etl::imessage& msg) 02290 { 02291 const size_t id = msg.message_id; 02292 02293 void* p = data; 02294 02295 switch (id) 02296 { 02297 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 02298 case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break; 02299 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 02300 } 02301 } 02302 02303 //******************************************** 02304 template <typename T> 02305 explicit message_packet(const T& msg) 02306 { 02307 STATIC_ASSERT((etl::is_one_of<T, T1, T2>::value), "Unsupported type for this message packet"); 02308 02309 void* p = data; 02310 ::new (p) T(static_cast<const T&>(msg)); 02311 } 02312 02313 //******************************************** 02314 ~message_packet() 02315 { 02316 static_cast<etl::imessage*>(data)->~imessage(); 02317 } 02318 02319 //******************************************** 02320 etl::imessage& get() 02321 { 02322 return *static_cast<etl::imessage*>(data); 02323 } 02324 02325 //******************************************** 02326 const etl::imessage& get() const 02327 { 02328 return *static_cast<const etl::imessage*>(data); 02329 } 02330 02331 enum 02332 { 02333 SIZE = etl::largest<T1, T2>::size, 02334 ALIGNMENT = etl::largest<T1, T2>::alignment 02335 }; 02336 02337 private: 02338 02339 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 02340 }; 02341 02342 //********************************************** 02343 message_router(etl::message_router_id_t id_) 02344 : imessage_router(id_) 02345 { 02346 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02347 } 02348 02349 //********************************************** 02350 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 02351 : imessage_router(id_, successor_) 02352 { 02353 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02354 } 02355 02356 //********************************************** 02357 void receive(const etl::imessage& msg) 02358 { 02359 receive(etl::null_message_router::instance(), msg); 02360 } 02361 02362 //********************************************** 02363 void receive(etl::imessage_router& source, const etl::imessage& msg) 02364 { 02365 const size_t id = msg.message_id; 02366 02367 switch (id) 02368 { 02369 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 02370 case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break; 02371 default: 02372 { 02373 if (has_successor()) 02374 { 02375 get_successor().receive(source, msg); 02376 } 02377 else 02378 { 02379 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 02380 } 02381 break; 02382 } 02383 } 02384 } 02385 02386 using imessage_router::accepts; 02387 02388 //********************************************** 02389 bool accepts(etl::message_id_t id) const 02390 { 02391 switch (id) 02392 { 02393 case T1::ID: case T2::ID: 02394 return true; break; 02395 default: 02396 return false; break; 02397 } 02398 } 02399 }; 02400 02401 //*************************************************************************** 02402 // Specialisation for 1 message type. 02403 //*************************************************************************** 02404 template <typename TDerived, 02405 typename T1> 02406 class message_router<TDerived, T1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void> 02407 : public imessage_router 02408 { 02409 public: 02410 02411 //********************************************** 02412 class message_packet 02413 { 02414 public: 02415 02416 //******************************************** 02417 explicit message_packet(const etl::imessage& msg) 02418 { 02419 const size_t id = msg.message_id; 02420 02421 void* p = data; 02422 02423 switch (id) 02424 { 02425 case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break; 02426 default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; 02427 } 02428 } 02429 02430 //******************************************** 02431 template <typename T> 02432 explicit message_packet(const T& msg) 02433 { 02434 STATIC_ASSERT((etl::is_one_of<T, T1>::value), "Unsupported type for this message packet"); 02435 02436 void* p = data; 02437 ::new (p) T(static_cast<const T&>(msg)); 02438 } 02439 02440 //******************************************** 02441 ~message_packet() 02442 { 02443 static_cast<etl::imessage*>(data)->~imessage(); 02444 } 02445 02446 //******************************************** 02447 etl::imessage& get() 02448 { 02449 return *static_cast<etl::imessage*>(data); 02450 } 02451 02452 //******************************************** 02453 const etl::imessage& get() const 02454 { 02455 return *static_cast<const etl::imessage*>(data); 02456 } 02457 02458 enum 02459 { 02460 SIZE = etl::largest<T1>::size, 02461 ALIGNMENT = etl::largest<T1>::alignment 02462 }; 02463 02464 private: 02465 02466 typename etl::aligned_storage<SIZE, ALIGNMENT>::type data; 02467 }; 02468 02469 //********************************************** 02470 message_router(etl::message_router_id_t id_) 02471 : imessage_router(id_) 02472 { 02473 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02474 } 02475 02476 //********************************************** 02477 message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) 02478 : imessage_router(id_, successor_) 02479 { 02480 ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); 02481 } 02482 02483 //********************************************** 02484 void receive(const etl::imessage& msg) 02485 { 02486 receive(etl::null_message_router::instance(), msg); 02487 } 02488 02489 //********************************************** 02490 void receive(etl::imessage_router& source, const etl::imessage& msg) 02491 { 02492 const size_t id = msg.message_id; 02493 02494 switch (id) 02495 { 02496 case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break; 02497 default: 02498 { 02499 if (has_successor()) 02500 { 02501 get_successor().receive(source, msg); 02502 } 02503 else 02504 { 02505 static_cast<TDerived*>(this)->on_receive_unknown(source, msg); 02506 } 02507 break; 02508 } 02509 } 02510 } 02511 02512 using imessage_router::accepts; 02513 02514 //********************************************** 02515 bool accepts(etl::message_id_t id) const 02516 { 02517 switch (id) 02518 { 02519 case T1::ID: 02520 return true; break; 02521 default: 02522 return false; break; 02523 } 02524 } 02525 }; 02526 } 02527 02528 #undef ETL_FILE 02529 02530 #endif 02531
Generated on Tue Jul 12 2022 14:05:42 by
