adevs
/home/rotten/adevs-2.6/include/adevs_wrapper.h
00001 /***************
00002 Copyright (C) 2007 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_wrapper_h_
00021 #define __adevs_wrapper_h_
00022 #include "adevs_models.h"
00023 
00024 namespace adevs
00025 {
00043         template <typename ExternalType, typename InternalType, class T = double> class ModelWrapper:
00044                 public Atomic<ExternalType,T>,
00045                 public EventListener<InternalType,T>
00046         {
00047                 public:
00053                         ModelWrapper(Devs<InternalType,T>* model);
00062                         virtual void translateInput(const Bag<ExternalType>& external_input,
00063                                         Bag<Event<InternalType,T> >& internal_input) = 0;
00072                         virtual void translateOutput(const Bag<Event<InternalType,T> >& internal_output,
00073                                         Bag<ExternalType>& external_output) = 0;
00080                         virtual void gc_input(Bag<Event<InternalType,T> >& g) = 0;
00082                         Devs<InternalType,T>* getWrappedModel() { return model; }
00084                         void delta_int();
00086                         void delta_ext(T e, const Bag<ExternalType>& xb);
00088                         void delta_conf(const Bag<ExternalType>& xb);
00090                         void output_func(Bag<ExternalType>& yb);
00092                         T ta();
00094                         void outputEvent(Event<InternalType,T> y, T t);
00096                         ~ModelWrapper();
00097                 private:
00098                         ModelWrapper(){}
00099                         ModelWrapper(const ModelWrapper&){}
00100                         void operator=(const ModelWrapper&){}
00101                         // Bag of events created by the input translation method 
00102                         Bag<Event<InternalType,T> > input;
00103                         // Output from the wrapped model
00104                         Bag<Event<InternalType,T> > output;
00105                         // The wrapped model
00106                         Devs<InternalType,T>* model;
00107                         // Simulator for driving the wrapped model
00108                         Simulator<InternalType,T>* sim;
00109                         // Last event time
00110                         T tL;
00111         };
00112 
00113 template <typename ExternalType, typename InternalType, class T> 
00114 ModelWrapper<ExternalType,InternalType,T>::ModelWrapper(Devs<InternalType,T>* model):
00115         Atomic<ExternalType,T>(),
00116         EventListener<InternalType,T>(),
00117         model(model),
00118         tL(adevs_zero<T>())
00119 {
00120         sim = new Simulator<InternalType,T>(model);
00121         sim->addEventListener(this);
00122 }
00123 
00124 template <typename ExternalType, typename InternalType, class T> 
00125 void ModelWrapper<ExternalType,InternalType,T>::delta_int()
00126 {
00127         // Update the internal clock
00128         tL = sim->nextEventTime();
00129         // Execute the next autonomous event for the wrapped model
00130         sim->execNextEvent();
00131 }
00132 
00133 template <typename ExternalType, typename InternalType, class T> 
00134 void ModelWrapper<ExternalType,InternalType,T>::delta_ext(T e, const Bag<ExternalType>& xb)
00135 {
00136         // Update the internal clock
00137         tL += e;
00138         // Convert the external inputs to internal inputs
00139         translateInput(xb,input);
00140         // Apply the input
00141         sim->computeNextState(input,tL);
00142         // Clean up 
00143         gc_input(input);
00144         input.clear();
00145 }
00146 
00147 template <typename ExternalType, typename InternalType, class T> 
00148 void ModelWrapper<ExternalType,InternalType,T>::delta_conf(const Bag<ExternalType>& xb)
00149 {
00150         // Update the internal clock
00151         tL = sim->nextEventTime();
00152         // Convert the external inputs to internal inputs
00153         translateInput(xb,input);
00154         // Apply the input
00155         sim->computeNextState(input,tL);
00156         // Clean up 
00157         gc_input(input);
00158         input.clear();
00159 }
00160 
00161 template <typename ExternalType, typename InternalType, class T> 
00162 T ModelWrapper<ExternalType,InternalType,T>::ta()
00163 {
00164         if (sim->nextEventTime() < adevs_inf<T>()) return sim->nextEventTime()-tL;
00165         else return adevs_inf<T>();
00166 }
00167 
00168 template <typename ExternalType, typename InternalType, class T> 
00169 void ModelWrapper<ExternalType,InternalType,T>::output_func(Bag<ExternalType>& yb)
00170 {
00171         // Compute the model's output events; this causes the outputEvent method to be called
00172         sim->computeNextOutput();
00173         // Translate the output events to external output events
00174         translateOutput(output,yb);
00175         // Clean up; the contents of the output bag are deleted by the wrapped model's 
00176         // gc_output method
00177         output.clear();
00178 }
00179 
00180 template <typename ExternalType, typename InternalType, class T> 
00181 void ModelWrapper<ExternalType,InternalType,T>::outputEvent(Event<InternalType,T> y, T t)
00182 {
00183         // Just save the events for processing by the output_func
00184         output.insert(y);
00185 }
00186 
00187 template <typename ExternalType, typename InternalType, class T> 
00188 ModelWrapper<ExternalType,InternalType,T>::~ModelWrapper()
00189 {
00190         delete sim;
00191         delete model;
00192 }
00193 
00194 } // end of namespace
00195 
00196 #endif