adevs
|
00001 /*************** 00002 Copyright (C) 2000-2006 by James Nutaro 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public 00015 License along with this library; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 Bugs, comments, and questions can be sent to nutaro@gmail.com 00019 ***************/ 00020 #ifndef __adevs_digraph_h_ 00021 #define __adevs_digraph_h_ 00022 #include "adevs.h" 00023 #include <map> 00024 #include <set> 00025 #include <cstdlib> 00026 00027 namespace adevs 00028 { 00029 00035 template <class VALUE, class PORT=int> class PortValue 00036 { 00037 public: 00039 PortValue(): 00040 port(), 00041 value() 00042 { 00043 } 00045 PortValue(const PortValue& src): 00046 port(src.port), 00047 value(src.value) 00048 { 00049 } 00051 PortValue(PORT port, const VALUE& value): 00052 port(port), 00053 value(value) 00054 { 00055 } 00057 const PortValue<VALUE,PORT>& operator=(const PortValue<VALUE,PORT>& src) 00058 { 00059 port = src.port; 00060 value = src.value; 00061 return *this; 00062 } 00064 ~PortValue() 00065 { 00066 } 00068 PORT port; 00070 VALUE value; 00071 }; 00072 00077 template <class VALUE, class PORT=int, class T = double> class Digraph: 00078 public Network<PortValue<VALUE,PORT>,T> 00079 { 00080 public: 00082 typedef PortValue<VALUE,PORT> IO_Type; 00084 typedef Devs<IO_Type,T> Component; 00085 00087 Digraph(): 00088 Network<IO_Type,T>() 00089 { 00090 } 00092 void add(Component* model); 00094 void couple(Component* src, PORT srcPort, 00095 Component* dst, PORT dstPort); 00097 void getComponents(Set<Component*>& c); 00099 void route(const IO_Type& x, Component* model, 00100 Bag<Event<IO_Type,T> >& r); 00102 ~Digraph(); 00103 00104 private: 00105 // A node in the coupling graph 00106 struct node 00107 { 00108 node(): 00109 model(NULL), 00110 port() 00111 { 00112 } 00113 node(Component* model, PORT port): 00114 model(model), 00115 port(port) 00116 { 00117 } 00118 const node& operator=(const node& src) 00119 { 00120 model = src.model; 00121 port = src.port; 00122 return *this; 00123 } 00124 Component* model; 00125 PORT port; 00126 00127 // Comparison for STL map 00128 bool operator<(const node& other) const 00129 { 00130 if (model == other.model) return port < other.port; 00131 return model < other.model; 00132 } 00133 }; 00134 // Component model set 00135 Set<Component*> models; 00136 // Coupling information 00137 std::map<node,Bag<node> > graph; 00138 }; 00139 00140 template <class VALUE, class PORT, class T> 00141 void Digraph<VALUE,PORT,T>::add(Component* model) 00142 { 00143 assert(model != this); 00144 models.insert(model); 00145 model->setParent(this); 00146 } 00147 00148 template <class VALUE, class PORT, class T> 00149 void Digraph<VALUE,PORT,T>::couple(Component* src, PORT srcPort, 00150 Component* dst, PORT dstPort) 00151 { 00152 if (src != this) add(src); 00153 if (dst != this) add(dst); 00154 node src_node(src,srcPort); 00155 node dst_node(dst,dstPort); 00156 graph[src_node].insert(dst_node); 00157 } 00158 00159 template <class VALUE, class PORT, class T> 00160 void Digraph<VALUE,PORT,T>::getComponents(Set<Component*>& c) 00161 { 00162 c = models; 00163 } 00164 00165 template <class VALUE, class PORT, class T> 00166 void Digraph<VALUE,PORT,T>:: 00167 route(const IO_Type& x, Component* model, 00168 Bag<Event<IO_Type,T> >& r) 00169 { 00170 // Find the list of target models and ports 00171 node src_node(model,x.port); 00172 typename std::map<node,Bag<node> >::iterator graph_iter; 00173 graph_iter = graph.find(src_node); 00174 // If no target, just return 00175 if (graph_iter == graph.end()) return; 00176 // Otherwise, add the targets to the event bag 00177 Event<IO_Type> event; 00178 typename Bag<node>::iterator node_iter; 00179 for (node_iter = (*graph_iter).second.begin(); 00180 node_iter != (*graph_iter).second.end(); node_iter++) 00181 { 00182 event.model = (*node_iter).model; 00183 event.value.port = (*node_iter).port; 00184 event.value.value = x.value; 00185 r.insert(event); 00186 } 00187 } 00188 template <class VALUE, class PORT, class T> 00189 Digraph<VALUE,PORT,T>::~Digraph() 00190 { 00191 typename Set<Component*>::iterator i; 00192 for (i = models.begin(); i != models.end(); i++) 00193 { 00194 delete *i; 00195 } 00196 } 00197 00198 } // end of namespace 00199 00200 #endif