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
00097 class Device
00098 {
00099 private:
00100 friend class CompatibleDevice;
00101
00102 simth::checkedVector<InputInterface*> inputInterfaces;
00103 simth::checkedVector<OutputInterface*> outputInterfaces;
00104
00105 simth::checkedVector<ControlInterface*> controlInterfaces;
00106
00107 bool lockedInputLengths_;
00108 bool lockedOutputLengths_;
00109
00110 bool isInterrupted_;
00111
00112 clock_t startClock;
00113 bool isStopWatchRunning;
00114 clock_t simulationClocks;
00115
00116 bool lockedInputLengths() const {return lockedInputLengths_;}
00117 void lockInputLengths() {lockedInputLengths_ = true;}
00118 void unlockInputLengths() {lockedInputLengths_ = false;}
00119
00120 bool lockedOutputLengths() const {return lockedOutputLengths_; }
00121 void lockOutputLengths() {lockedOutputLengths_ = true;}
00122 void unlockOutputLengths() {lockedOutputLengths_ = false;}
00123
00124 int ID_;
00125 DeviceSystemIntf* system_;
00126
00128 PropertyList properties;
00129
00138 Device(const PropertyList& pl);
00139
00142 void processStarted();
00143
00146 void processFinished();
00147
00148 protected:
00149
00150
00163 template<class T>
00164 void setProperty(const std::string& name, const T& value);
00165
00168 DeviceSystemIntf* systemPtr() {return system_;}
00170
00199 template<class T>
00200 size_t insertInputInterface(int number = 1,
00201 const typename T::value_type&
00202 default_val = typename T::value_type() );
00203
00208 virtual InputInterface* inputInterface(int interfaceID);
00209
00214 virtual const InputInterface* inputInterface(int interfaceID) const;
00215
00216
00219 bool isInputInterface(int interfaceID) const;
00220
00224 bool isInputInterfaceConnected(int interfaceID) const;
00225
00229 bool isInputSequence(int interfaceID) const;
00230
00246 template<class T>
00247 T* getInputSequence(int interfaceID);
00249
00250
00253
00263 template<class T>
00264 size_t insertOutputInterface(int number = 1);
00265
00270 virtual OutputInterface* outputInterface(int interfaceID);
00271
00276 virtual const OutputInterface* outputInterface(int interfaceID) const;
00277
00278
00282 bool isOutputInterface(int interfaceID) const;
00283
00287 bool isOutputInterfaceConnected(int interfaceID) const;
00288
00300 template<class T>
00301 T* getOutputSequence(int interfaceID);
00303
00304
00322 virtual void updateInputLengths() = 0;
00323
00340 virtual void updateOutputLengths() = 0;
00342
00343
00367 void flushProcessedSequences();
00368
00384 void flushProcessedInputSequences();
00385
00386
00402 void flushProcessedOutputSequences();
00403
00413 void flushProcessedInputSequence(int interface);
00414
00424 void flushProcessedOutputSequence(int interface);
00425
00438 void releaseProcessedInputSequence(int interface);
00440
00441
00461 template<class D>
00462 size_t insertControlInterface(D* dev, void (D::* helpFuncPtr)());
00463
00482 template<class T, class D>
00483 size_t insertControlInterface(D* dev, void (D::* helpFuncPtr)(T));
00484
00485
00486
00503 template<class D>
00504 size_t insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(),
00505 const std::string& globalName);
00506
00524 template<class T, class D>
00525 size_t insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(T),
00526 const std::string& globalName);
00527
00528
00531 bool isControlInterface(int interfaceID) const;
00532
00533
00536 virtual ControlInterface* controlInterface(int interfaceNr);
00538
00539
00544
00545
00546
00547
00550 void sendReadyToProcessSignal();
00553 void sendStopIterationSignal();
00556 void sendStopSimulationPrematureSignal();
00557
00558 void interrupt();
00559 bool isInterrupted() const {return isInterrupted_;}
00561
00562
00568 void startStopWatch();
00569
00573 void stopStopWatch();
00575
00576
00577
00578 public:
00579
00580
00594 Device(int deviceID, DeviceSystemIntf* system,
00595 const PropertyList& pl);
00596
00599 virtual ~Device();
00600
00601
00607 virtual int ID() const {return ID_;}
00608
00616 template<class T>
00617 const T& getProperty(const std::string &name) const;
00618
00624 bool hasProperty(const std::string& name) const;
00625
00634 bool propertyIsSet(const std::string& name) const;
00635
00639 virtual void print(std::ostream &os) const;
00641
00642
00657 void connect(int fromInterfaceID, Device* toDev, int toInterfaceID);
00658
00668 void connectControlInterface(int interfaceNr, const std::string& globalName);
00669
00676 InputInterface* const acceptConnection(int interfaceID);
00677
00689 virtual void startOfSimulation() {};
00690
00696 virtual void endOfSimulation() {};
00697
00699
00700
00710 virtual void refresh() {};
00711
00721 void invokeProcess();
00722
00734 virtual void process() = 0;
00735
00742 virtual void acceptNewData(int interfaceID);
00743
00744
00754 void resetDevice();
00755
00758 void resetInterfaces();
00759
00767 virtual void reset() {};
00768
00771 void deInterrupt() {isInterrupted_ = false;}
00772
00774
00775
00789 void setInputLength(size_t newLength,int interfaceID, bool enableUpdate = true);
00790
00801 void setInputLength(size_t newLength, bool enableUpdate = true);
00802
00807 size_t inputLength(int interfaceID) const;
00808
00815 size_t inputLength( ) const;
00816
00820 bool isInputLengthUndefined(int interfaceID) const;
00822
00823
00837 void setOutputLength(size_t newLength, int interfaceID, bool enableUpdate = true);
00838
00848 void setOutputLength(size_t newLength, bool enableUpdate = true);
00849
00854 size_t outputLength(int interfaceID) const;
00855
00860 size_t outputLength( ) const;
00861
00865 bool isOutputLengthUndefined(int interfaceID) const;
00866
00882 void reserveOutputLength(size_t newCapacity, int interfaceID);
00883
00897 void reserveOutputLength(size_t newCapacity);
00898
00904 size_t outputCapacity(int interfaceID) const;
00910 size_t outputCapacity( ) const;
00912
00913 };
00914
00915
00916
00917
00932 class CompatibleDevice : public Device
00933 {
00934
00935 public:
00936
00944 CompatibleDevice(const PropertyList& pl = PropertyList()) : Device(pl) {};
00945
00954 void setID(int ID);
00955
00964 void setSystemPtr(DeviceSystemIntf* systemPtr);
00965
00966 };
00967
00968
00969
00970 template<class T>
00971 inline T* Device::getInputSequence(int interfaceID)
00972 {
00973 InputInterface* iface_ptr = inputInterface(interfaceID);
00974 InputInterfaceT<T>* helpPtr = dynamic_cast<InputInterfaceT<T>*>(iface_ptr);
00975
00976 if(helpPtr == NULL) {
00977 throw std::runtime_error(
00978 "Device::getInputSequence<T>(): "
00979 "input interface "+simth::i2string(interfaceID)
00980 + " of Device "+simth::i2string(ID())
00981 + " has wrong type: Expected \""
00982 + simth::demangle(typeid(InputInterfaceT<T>).name())
00983 + "\" but the interface has type \""
00984 + (iface_ptr ? simth::demangle(typeid(*iface_ptr).name()) :
00985 simth::demangle(typeid(iface_ptr).name()))
00986 + "\"");
00987 }
00988 if(!helpPtr->isConnected()) {
00989 throw std::runtime_error("Device::getInputSequence(int interfaceID) : "
00990 "input interface "+simth::i2string(interfaceID)+
00991 " of Device "+simth::i2string(ID())+" is not connected");
00992 }
00993 return helpPtr->internSequence();
00994 }
00995
00996
00997
00998
00999
01000 template<class T>
01001 inline T* Device::getOutputSequence(int interfaceID)
01002 {
01003 OutputInterfaceT<T>* helpPtr = dynamic_cast<OutputInterfaceT<T>*>(outputInterface(interfaceID));
01004 if(SECURITY) {
01005 if(helpPtr == NULL) {
01006 throw std::runtime_error("Device::getOutputSequence(int interfaceID) : "
01007 " output interface "+simth::i2string(interfaceID)+
01008 " of Device "+simth::i2string(ID())+" has wrong type");
01009 }
01010 if(!helpPtr->isConnected()){
01011 throw std::runtime_error("Device::getOutputSequence(int interfaceID) : "
01012 " output interface "+simth::i2string(interfaceID)+
01013 " of Device "+simth::i2string(ID())+" is not connected.");
01014 }
01015 }
01016 return helpPtr->internSequence();
01017 }
01018
01019
01020 template<class T>
01021 inline size_t Device::insertInputInterface(int number,
01022 const typename T::value_type&
01023 default_val)
01024 {
01025 size_t id = inputInterfaces.size();
01026 for(int i=0; i< number; ++i) {
01027 InputInterfaceT<T>* newInterface =
01028 new InputInterfaceT<T>(this, id, default_val);
01029 inputInterfaces.push_back(newInterface);
01030 ++id;
01031 }
01032 return id;
01033
01034 }
01035
01036 template<class T>
01037 inline size_t Device::insertOutputInterface(int number)
01038 {
01039 size_t id = outputInterfaces.size();
01040 for(int i=0; i< number; ++i) {
01041 OutputInterfaceT<T>* newInterface = new OutputInterfaceT<T>(this, id);
01042 outputInterfaces.push_back(newInterface);
01043 ++id;
01044 }
01045 return id;
01046
01047 }
01048
01049 template<class D>
01050 inline size_t
01051 Device::insertControlInterface(D* dev, void (D::* helpFuncPtr)())
01052 {
01053 ControlInterfaceVoidD<D>* newVar = new ControlInterfaceVoidD<D>(dev, helpFuncPtr);
01054 controlInterfaces.push_back(newVar);
01055 return controlInterfaces.size();
01056 }
01057
01058 template<class T, class D>
01059 inline size_t
01060 Device::insertControlInterface(D* dev, void (D::* helpFuncPtr)(T))
01061 {
01062 ControlInterfaceTD<T,D>* newVar = new ControlInterfaceTD<T,D>(dev, helpFuncPtr);
01063 controlInterfaces.push_back(newVar);
01064 return controlInterfaces.size();
01065 }
01066
01067 template<class D>
01068 inline size_t
01069 Device::insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(),
01070 const std::string& globalName)
01071 {
01072 size_t size_ = insertControlInterface<D>(dev,helpFuncPtr);
01073 connectControlInterface(size_-1,globalName);
01074 return size_;
01075 }
01076
01077 template<class T, class D>
01078 inline size_t
01079 Device::insertAndConnectControlInterface(D* dev, void (D::* helpFuncPtr)(T),
01080 const std::string& globalName)
01081 {
01082 size_t size_ = insertControlInterface<T,D>(dev,helpFuncPtr);
01083 connectControlInterface(size_-1,globalName);
01084 return size_;
01085 }
01086
01087
01088 template<class T>
01089 const T& Device::getProperty(const std::string &name) const
01090 {
01091 try {
01092 return properties.PropertyList::getProperty<T>(name);
01093 }
01094 catch (std::runtime_error &err) {
01095 throw std::runtime_error(std::string(err.what()) + " in device "
01096 +simth::i2string(ID()));
01097 }
01098 }
01099
01100
01101 template<class T>
01102 void Device::setProperty(const std::string& name, const T& value)
01103 {
01104 try {
01105 properties.setProperty(name, value);
01106 }
01107 catch (std::runtime_error &err) {
01108 throw std::runtime_error(std::string(err.what()) + " in device "
01109 +simth::i2string(ID()));
01110 }
01111 }
01112
01113 }
01114
01115 #endif
01116
01117