Embedded Template Library  1.0
message_router_generator.h
1 /******************************************************************************
2 The MIT License(MIT)
3 
4 Embedded Template Library.
5 https://github.com/ETLCPP/etl
6 https://www.etlcpp.com
7 
8 Copyright(c) 2017 jwellbelove
9 
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files(the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions :
16 
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19 
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 ******************************************************************************/
28 
29 /*[[[cog
30 import cog
31 cog.outl("#if 0")
32 ]]]*/
33 /*[[[end]]]*/
34 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
35 /*[[[cog
36 import cog
37 cog.outl("#endif")
38 ]]]*/
39 /*[[[end]]]*/
40 
41 /*[[[cog
42 import cog
43 cog.outl("//***************************************************************************")
44 cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.")
45 cog.outl("//***************************************************************************")
46 ]]]*/
47 /*[[[end]]]*/
48 
49 //***************************************************************************
50 // To generate to header file, run this at the command line.
51 // Note: You will need Python and COG installed.
52 //
53 // python -m cogapp -d -e -omessage_router.h -DHandlers=<n> message_router_generator.h
54 // Where <n> is the number of messages to support.
55 //
56 // e.g.
57 // To generate handlers for up to 16 messages...
58 // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h
59 //
60 // See generate.bat
61 //***************************************************************************
62 
63 #ifndef ETL_MESSAGE_ROUTER_INCLUDED
64 #define ETL_MESSAGE_ROUTER_INCLUDED
65 
66 #include <stdint.h>
67 
68 #include "platform.h"
69 #include "message.h"
70 #include "message_packet.h"
71 #include "message_types.h"
72 #include "alignment.h"
73 #include "error_handler.h"
74 #include "exception.h"
75 #include "largest.h"
76 #include "nullptr.h"
77 #include "placement_new.h"
78 
79 #undef ETL_FILE
80 #define ETL_FILE "35"
81 
82 namespace etl
83 {
84  //***************************************************************************
86  //***************************************************************************
88  {
89  public:
90 
91  message_router_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
92  : etl::exception(reason_, file_name_, line_number_)
93  {
94  }
95  };
96 
97  //***************************************************************************
99  //***************************************************************************
101  {
102  public:
103 
104  message_router_illegal_id(string_type file_name_, numeric_type line_number_)
105  : message_router_exception(ETL_ERROR_TEXT("message router:illegal id", ETL_FILE"A"), file_name_, line_number_)
106  {
107  }
108  };
109 
110  //***************************************************************************
112  //***************************************************************************
114  {
115  public:
116 
117  virtual ~imessage_router() {}
118  virtual void receive(const etl::imessage& message) = 0;
119  virtual void receive(imessage_router& source, const etl::imessage& message) = 0;
120  virtual void receive(imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& message) = 0;
121  virtual bool accepts(etl::message_id_t id) const = 0;
122  virtual bool is_null_router() const = 0;
123  virtual bool is_producer() const = 0;
124  virtual bool is_consumer() const = 0;
125 
126  //********************************************
127  bool accepts(const etl::imessage& msg) const
128  {
129  return accepts(msg.message_id);
130  }
131 
132  //********************************************
133  etl::message_router_id_t get_message_router_id() const
134  {
135  return message_router_id;
136  }
137 
138  //********************************************
139  void set_successor(imessage_router& successor_)
140  {
141  successor = &successor_;
142  }
143 
144  //********************************************
145  imessage_router& get_successor() const
146  {
147  return *successor;
148  }
149 
150  //********************************************
151  bool has_successor() const
152  {
153  return (successor != ETL_NULLPTR);
154  }
155 
156  enum
157  {
158  NULL_MESSAGE_ROUTER = 255,
159  MESSAGE_BUS = 254,
160  ALL_MESSAGE_ROUTERS = 253,
161  MAX_MESSAGE_ROUTER = 249
162  };
163 
164  protected:
165 
166  imessage_router(etl::message_router_id_t id_)
167  : successor(ETL_NULLPTR),
168  message_router_id(id_)
169  {
170  }
171 
172  imessage_router(etl::message_router_id_t id_,
173  imessage_router& successor_)
174  : successor(&successor_),
175  message_router_id(id_)
176  {
177  }
178 
179  private:
180 
181  // Disabled.
183  imessage_router& operator =(const imessage_router&);
184 
185  etl::imessage_router* successor;
186 
187  etl::message_router_id_t message_router_id;
188  };
189 
190  //***************************************************************************
192  //***************************************************************************
194  {
195  public:
196 
198  : imessage_router(imessage_router::NULL_MESSAGE_ROUTER)
199  {
200  }
201 
202  //********************************************
203  void receive(const etl::imessage&) ETL_OVERRIDE
204  {
205  }
206 
207  //********************************************
208  void receive(etl::imessage_router&, const etl::imessage&) ETL_OVERRIDE
209  {
210  }
211 
212  //********************************************
213  void receive(imessage_router&, etl::message_router_id_t, const etl::imessage&) ETL_OVERRIDE
214  {
215  }
216 
217  //********************************************
218  bool accepts(etl::message_id_t) const ETL_OVERRIDE
219  {
220  return false;
221  }
222 
223  //********************************************
224  ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE
225  {
226  return true;
227  }
228 
229  //********************************************
230  bool is_producer() const ETL_OVERRIDE
231  {
232  return false;
233  }
234 
235  //********************************************
236  bool is_consumer() const ETL_OVERRIDE
237  {
238  return false;
239  }
240 
241  //********************************************
242  static null_message_router& instance()
243  {
244  static null_message_router nmr;
245  return nmr;
246  }
247  };
248 
249  //***************************************************************************
251  //***************************************************************************
253  {
254  public:
255 
256  message_producer(etl::message_router_id_t id_)
257  : imessage_router(id_)
258  {
259  }
260 
261  //********************************************
262  void receive(const etl::imessage&) ETL_OVERRIDE
263  {
264  }
265 
266  //********************************************
267  void receive(etl::imessage_router&, const etl::imessage&) ETL_OVERRIDE
268  {
269  }
270 
271  //********************************************
272  void receive(imessage_router&, etl::message_router_id_t, const etl::imessage&) ETL_OVERRIDE
273  {
274  }
275 
276  //********************************************
277  bool accepts(etl::message_id_t) const ETL_OVERRIDE
278  {
279  return false;
280  }
281 
282  //********************************************
283  ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE
284  {
285  return false;
286  }
287 
288  //********************************************
289  bool is_producer() const ETL_OVERRIDE
290  {
291  return true;
292  }
293 
294  //********************************************
295  bool is_consumer() const ETL_OVERRIDE
296  {
297  return false;
298  }
299  };
300  //***************************************************************************
303  //***************************************************************************
304  inline static void send_message(etl::imessage_router& destination,
305  const etl::imessage& message)
306  {
307  destination.receive(message);
308  }
309 
310  //***************************************************************************
312  //***************************************************************************
313  inline static void send_message(etl::imessage_router& source,
314  etl::imessage_router& destination,
315  const etl::imessage& message)
316  {
317  destination.receive(source, message);
318  }
319 
320  /*[[[cog
321  import cog
322  ################################################
323  # The first definition for all of the messages.
324  ################################################
325  cog.outl("//***************************************************************************")
326  cog.outl("// The definition for all %s message types." % Handlers)
327  cog.outl("//***************************************************************************")
328  cog.outl("template <typename TDerived,")
329  cog.out(" ")
330  cog.out("typename T1, ")
331  for n in range(2, int(Handlers)):
332  cog.out("typename T%s = void, " % n)
333  if n % 4 == 0:
334  cog.outl("")
335  cog.out(" ")
336  cog.outl("typename T%s = void>" % int(Handlers))
337  cog.out("class message_router")
338  cog.outl(" : public imessage_router")
339  cog.outl("{")
340  cog.outl("public:")
341  cog.outl("")
342  cog.out(" typedef etl::message_packet<")
343  for n in range(1, int(Handlers)):
344  cog.out("T%s, " % n)
345  cog.outl(" T%s> message_packet;" % int(Handlers))
346  cog.outl("")
347  cog.outl(" //**********************************************")
348  cog.outl(" message_router(etl::message_router_id_t id_)")
349  cog.outl(" : imessage_router(id_)")
350  cog.outl(" {")
351  cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
352  cog.outl(" }")
353  cog.outl("")
354  cog.outl(" //**********************************************")
355  cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)")
356  cog.outl(" : imessage_router(id_, successor_)")
357  cog.outl(" {")
358  cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
359  cog.outl(" }")
360  cog.outl("")
361  cog.outl(" //**********************************************")
362  cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE")
363  cog.outl(" {")
364  cog.outl(" receive(etl::null_message_router::instance(), msg);")
365  cog.outl(" }")
366  cog.outl("")
367  cog.outl(" //**********************************************")
368  cog.outl(" void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE")
369  cog.outl(" {")
370  cog.outl(" if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))")
371  cog.outl(" {")
372  cog.outl(" receive(source, msg);")
373  cog.outl(" }")
374  cog.outl(" }")
375  cog.outl("")
376  cog.outl(" //**********************************************")
377  cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE")
378  cog.outl(" {")
379  cog.outl(" const etl::message_id_t id = msg.message_id;")
380  cog.outl("")
381  cog.outl(" switch (id)")
382  cog.outl(" {")
383  for n in range(1, int(Handlers) + 1):
384  cog.out(" case T%d::ID:" % n)
385  cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % n)
386  cog.outl(" break;")
387  cog.outl(" default:")
388  cog.outl(" {")
389  cog.outl(" if (has_successor())")
390  cog.outl(" {")
391  cog.outl(" get_successor().receive(source, msg);")
392  cog.outl(" }")
393  cog.outl(" else")
394  cog.outl(" {")
395  cog.outl(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);")
396  cog.outl(" }")
397  cog.outl(" break;")
398  cog.outl(" }")
399  cog.outl(" }")
400  cog.outl(" }")
401  cog.outl("")
402  cog.outl(" using imessage_router::accepts;")
403  cog.outl("")
404  cog.outl(" //**********************************************")
405  cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE")
406  cog.outl(" {")
407  cog.outl(" switch (id)")
408  cog.outl(" {")
409  cog.out(" ")
410  for n in range(1, int(Handlers) + 1):
411  cog.out("case T%d::ID: " % n)
412  if n % 8 == 0:
413  cog.outl("")
414  cog.out(" ")
415  cog.outl(" return true;")
416  cog.outl(" default:")
417  cog.outl(" return false;")
418  cog.outl(" }")
419  cog.outl(" }")
420  cog.outl("")
421  cog.outl(" //********************************************")
422  cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE")
423  cog.outl(" {")
424  cog.outl(" return false;")
425  cog.outl(" }")
426  cog.outl("")
427  cog.outl(" //********************************************")
428  cog.outl(" bool is_producer() const ETL_OVERRIDE")
429  cog.outl(" {")
430  cog.outl(" return true;")
431  cog.outl(" }")
432  cog.outl("")
433  cog.outl(" //********************************************")
434  cog.outl(" bool is_consumer() const ETL_OVERRIDE")
435  cog.outl(" {")
436  cog.outl(" return true;")
437  cog.outl(" }")
438  cog.outl("};")
439 
440  ####################################
441  # All of the other specialisations.
442  ####################################
443  for n in range(int(Handlers) - 1, 0, -1):
444  cog.outl("")
445  cog.outl("//***************************************************************************")
446  if n == 1:
447  cog.outl("// Specialisation for %d message type." % n)
448  else:
449  cog.outl("// Specialisation for %d message types." % n)
450  cog.outl("//***************************************************************************")
451  cog.outl("template <typename TDerived, ")
452  cog.out(" ")
453  for t in range(1, n):
454  cog.out("typename T%d, " % t)
455  if t % 4 == 0:
456  cog.outl("")
457  cog.out(" ")
458  cog.outl("typename T%d>" % n)
459  cog.out("class message_router<TDerived, ")
460  for t in range(1, n + 1):
461  cog.out("T%d, " % t)
462  if t % 16 == 0:
463  cog.outl("")
464  cog.out(" ")
465  for t in range(n + 1, int(Handlers)):
466  cog.out("void, ")
467  if t % 16 == 0:
468  cog.outl("")
469  cog.out(" ")
470  cog.outl("void>")
471  cog.outl(" : public imessage_router")
472  cog.outl("{")
473  cog.outl("public:")
474  cog.outl("")
475  cog.out(" typedef etl::message_packet<")
476  for t in range(1, n):
477  cog.out("T%s, " % t)
478  cog.outl(" T%s> message_packet;" % n)
479  cog.outl("")
480  cog.outl(" //**********************************************")
481  cog.outl(" message_router(etl::message_router_id_t id_)")
482  cog.outl(" : imessage_router(id_)")
483  cog.outl(" {")
484  cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
485  cog.outl(" }")
486  cog.outl("")
487  cog.outl(" //**********************************************")
488  cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)")
489  cog.outl(" : imessage_router(id_, successor_)")
490  cog.outl(" {")
491  cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
492  cog.outl(" }")
493  cog.outl("")
494  cog.outl(" //**********************************************")
495  cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE")
496  cog.outl(" {")
497  cog.outl(" receive(etl::null_message_router::instance(), msg);")
498  cog.outl(" }")
499  cog.outl("")
500  cog.outl(" //**********************************************")
501  cog.outl(" void receive(etl::imessage_router& source, etl::message_router_id_t destination_router_id, const etl::imessage& msg) ETL_OVERRIDE")
502  cog.outl(" {")
503  cog.outl(" if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS))")
504  cog.outl(" {")
505  cog.outl(" receive(source, msg);")
506  cog.outl(" }")
507  cog.outl(" }")
508  cog.outl("")
509  cog.outl(" //**********************************************")
510  cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg) ETL_OVERRIDE")
511  cog.outl(" {")
512  cog.outl(" const size_t id = msg.message_id;")
513  cog.outl("")
514  cog.outl(" switch (id)")
515  cog.outl(" {")
516  for t in range(1, n + 1):
517  cog.out(" case T%d::ID:" % t)
518  cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % t)
519  cog.outl(" break;")
520  cog.outl(" default:")
521  cog.outl(" {")
522  cog.outl(" if (has_successor())")
523  cog.outl(" {")
524  cog.outl(" get_successor().receive(source, msg);")
525  cog.outl(" }")
526  cog.outl(" else")
527  cog.outl(" {")
528  cog.outl(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);")
529  cog.outl(" }")
530  cog.outl(" break;")
531  cog.outl(" }")
532  cog.outl(" }")
533  cog.outl(" }")
534  cog.outl("")
535  cog.outl(" using imessage_router::accepts;")
536  cog.outl("")
537  cog.outl(" //**********************************************")
538  cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE")
539  cog.outl(" {")
540  cog.outl(" switch (id)")
541  cog.outl(" {")
542  cog.out(" ")
543  for t in range(1, n + 1):
544  cog.out("case T%d::ID: " % t)
545  if t % 8 == 0:
546  cog.outl("")
547  cog.out(" ")
548  cog.outl("")
549  cog.outl(" return true;")
550  cog.outl(" default:")
551  cog.outl(" return false;")
552  cog.outl(" }")
553  cog.outl(" }")
554  cog.outl("")
555  cog.outl(" //********************************************")
556  cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE")
557  cog.outl(" {")
558  cog.outl(" return false;")
559  cog.outl(" }")
560  cog.outl("")
561  cog.outl(" //********************************************")
562  cog.outl(" bool is_producer() const ETL_OVERRIDE")
563  cog.outl(" {")
564  cog.outl(" return true;")
565  cog.outl(" }")
566  cog.outl("")
567  cog.outl(" //********************************************")
568  cog.outl(" bool is_consumer() const ETL_OVERRIDE")
569  cog.outl(" {")
570  cog.outl(" return true;")
571  cog.outl(" }")
572  cog.outl("};")
573  ]]]*/
574  /*[[[end]]]*/
575 }
576 
577 #undef ETL_FILE
578 
579 #endif
This is the base of all message routers.
Definition: message_router_generator.h:114
Definition: message.h:68
This router can be used as a producer-only of messages, such an interrupt routine.
Definition: message_router_generator.h:253
Base exception class for message router.
Definition: message_router_generator.h:88
Router id is out of the legal range.
Definition: message_router_generator.h:101
Definition: message.h:92
This router can be used as a sink for messages or a 'null source' router.
Definition: message_router_generator.h:194
Definition: exception.h:47
Definition: absolute.h:37
uint_least8_t message_id_t
Allow alternative type for message id.
Definition: message_types.h:40