adevs
/home/rotten/adevs-2.6/include/adevs_cellspace.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_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