00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00050 #ifndef BASIC_DEVICE_HEADER
00051 #define BASIC_DEVICE_HEADER
00052
00053 #include <simthetic/exceptions.h>
00054 #include <simthetic/controlinterface.h>
00055 #include <simthetic/signals.h>
00056 #include <simthetic/interfaces.h>
00057 #include <simthetic/propertylist.h>
00058 #include <simthetic/phbib.h>
00059
00060
00061 namespace simth
00062 {
00063
00064 class DeviceSystemIntf;
00065 class LoopControl;
00066 class ControlInterface;
00067 class InputInterface;
00068 class OutputInterface;
00069
00070
00099 class Device
00100 {
00101 private:
00102 friend class CompatibleDevice;
00103
00104 simth::checkedVector<InputInterface*> inputInterfaces;
00105 simth::checkedVector<OutputInterface*> outputInterfaces;
00106
00107 simth::checkedVector<ControlInterface*> controlInterfaces;
00108
00109 bool lockedInputLengths_;
00110 bool lockedOutputLengths_;
00111
00112
00113
00114 clock_t startClock;
00115 bool isStopWatchRunning;
00116 clock_t simulationClocks;
00117
00118 bool lockedInputLengths() const {return lockedInputLengths_;}
00119 void lockInputLengths() {lockedInputLengths_ = true;}
00120 void unlockInputLengths() {lockedInputLengths_ = false;}
00121
00122 bool lockedOutputLengths() const {return lockedOutputLengths_; }
00123 void lockOutputLengths() {lockedOutputLengths_ = true;}
00124 void unlockOutputLengths() {lockedOutputLengths_ = false;}
00125
00126 int ID_;
00127 DeviceSystemIntf* system_;
00128
00130 PropertyList properties;
00131
00140 Device(const PropertyList& pl);
00141
00144 void processStarted();
00145
00148 void processFinished();
00149
00150 protected:
00151
00152
00165 template<class T>
00166 void setProperty(const std::string& name, const T& value);
00167
00170 DeviceSystemIntf* systemPtr() {return system_;}
00172
00201 template<class T>
00202 size_t insertInputInterface(int number = 1,
00203 const typename T::value_type&
00204 default_val = typename T::value_type() );
00205
00210 virtual InputInterface* inputInterface(int interfaceID);
00211
00216 virtual const InputInterface* inputInterface(int interfaceID) const;
00217
00218
00221 bool isInputInterface(int interfaceID) const;
00222
00226 bool isInputInterfaceConnected(int interfaceID) const;
00227
00231 bool isInputSequence(int interfaceID) const;
00232
00248 template<class T>
00249 T* getInputSequence(int interfaceID);
00251
00252
00255
00265 template<class T>
00266 size_t insertOutputInterface(int number = 1);
00267
00272 virtual OutputInterface* outputInterface(int interfaceID);
00273
00278 virtual const OutputInterface* outputInterface(int interfaceID) const;
00279
00280
00284 bool isOutputInterface(int interfaceID) const;
00285
00289 bool isOutputInterfaceConnected(int interfaceID) const;
00290
00302 template<class T>
00303 T* getOutputSequence(int interfaceID);
00305
00306
00334 virtual void updateInputLengths() = 0;
00335
00361 virtual void updateOutputLengths() = 0;
00363
00364
00390 void flushProcessedSequences();
00391
00409 void flushProcessedInputSequences();
00410
00411
00429 void flushProcessedOutputSequences();
00430
00442 void flushProcessedInputSequence(int interface);
00443
00455 void flushProcessedOutputSequence(int interface);
00456
00471 void releaseProcessedInputSequence(int interface);
00473
00474
00494 template<class D>
00495 size_t insertControlInterface(D* dev, void (D::* helpFuncPtr)());
00496
00515 template<class T, class D>
00516 size_t insertControlInterface(D* dev, void (D::* helpFuncPtr)(T));
00517
00518
00519
00536 template<class D>
00537 size_t insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(),
00538 const std::string& globalName);
00539
00557 template<class T, class D>
00558 size_t insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(T),
00559 const std::string& globalName);
00560
00561
00564 bool isControlInterface(int interfaceID) const;
00565
00566
00569 virtual ControlInterface* controlInterface(int interfaceNr);
00571
00572
00577
00578
00579
00580
00585 void sendReadyToProcessSignal();
00588 void sendStopIterationSignal();
00591 void sendStopSimulationPrematureSignal();
00592
00593
00594
00596
00597
00603 void startStopWatch();
00604
00608 void stopStopWatch();
00610
00611
00612
00613 public:
00614
00615
00629 Device(int deviceID, DeviceSystemIntf* system,
00630 const PropertyList& pl);
00631
00634 virtual ~Device();
00635
00636
00642 virtual int ID() const {return ID_;}
00643
00651 template<class T>
00652 const T& getProperty(const std::string &name) const;
00653
00659 bool hasProperty(const std::string& name) const;
00660
00669 bool propertyIsSet(const std::string& name) const;
00670
00674 virtual void print(std::ostream &os) const;
00676
00677
00692 void connect(int fromInterfaceID, Device* toDev, int toInterfaceID);
00693
00703 void connectControlInterface(int interfaceNr, const std::string& globalName);
00704
00711 InputInterface* const acceptConnection(int interfaceID);
00712
00726 virtual void startOfSimulation() {};
00727
00733 virtual void endOfSimulation() {};
00734
00736
00737
00747 virtual void refresh() {};
00748
00758 void invokeProcess();
00759
00773 virtual void process() = 0;
00774
00785 virtual void acceptNewData(int interfaceID);
00786
00787
00799 void resetDevice();
00800
00803 void resetInterfaces();
00804
00821 virtual void reset();
00822
00823
00824
00825
00826
00828
00829
00848 void setInputLength(size_t newLength,int interfaceID, bool enableUpdate = true);
00849
00865 void setInputLength(size_t newLength, bool enableUpdate = true);
00866
00871 size_t inputLength(int interfaceID) const;
00872
00879 size_t inputLength( ) const;
00880
00884 bool isInputLengthUndefined(int interfaceID) const;
00886
00887
00906 void setOutputLength(size_t newLength, int interfaceID, bool enableUpdate = true);
00907
00922 void setOutputLength(size_t newLength, bool enableUpdate = true);
00923
00928 size_t outputLength(int interfaceID) const;
00929
00934 size_t outputLength( ) const;
00935
00939 bool isOutputLengthUndefined(int interfaceID) const;
00940
00956 void reserveOutputLength(size_t newCapacity, int interfaceID);
00957
00971 void reserveOutputLength(size_t newCapacity);
00972
00978 size_t outputCapacity(int interfaceID) const;
00984 size_t outputCapacity( ) const;
00986
00987 };
00988
00989
00990
00991
01006 class CompatibleDevice : public Device
01007 {
01008
01009 public:
01010
01018 CompatibleDevice(const PropertyList& pl = PropertyList()) : Device(pl) {};
01019
01028 void setID(int ID);
01029
01038 void setSystemPtr(DeviceSystemIntf* systemPtr);
01039
01040 };
01041
01042
01043
01044 template<class T>
01045 inline T* Device::getInputSequence(int interfaceID)
01046 {
01047 InputInterface* iface_ptr = inputInterface(interfaceID);
01048 InputInterfaceT<T>* helpPtr = dynamic_cast<InputInterfaceT<T>*>(iface_ptr);
01049
01050 if(helpPtr == NULL) {
01051 throw std::runtime_error(
01052 "Device::getInputSequence<T>(): "
01053 "input interface "+simth::i2string(interfaceID)
01054 + " of Device "+simth::i2string(ID())
01055 + " has wrong type: Expected \""
01056 + simth::demangle(typeid(InputInterfaceT<T>).name())
01057 + "\" but the interface has type \""
01058 + (iface_ptr ? simth::demangle(typeid(*iface_ptr).name()) :
01059 simth::demangle(typeid(iface_ptr).name()))
01060 + "\"");
01061 }
01062 if(!helpPtr->isConnected()) {
01063 throw std::runtime_error("Device::getInputSequence(int interfaceID) : "
01064 "input interface "+simth::i2string(interfaceID)+
01065 " of Device "+simth::i2string(ID())+" is not connected");
01066 }
01067 return helpPtr->internSequence();
01068 }
01069
01070
01071
01072
01073
01074 template<class T>
01075 inline T* Device::getOutputSequence(int interfaceID)
01076 {
01077 OutputInterfaceT<T>* helpPtr = dynamic_cast<OutputInterfaceT<T>*>(outputInterface(interfaceID));
01078 if(SECURITY) {
01079 if(helpPtr == NULL) {
01080 throw std::runtime_error("Device::getOutputSequence(int interfaceID) : "
01081 " output interface "+simth::i2string(interfaceID)+
01082 " of Device "+simth::i2string(ID())+" has wrong type");
01083 }
01084 if(!helpPtr->isConnected()){
01085 throw std::runtime_error("Device::getOutputSequence(int interfaceID) : "
01086 " output interface "+simth::i2string(interfaceID)+
01087 " of Device "+simth::i2string(ID())+" is not connected.");
01088 }
01089 }
01090 return helpPtr->internSequence();
01091 }
01092
01093
01094 template<class T>
01095 inline size_t Device::insertInputInterface(int number,
01096 const typename T::value_type&
01097 default_val)
01098 {
01099 size_t id = inputInterfaces.size();
01100 for(int i=0; i< number; ++i) {
01101 InputInterfaceT<T>* newInterface =
01102 new InputInterfaceT<T>(this, id, default_val);
01103 inputInterfaces.push_back(newInterface);
01104 ++id;
01105 }
01106 return id;
01107
01108 }
01109
01110 template<class T>
01111 inline size_t Device::insertOutputInterface(int number)
01112 {
01113 size_t id = outputInterfaces.size();
01114 for(int i=0; i< number; ++i) {
01115 OutputInterfaceT<T>* newInterface = new OutputInterfaceT<T>(this, id);
01116 outputInterfaces.push_back(newInterface);
01117 ++id;
01118 }
01119 return id;
01120
01121 }
01122
01123 template<class D>
01124 inline size_t
01125 Device::insertControlInterface(D* dev, void (D::* helpFuncPtr)())
01126 {
01127 ControlInterfaceVoidD<D>* newVar = new ControlInterfaceVoidD<D>(dev, helpFuncPtr);
01128 controlInterfaces.push_back(newVar);
01129 return controlInterfaces.size();
01130 }
01131
01132 template<class T, class D>
01133 inline size_t
01134 Device::insertControlInterface(D* dev, void (D::* helpFuncPtr)(T))
01135 {
01136 ControlInterfaceTD<T,D>* newVar = new ControlInterfaceTD<T,D>(dev, helpFuncPtr);
01137 controlInterfaces.push_back(newVar);
01138 return controlInterfaces.size();
01139 }
01140
01141 template<class D>
01142 inline size_t
01143 Device::insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(),
01144 const std::string& globalName)
01145 {
01146 size_t size_ = insertControlInterface<D>(dev,helpFuncPtr);
01147 connectControlInterface(size_-1,globalName);
01148 return size_;
01149 }
01150
01151 template<class T, class D>
01152 inline size_t
01153 Device::insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(T),
01154 const std::string& globalName)
01155 {
01156 size_t size_ = insertControlInterface<T,D>(dev,helpFuncPtr);
01157 connectControlInterface(size_-1,globalName);
01158 return size_;
01159 }
01160
01161
01162 template<class T>
01163 const T& Device::getProperty(const std::string &name) const
01164 {
01165 try {
01166 return properties.PropertyList::getProperty<T>(name);
01167 }
01168 catch (std::runtime_error &err) {
01169 throw std::runtime_error(std::string(err.what()) + " in device "
01170 +simth::i2string(ID()));
01171 }
01172 }
01173
01174
01175 template<class T>
01176 void Device::setProperty(const std::string& name, const T& value)
01177 {
01178 try {
01179 properties.setProperty(name, value);
01180 }
01181 catch (std::runtime_error &err) {
01182 throw std::runtime_error(std::string(err.what()) + " in device "
01183 +simth::i2string(ID()));
01184 }
01185 }
01186
01187 }
01188
01189 #endif
01190
01191