adevs_digraph.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * Copyright (c) 2013, James Nutaro
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  18. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. *
  25. * The views and conclusions contained in the software and documentation are those
  26. * of the authors and should not be interpreted as representing official policies,
  27. * either expressed or implied, of the FreeBSD Project.
  28. *
  29. * Bugs, comments, and questions can be sent to nutaro@gmail.com
  30. */
  31. #ifndef __adevs_digraph_h_
  32. #define __adevs_digraph_h_
  33. #include "adevs.h"
  34. #include <cassert>
  35. #include <map>
  36. #include <set>
  37. #include <cstdlib>
  38. namespace adevs
  39. {
  40. /**
  41. * The components of a digraph model must use PortValue objects
  42. * as their basic I/O type: the port and value types are template
  43. * arguments. The default port type is an integer.
  44. */
  45. template <class VALUE, class PORT=int> class PortValue
  46. {
  47. public:
  48. /// Constructor
  49. PortValue():
  50. port(),
  51. value()
  52. {
  53. }
  54. /// Copy constructor
  55. PortValue(const PortValue& src):
  56. port(src.port),
  57. value(src.value)
  58. {
  59. }
  60. /// Create an object with the specified port and value
  61. PortValue(PORT port, const VALUE& value):
  62. port(port),
  63. value(value)
  64. {
  65. }
  66. /// Assignment operator
  67. const PortValue<VALUE,PORT>& operator=(const PortValue<VALUE,PORT>& src)
  68. {
  69. port = src.port;
  70. value = src.value;
  71. return *this;
  72. }
  73. /// Destructor
  74. ~PortValue()
  75. {
  76. }
  77. /// The port on which the value appears
  78. PORT port;
  79. /// The value appearing on the port
  80. VALUE value;
  81. };
  82. /**
  83. * The digraph model is used to build block-diagrams from network and atomic components.
  84. * Its components must have PortValue objects as their input/output type.
  85. */
  86. template <class VALUE, class PORT=int, class T = double> class Digraph:
  87. public Network<PortValue<VALUE,PORT>,T>
  88. {
  89. public:
  90. /// An input or output to a component model
  91. typedef PortValue<VALUE,PORT> IO_Type;
  92. /// A component of the Digraph model
  93. typedef Devs<IO_Type,T> Component;
  94. /// Construct a network with no components.
  95. Digraph():
  96. Network<IO_Type,T>()
  97. {
  98. }
  99. /// Add a model to the network.
  100. void add(Component* model);
  101. /// Couple the source model to the destination model.
  102. void couple(Component* src, PORT srcPort,
  103. Component* dst, PORT dstPort);
  104. /// Puts the network's components into to c
  105. void getComponents(Set<Component*>& c);
  106. /// Route an event based on the coupling information.
  107. void route(const IO_Type& x, Component* model,
  108. Bag<Event<IO_Type,T> >& r);
  109. /// Destructor. Destroys all of the component models.
  110. ~Digraph();
  111. private:
  112. // A node in the coupling graph
  113. struct node
  114. {
  115. node():
  116. model(NULL),
  117. port()
  118. {
  119. }
  120. node(Component* model, PORT port):
  121. model(model),
  122. port(port)
  123. {
  124. }
  125. const node& operator=(const node& src)
  126. {
  127. model = src.model;
  128. port = src.port;
  129. return *this;
  130. }
  131. Component* model;
  132. PORT port;
  133. // Comparison for STL map
  134. bool operator<(const node& other) const
  135. {
  136. if (model == other.model) return port < other.port;
  137. return model < other.model;
  138. }
  139. };
  140. // Component model set
  141. Set<Component*> models;
  142. // Coupling information
  143. std::map<node,Bag<node> > graph;
  144. };
  145. template <class VALUE, class PORT, class T>
  146. void Digraph<VALUE,PORT,T>::add(Component* model)
  147. {
  148. assert(model != this);
  149. models.insert(model);
  150. model->setParent(this);
  151. }
  152. template <class VALUE, class PORT, class T>
  153. void Digraph<VALUE,PORT,T>::couple(Component* src, PORT srcPort,
  154. Component* dst, PORT dstPort)
  155. {
  156. if (src != this) add(src);
  157. if (dst != this) add(dst);
  158. node src_node(src,srcPort);
  159. node dst_node(dst,dstPort);
  160. graph[src_node].insert(dst_node);
  161. }
  162. template <class VALUE, class PORT, class T>
  163. void Digraph<VALUE,PORT,T>::getComponents(Set<Component*>& c)
  164. {
  165. c = models;
  166. }
  167. template <class VALUE, class PORT, class T>
  168. void Digraph<VALUE,PORT,T>::
  169. route(const IO_Type& x, Component* model,
  170. Bag<Event<IO_Type,T> >& r)
  171. {
  172. // Find the list of target models and ports
  173. node src_node(model,x.port);
  174. typename std::map<node,Bag<node> >::iterator graph_iter;
  175. graph_iter = graph.find(src_node);
  176. // If no target, just return
  177. if (graph_iter == graph.end()) return;
  178. // Otherwise, add the targets to the event bag
  179. Event<IO_Type,T> event;
  180. typename Bag<node>::iterator node_iter;
  181. for (node_iter = (*graph_iter).second.begin();
  182. node_iter != (*graph_iter).second.end(); node_iter++)
  183. {
  184. event.model = (*node_iter).model;
  185. event.value.port = (*node_iter).port;
  186. event.value.value = x.value;
  187. r.insert(event);
  188. }
  189. }
  190. template <class VALUE, class PORT, class T>
  191. Digraph<VALUE,PORT,T>::~Digraph()
  192. {
  193. typename Set<Component*>::iterator i;
  194. for (i = models.begin(); i != models.end(); i++)
  195. {
  196. delete *i;
  197. }
  198. }
  199. } // end of namespace
  200. #endif