adevs
|
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