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_cellspace_h_ 00021 #define __adevs_cellspace_h_ 00022 #include "adevs.h" 00023 #include <cstdlib> 00024 00025 namespace adevs 00026 { 00027 00033 template <class X> class CellEvent 00034 { 00035 public: 00037 CellEvent(){ x = y = z = 0; } 00039 CellEvent(const CellEvent<X>& src): 00040 x(src.x),y(src.y),z(src.z),value(src.value){} 00042 const CellEvent& operator=(const CellEvent<X>& src) 00043 { 00044 x = src.x; y = src.y; z = src.z; value = src.value; 00045 return *this; 00046 } 00048 long int x; 00050 long int y; 00052 long int z; 00054 X value; 00055 }; 00056 00068 template <class X, class T = double> class CellSpace: public Network<CellEvent<X>,T> 00069 { 00070 public: 00072 typedef Devs<CellEvent<X>,T> Cell; 00074 CellSpace(long int width, long int height = 1, long int depth = 1); 00076 void add(Cell* model, long int x, long int y = 0, long int z = 0) 00077 { 00078 space[x][y][z] = model; 00079 model->setParent(this); 00080 } 00082 const Cell* getModel(long int x, long int y = 0, long int z = 0) const 00083 { 00084 return space[x][y][z]; 00085 } 00087 Cell* getModel(long int x, long int y = 0, long int z = 0) 00088 { 00089 return space[x][y][z]; 00090 } 00092 long int getWidth() const { return w; } 00094 long int getHeight() const { return h; } 00096 long int getDepth() const { return d; } 00098 void getComponents(Set<Cell*>& c); 00100 void route(const CellEvent<X>& event, Cell* model, 00101 Bag<Event<CellEvent<X>,T> >& r); 00103 ~CellSpace(); 00104 private: 00105 long int w, h, d; 00106 Cell**** space; 00107 }; 00108 00109 // Implementation of constructor 00110 template <class X, class T> 00111 CellSpace<X,T>::CellSpace(long int width, long int height, long int depth): 00112 Network<CellEvent<X>,T>() 00113 { 00114 w = width; 00115 h = height; 00116 d = depth; 00117 // Allocate space for the cells and set the entries to NULL 00118 space = new Cell***[w]; 00119 for (long int x = 0; x < w; x++) 00120 { 00121 space[x] = new Cell**[h]; 00122 for (long int y = 0; y < h; y++) 00123 { 00124 space[x][y] = new Cell*[h]; 00125 for (long int z = 0; z < d; z++) 00126 { 00127 space[x][y][z] = NULL; 00128 } 00129 } 00130 } 00131 } 00132 00133 // Implementation of destructor 00134 template <class X, class T> 00135 CellSpace<X,T>::~CellSpace() 00136 { 00137 for (long int x = 0; x < w; x++) 00138 { 00139 for (long int y = 0; y < h; y++) 00140 { 00141 for (long int z = 0; z < d; z++) 00142 { 00143 if (space[x][y][z] != NULL) 00144 { 00145 delete space[x][y][z]; 00146 } 00147 } 00148 delete [] space[x][y]; 00149 } 00150 delete [] space[x]; 00151 } 00152 delete [] space; 00153 } 00154 00155 // Implementation of the getComponents() method 00156 template <class X, class T> 00157 void CellSpace<X,T>::getComponents(Set<Cell*>& c) 00158 { 00159 // Add all non-null entries to the set c 00160 for (long int x = 0; x < w; x++) 00161 { 00162 for (long int y = 0; y < h; y++) 00163 { 00164 for (long int z = 0; z < d; z++) 00165 { 00166 if (space[x][y][z] != NULL) 00167 { 00168 c.insert(space[x][y][z]); 00169 } 00170 } 00171 } 00172 } 00173 } 00174 00175 // Event routing function for the net_exec 00176 template <class X, class T> 00177 void CellSpace<X,T>::route( 00178 const CellEvent<X>& event, Cell* model, Bag<Event<CellEvent<X>,T> >& r) 00179 { 00180 Cell* target = NULL; 00181 // If the target cell is inside of the cellspace 00182 if (event.x >= 0 && event.x < w && // check x dimension 00183 event.y >= 0 && event.y < h && // check y dimension 00184 event.z >= 0 && event.z < d) // check z dimension 00185 { 00186 // Get the interior target 00187 target = space[event.x][event.y][event.z]; 00188 } 00189 else 00190 { 00191 // Otherwise, the event becomes an external output from the cellspace 00192 target = this; 00193 } 00194 // If the target exists 00195 if (target != NULL) 00196 { 00197 // Add an appropriate event to the receiver bag 00198 Event<CellEvent<X> > io(target,event); 00199 r.insert(io); 00200 } 00201 } 00202 00203 } // end of namespace 00204 00205 #endif