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_generator.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 /*[[[cog 00030 import cog 00031 cog.outl("#if 0") 00032 ]]]*/ 00033 /*[[[end]]]*/ 00034 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. 00035 /*[[[cog 00036 import cog 00037 cog.outl("#endif") 00038 ]]]*/ 00039 /*[[[end]]]*/ 00040 00041 /*[[[cog 00042 import cog 00043 cog.outl("//***************************************************************************") 00044 cog.outl("// This file has been auto generated. Do not edit this file.") 00045 cog.outl("//***************************************************************************") 00046 ]]]*/ 00047 /*[[[end]]]*/ 00048 00049 //*************************************************************************** 00050 // To generate to header file, run this at the command line. 00051 // Note: You will need Python and COG installed. 00052 // 00053 // python -m cogapp -d -e -omessage_router.h -DHandlers=<n> message_router_generator.h 00054 // Where <n> is the number of messages to support. 00055 // 00056 // e.g. 00057 // To generate handlers for up to 16 messages... 00058 // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h 00059 // 00060 // See generate.bat 00061 //*************************************************************************** 00062 00063 #ifndef __ETL_MESSAGE_ROUTER__ 00064 #define __ETL_MESSAGE_ROUTER__ 00065 00066 #include <stdint.h> 00067 00068 #include "platform.h " 00069 #include "message.h" 00070 #include "message_types.h" 00071 #include "alignment.h " 00072 #include "error_handler.h " 00073 #include "exception.h " 00074 #include "largest.h " 00075 #include "nullptr.h " 00076 00077 #undef ETL_FILE 00078 #define ETL_FILE "35" 00079 00080 namespace etl 00081 { 00082 //*************************************************************************** 00083 /// Base exception class for message router 00084 //*************************************************************************** 00085 class message_router_exception : public etl::exception 00086 { 00087 public: 00088 00089 message_router_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00090 : etl::exception(reason_, file_name_, line_number_) 00091 { 00092 } 00093 }; 00094 00095 //*************************************************************************** 00096 /// Router id is out of the legal range. 00097 //*************************************************************************** 00098 class message_router_illegal_id : public etl::message_router_exception 00099 { 00100 public: 00101 00102 message_router_illegal_id(string_type file_name_, numeric_type line_number_) 00103 : message_router_exception(ETL_ERROR_TEXT("message router:illegal id", ETL_FILE"A"), file_name_, line_number_) 00104 { 00105 } 00106 }; 00107 00108 //*************************************************************************** 00109 class imessage_router 00110 { 00111 public: 00112 00113 virtual ~imessage_router() {} 00114 virtual void receive(const etl::imessage& message) = 0; 00115 virtual void receive(imessage_router& source, const etl::imessage& message) = 0; 00116 virtual bool accepts(etl::message_id_t id) const = 0; 00117 00118 //******************************************** 00119 bool accepts(const etl::imessage& msg) const 00120 { 00121 return accepts(msg.message_id); 00122 } 00123 00124 //******************************************** 00125 etl::message_router_id_t get_message_router_id() const 00126 { 00127 return message_router_id; 00128 } 00129 00130 //******************************************** 00131 bool is_null_router() const 00132 { 00133 return (message_router_id == NULL_MESSAGE_ROUTER); 00134 } 00135 00136 //******************************************** 00137 bool is_bus() const 00138 { 00139 return (message_router_id == MESSAGE_BUS); 00140 } 00141 00142 //******************************************** 00143 void set_successor(imessage_router& successor_) 00144 { 00145 successor = &successor_; 00146 } 00147 00148 //******************************************** 00149 imessage_router& get_successor() const 00150 { 00151 return *successor; 00152 } 00153 00154 //******************************************** 00155 bool has_successor() const 00156 { 00157 return (successor != std::nullptr); 00158 } 00159 00160 enum 00161 { 00162 NULL_MESSAGE_ROUTER = 255, 00163 MESSAGE_BUS = 254, 00164 ALL_MESSAGE_ROUTERS = 253, 00165 MAX_MESSAGE_ROUTER = 249 00166 }; 00167 00168 protected: 00169 00170 imessage_router(etl::message_router_id_t id_) 00171 : successor(std::nullptr), 00172 message_router_id(id_) 00173 { 00174 } 00175 00176 imessage_router(etl::message_router_id_t id_, 00177 imessage_router& successor_) 00178 : successor(&successor_), 00179 message_router_id(id_) 00180 { 00181 } 00182 00183 private: 00184 00185 // Disabled. 00186 imessage_router(const imessage_router&); 00187 imessage_router& operator =(const imessage_router&); 00188 00189 etl::imessage_router* successor; 00190 00191 etl::message_router_id_t message_router_id; 00192 }; 00193 00194 //*************************************************************************** 00195 /// This router can be used either as a sink for messages 00196 /// or as a producer-only of messages such an interrupt routine. 00197 //*************************************************************************** 00198 class null_message_router : public imessage_router 00199 { 00200 public: 00201 00202 null_message_router() 00203 : imessage_router(imessage_router::NULL_MESSAGE_ROUTER) 00204 { 00205 } 00206 00207 //******************************************** 00208 void receive(const etl::imessage&) 00209 { 00210 } 00211 00212 //******************************************** 00213 void receive(etl::imessage_router&, const etl::imessage&) 00214 { 00215 } 00216 00217 //******************************************** 00218 bool accepts(etl::message_id_t) const 00219 { 00220 return false; 00221 } 00222 00223 //******************************************** 00224 static null_message_router& instance() 00225 { 00226 static null_message_router nmr; 00227 return nmr; 00228 } 00229 }; 00230 00231 //*************************************************************************** 00232 /// Send a message to a router. 00233 /// Sets the 'sender' to etl::null_message_router type. 00234 //*************************************************************************** 00235 inline static void send_message(etl::imessage_router& destination, 00236 const etl::imessage& message) 00237 { 00238 destination.receive(message); 00239 } 00240 00241 //*************************************************************************** 00242 /// Send a message to a router. 00243 //*************************************************************************** 00244 inline static void send_message(etl::imessage_router& source, 00245 etl::imessage_router& destination, 00246 const etl::imessage& message) 00247 { 00248 destination.receive(source, message); 00249 } 00250 00251 /*[[[cog 00252 import cog 00253 ################################################ 00254 # The first definition for all of the messages. 00255 ################################################ 00256 cog.outl("//***************************************************************************") 00257 cog.outl("// The definition for all %s message types." % Handlers) 00258 cog.outl("//***************************************************************************") 00259 cog.outl("template <typename TDerived,") 00260 cog.out(" ") 00261 cog.out("typename T1, ") 00262 for n in range(2, int(Handlers)): 00263 cog.out("typename T%s = void, " % n) 00264 if n % 4 == 0: 00265 cog.outl("") 00266 cog.out(" ") 00267 cog.outl("typename T%s = void>" % int(Handlers)) 00268 cog.out("class message_router") 00269 cog.outl(" : public imessage_router") 00270 cog.outl("{") 00271 cog.outl("public:") 00272 cog.outl("") 00273 cog.outl(" //**********************************************") 00274 cog.outl(" class message_packet") 00275 cog.outl(" {") 00276 cog.outl(" public:") 00277 cog.outl("") 00278 cog.outl(" //********************************************") 00279 cog.outl(" explicit message_packet(const etl::imessage& msg)") 00280 cog.outl(" {") 00281 cog.outl(" const size_t id = msg.message_id;") 00282 cog.outl("") 00283 cog.outl(" void* p = data;") 00284 cog.outl("") 00285 cog.outl(" switch (id)") 00286 cog.outl(" {") 00287 for n in range(1, int(Handlers) + 1): 00288 cog.outl(" case T%s::ID: ::new (p) T%s(static_cast<const T%s&>(msg)); break;" % (n, n, n)) 00289 cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") 00290 cog.outl(" }") 00291 cog.outl(" }") 00292 cog.outl("") 00293 cog.outl(" //********************************************") 00294 cog.outl(" template <typename T>") 00295 cog.outl(" explicit message_packet(const T& msg)") 00296 cog.outl(" {") 00297 cog.out(" STATIC_ASSERT((etl::is_one_of<T, ") 00298 for n in range(1, int(Handlers)): 00299 cog.out("T%s, " % n) 00300 if n % 16 == 0: 00301 cog.outl("") 00302 cog.out(" ") 00303 cog.outl("""T%s>::value), "Unsupported type for this message packet");""" % int(Handlers)) 00304 cog.outl("") 00305 cog.outl(" void* p = data;") 00306 cog.outl(" ::new (p) T(static_cast<const T&>(msg));") 00307 cog.outl(" }") 00308 cog.outl("") 00309 cog.outl(" //********************************************") 00310 cog.outl(" ~message_packet()") 00311 cog.outl(" {") 00312 cog.outl(" static_cast<etl::imessage*>(data)->~imessage();") 00313 cog.outl(" }") 00314 cog.outl("") 00315 cog.outl(" //********************************************") 00316 cog.outl(" etl::imessage& get()") 00317 cog.outl(" {") 00318 cog.outl(" return *static_cast<etl::imessage*>(data);") 00319 cog.outl(" }") 00320 cog.outl("") 00321 cog.outl(" //********************************************") 00322 cog.outl(" const etl::imessage& get() const") 00323 cog.outl(" {") 00324 cog.outl(" return *static_cast<const etl::imessage*>(data);") 00325 cog.outl(" }") 00326 cog.outl("") 00327 cog.outl(" enum") 00328 cog.outl(" {") 00329 cog.out(" SIZE = etl::largest<") 00330 for n in range(1, int(Handlers)): 00331 cog.out("T%s, " % n) 00332 cog.outl("T%s>::size," % int(Handlers)) 00333 cog.out(" ALIGNMENT = etl::largest<") 00334 for n in range(1, int(Handlers)): 00335 cog.out("T%s, " % n) 00336 cog.outl("T%s>::alignment" % int(Handlers)) 00337 cog.outl(" };") 00338 cog.outl("") 00339 cog.outl(" private:") 00340 cog.outl("") 00341 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;") 00342 cog.outl(" };") 00343 cog.outl("") 00344 cog.outl(" //**********************************************") 00345 cog.outl(" message_router(etl::message_router_id_t id_)") 00346 cog.outl(" : imessage_router(id_)") 00347 cog.outl(" {") 00348 cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") 00349 cog.outl(" }") 00350 cog.outl("") 00351 cog.outl(" //**********************************************") 00352 cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") 00353 cog.outl(" : imessage_router(id_, successor_)") 00354 cog.outl(" {") 00355 cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") 00356 cog.outl(" }") 00357 cog.outl("") 00358 cog.outl(" //**********************************************") 00359 cog.outl(" void receive(const etl::imessage& msg)") 00360 cog.outl(" {") 00361 cog.outl(" receive(etl::null_message_router::instance(), msg);") 00362 cog.outl(" }") 00363 cog.outl("") 00364 cog.outl(" //**********************************************") 00365 cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg)") 00366 cog.outl(" {") 00367 cog.outl(" const etl::message_id_t id = msg.message_id;") 00368 cog.outl("") 00369 cog.outl(" switch (id)") 00370 cog.outl(" {") 00371 for n in range(1, int(Handlers) + 1): 00372 cog.out(" case T%d::ID:" % n) 00373 cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % n) 00374 cog.outl(" break;") 00375 cog.outl(" default:") 00376 cog.outl(" {") 00377 cog.outl(" if (has_successor())") 00378 cog.outl(" {") 00379 cog.outl(" get_successor().receive(source, msg);") 00380 cog.outl(" }") 00381 cog.outl(" else") 00382 cog.outl(" {") 00383 cog.outl(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);") 00384 cog.outl(" }") 00385 cog.outl(" break;") 00386 cog.outl(" }") 00387 cog.outl(" }") 00388 cog.outl(" }") 00389 cog.outl("") 00390 cog.outl(" using imessage_router::accepts;") 00391 cog.outl("") 00392 cog.outl(" //**********************************************") 00393 cog.outl(" bool accepts(etl::message_id_t id) const") 00394 cog.outl(" {") 00395 cog.outl(" switch (id)") 00396 cog.outl(" {") 00397 cog.out(" ") 00398 for n in range(1, int(Handlers) + 1): 00399 cog.out("case T%d::ID: " % n) 00400 if n % 8 == 0: 00401 cog.outl("") 00402 cog.out(" ") 00403 cog.outl(" return true; break;") 00404 cog.outl(" default:") 00405 cog.outl(" return false; break;") 00406 cog.outl(" }") 00407 cog.outl(" }") 00408 cog.outl("};") 00409 00410 #################################### 00411 # All of the other specialisations. 00412 #################################### 00413 for n in range(int(Handlers) - 1, 0, -1): 00414 cog.outl("") 00415 cog.outl("//***************************************************************************") 00416 if n == 1: 00417 cog.outl("// Specialisation for %d message type." % n) 00418 else: 00419 cog.outl("// Specialisation for %d message types." % n) 00420 cog.outl("//***************************************************************************") 00421 cog.outl("template <typename TDerived, ") 00422 cog.out(" ") 00423 for t in range(1, n): 00424 cog.out("typename T%d, " % t) 00425 if t % 4 == 0: 00426 cog.outl("") 00427 cog.out(" ") 00428 cog.outl("typename T%d>" % n) 00429 cog.out("class message_router<TDerived, ") 00430 for t in range(1, n + 1): 00431 cog.out("T%d, " % t) 00432 if t % 16 == 0: 00433 cog.outl("") 00434 cog.out(" ") 00435 for t in range(n + 1, int(Handlers)): 00436 cog.out("void, ") 00437 if t % 16 == 0: 00438 cog.outl("") 00439 cog.out(" ") 00440 cog.outl("void>") 00441 cog.outl(" : public imessage_router") 00442 cog.outl("{") 00443 cog.outl("public:") 00444 cog.outl("") 00445 cog.outl(" //**********************************************") 00446 cog.outl(" class message_packet") 00447 cog.outl(" {") 00448 cog.outl(" public:") 00449 cog.outl("") 00450 cog.outl(" //********************************************") 00451 cog.outl(" explicit message_packet(const etl::imessage& msg)") 00452 cog.outl(" {") 00453 cog.outl(" const size_t id = msg.message_id;") 00454 cog.outl("") 00455 cog.outl(" void* p = data;") 00456 cog.outl("") 00457 cog.outl(" switch (id)") 00458 cog.outl(" {") 00459 for t in range(1, n + 1): 00460 cog.outl(" case T%s::ID: ::new (p) T%s(static_cast<const T%s&>(msg)); break;" % (t, t, t)) 00461 cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") 00462 cog.outl(" }") 00463 cog.outl(" }") 00464 cog.outl("") 00465 cog.outl(" //********************************************") 00466 cog.outl(" template <typename T>") 00467 cog.outl(" explicit message_packet(const T& msg)") 00468 cog.outl(" {") 00469 cog.out(" STATIC_ASSERT((etl::is_one_of<T, ") 00470 for t in range(1, n): 00471 cog.out("T%s, " % t) 00472 if t % 16 == 0: 00473 cog.outl("") 00474 cog.out(" ") 00475 cog.outl("""T%s>::value), "Unsupported type for this message packet");""" % n) 00476 cog.outl("") 00477 cog.outl(" void* p = data;") 00478 cog.outl(" ::new (p) T(static_cast<const T&>(msg));") 00479 cog.outl(" }") 00480 cog.outl("") 00481 cog.outl(" //********************************************") 00482 cog.outl(" ~message_packet()") 00483 cog.outl(" {") 00484 cog.outl(" static_cast<etl::imessage*>(data)->~imessage();") 00485 cog.outl(" }") 00486 cog.outl("") 00487 cog.outl(" //********************************************") 00488 cog.outl(" etl::imessage& get()") 00489 cog.outl(" {") 00490 cog.outl(" return *static_cast<etl::imessage*>(data);") 00491 cog.outl(" }") 00492 cog.outl("") 00493 cog.outl(" //********************************************") 00494 cog.outl(" const etl::imessage& get() const") 00495 cog.outl(" {") 00496 cog.outl(" return *static_cast<const etl::imessage*>(data);") 00497 cog.outl(" }") 00498 cog.outl("") 00499 cog.outl(" enum") 00500 cog.outl(" {") 00501 cog.out(" SIZE = etl::largest<") 00502 for t in range(1, n): 00503 cog.out("T%s, " % t) 00504 cog.outl("T%s>::size," % n) 00505 cog.out(" ALIGNMENT = etl::largest<") 00506 for t in range(1, n): 00507 cog.out("T%s, " % t) 00508 cog.outl("T%s>::alignment" % n) 00509 cog.outl(" };") 00510 cog.outl("") 00511 cog.outl(" private:") 00512 cog.outl("") 00513 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;") 00514 cog.outl(" };") 00515 cog.outl("") 00516 cog.outl(" //**********************************************") 00517 cog.outl(" message_router(etl::message_router_id_t id_)") 00518 cog.outl(" : imessage_router(id_)") 00519 cog.outl(" {") 00520 cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") 00521 cog.outl(" }") 00522 cog.outl("") 00523 cog.outl(" //**********************************************") 00524 cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") 00525 cog.outl(" : imessage_router(id_, successor_)") 00526 cog.outl(" {") 00527 cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") 00528 cog.outl(" }") 00529 cog.outl("") 00530 cog.outl(" //**********************************************") 00531 cog.outl(" void receive(const etl::imessage& msg)") 00532 cog.outl(" {") 00533 cog.outl(" receive(etl::null_message_router::instance(), msg);") 00534 cog.outl(" }") 00535 cog.outl("") 00536 cog.outl(" //**********************************************") 00537 cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg)") 00538 cog.outl(" {") 00539 cog.outl(" const size_t id = msg.message_id;") 00540 cog.outl("") 00541 cog.outl(" switch (id)") 00542 cog.outl(" {") 00543 for t in range(1, n + 1): 00544 cog.out(" case T%d::ID:" % t) 00545 cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % t) 00546 cog.outl(" break;") 00547 cog.outl(" default:") 00548 cog.outl(" {") 00549 cog.outl(" if (has_successor())") 00550 cog.outl(" {") 00551 cog.outl(" get_successor().receive(source, msg);") 00552 cog.outl(" }") 00553 cog.outl(" else") 00554 cog.outl(" {") 00555 cog.outl(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);") 00556 cog.outl(" }") 00557 cog.outl(" break;") 00558 cog.outl(" }") 00559 cog.outl(" }") 00560 cog.outl(" }") 00561 cog.outl("") 00562 cog.outl(" using imessage_router::accepts;") 00563 cog.outl("") 00564 cog.outl(" //**********************************************") 00565 cog.outl(" bool accepts(etl::message_id_t id) const") 00566 cog.outl(" {") 00567 cog.outl(" switch (id)") 00568 cog.outl(" {") 00569 cog.out(" ") 00570 for t in range(1, n + 1): 00571 cog.out("case T%d::ID: " % t) 00572 if t % 8 == 0: 00573 cog.outl("") 00574 cog.out(" ") 00575 cog.outl("") 00576 cog.outl(" return true; break;") 00577 cog.outl(" default:") 00578 cog.outl(" return false; break;") 00579 cog.outl(" }") 00580 cog.outl(" }") 00581 cog.outl("};") 00582 ]]]*/ 00583 /*[[[end]]]*/ 00584 } 00585 00586 #undef ETL_FILE 00587 00588 #endif 00589
Generated on Tue Jul 12 2022 14:05:42 by
