adevs
/home/rotten/adevs-2.6/include/adevs_digraph.h
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