ccomponent.h

00001 //==========================================================================
00002 //   CCOMPONENT.H  -  header for
00003 //                     OMNeT++/OMNEST
00004 //            Discrete System Simulation in C++
00005 //
00006 //==========================================================================
00007 
00008 /*--------------------------------------------------------------*
00009   Copyright (C) 1992-2008 Andras Varga
00010   Copyright (C) 2006-2008 OpenSim Ltd.
00011 
00012   This file is distributed WITHOUT ANY WARRANTY. See the file
00013   `license' for details on this and other legal matters.
00014 *--------------------------------------------------------------*/
00015 
00016 #ifndef __CCOMPONENT_H
00017 #define __CCOMPONENT_H
00018 
00019 #include <vector>
00020 #include "simkerneldefs.h"
00021 #include "cownedobject.h"
00022 #include "cpar.h"
00023 #include "cdefaultlist.h"
00024 #include "simtime.h"
00025 #include "cenvir.h"
00026 #include "clistener.h"
00027 
00028 NAMESPACE_BEGIN
00029 
00030 class cComponentType;
00031 class cProperties;
00032 class cDisplayString;
00033 class cRNG;
00034 class cStatistic;
00035 
00036 
00043 class SIM_API cComponent : public cDefaultList //implies noncopyable
00044 {
00045     friend class cPar; // needs to call handleParameterChange()
00046     friend class cChannel; // allow it to access FL_INITIALIZED and releaseLocalListeners()
00047     friend class cModule; // allow it to access FL_INITIALIZED, releaseLocalListeners() and repairSignalFlags()
00048     friend class cGate;   // because of repairSignalFlags()
00049 
00050   private:
00051     enum {
00052       FL_PARAMSFINALIZED = 4,   // whether finalizeParameters() has been called
00053       FL_INITIALIZED = 8,       // whether initialize() has been called
00054       FL_EVLOGENABLED = 16,     // whether logging via ev<< is enabled
00055       FL_DISPSTR_CHECKED = 32,  // for hasDisplayString(): whether the FL_DISPSTR_NOTEMPTY flag is valid
00056       FL_DISPSTR_NOTEMPTY = 64, // for hasDisplayString(): whether the display string is not empty
00057     };
00058 
00059   private:
00060     cComponentType *componenttype;  // component type object
00061 
00062     short rngmapsize;  // size of rngmap array (RNGs>=rngmapsize are mapped one-to-one to physical RNGs)
00063     int *rngmap;       // maps local RNG numbers (may be NULL if rngmapsize==0)
00064 
00065     short paramvsize;
00066     short numparams;
00067     cPar *paramv;  // array of cPar objects
00068 
00069     cDisplayString *dispstr; // display string (created on demand)
00070 
00071     struct SignalData
00072     {
00073         simsignal_t signalID;
00074         cIListener **listeners; // NULL-terminated array
00075 
00076         SignalData() {signalID=SIMSIGNAL_NULL; listeners=NULL;}
00077         void dispose() {delete [] listeners;}
00078         bool addListener(cIListener *l);
00079         bool removeListener(cIListener *l);
00080         int findListener(cIListener *l);
00081         int countListeners();
00082         bool hasListener() {return listeners && listeners[0];}
00083         static bool gt(const SignalData& e1, const SignalData& e2) {return e1.signalID > e2.signalID;}
00084     };
00085 
00086     typedef std::vector<SignalData> SignalTable;
00087     SignalTable *signalTable; // ordered by signalID so we can do binary search
00088 
00089     // flags to speed up emit() for signals 0..63 when there are no or few listeners
00090     uint64 signalHasLocalListeners;    // bit[k]==1: signalID k has local listeners
00091     uint64 signalHasAncestorListeners; // bit[k]==1: signalID k has listener in parent or in any ancestor component
00092 
00093     // string-to-simsignal_t mapping
00094     static struct SignalNameMapping {
00095         std::map<std::string,simsignal_t> signalNameToID;
00096         std::map<simsignal_t,std::string> signalIDToName;
00097     } *signalNameMapping;  // must be dynamically allocated on first access so that registerSignal() can be invoked from static initialization code
00098     static int lastSignalID;
00099 
00100     // dynamic assignment of signalHasLocalListeners/signalHasAncestorListeners bits (64 of them) to signalIDs
00101     static std::vector<uint64> signalMasks;  // index: signalID, value: mask (1<<bitIndex), or 0xffff... for "unfilled"
00102     static int firstFreeSignalMaskBitIndex; // 0..63; 64 means "all sold out"
00103 
00104     // stack of listener lists being notified, to detect concurrent modification
00105     static cIListener **notificationStack[];
00106     static int notificationSP;
00107 
00108     // whether only signals declared in NED via @signal are allowed to be emitted
00109     static bool checkSignals;
00110 
00111   private:
00112     SignalData *findSignalData(simsignal_t signalID) const;
00113     SignalData *findOrCreateSignalData(simsignal_t signalID);
00114     void removeSignalData(simsignal_t signalID);
00115     void checkNotFiring(simsignal_t, cIListener **listenerList);
00116     template<typename T> void fire(cComponent *src, simsignal_t signalID, const uint64& mask, T x);
00117     void fireFinish();
00118     void signalListenerAdded(simsignal_t signalID, uint64 mask);
00119     void signalListenerRemoved(simsignal_t signalID, uint64 mask);
00120     void repairSignalFlags();
00121     bool computeHasListeners(simsignal_t signalID) const;
00122     void releaseLocalListeners();
00123 
00124   public:
00125     // internal: currently used by Cmdenv
00126     void setEvEnabled(bool e)  {setFlag(FL_EVLOGENABLED,e);}
00127     bool isEvEnabled() const  {return flags&FL_EVLOGENABLED;}
00128 
00129     // internal: invoked from within cEnvir::getRNGMappingFor(component)
00130     void setRNGMap(short size, int *map) {rngmapsize=size; rngmap=map;}
00131 
00132     // internal: sets associated cComponentType for the component;
00133     // called as part of the creation process.
00134     virtual void setComponentType(cComponentType *componenttype);
00135 
00136     // internal: adds a new parameter to the component; called as part of the creation process
00137     virtual void addPar(cParImpl *value);
00138 
00139     // internal: reallocates paramv (size must be >= numparams)
00140     void reallocParamv(int size);
00141 
00142     // internal: save parameters marked with "save-as-scalars=true"
00143     virtual void recordParametersAsScalars();
00144 
00145     // internal: has finalizeParameters() been called?
00146     bool parametersFinalized() const {return flags&FL_PARAMSFINALIZED;}
00147 
00148     // internal: has initialize() been called?
00149     bool initialized() const {return flags&FL_INITIALIZED;}
00150 
00151     // internal: used from Tkenv: find out if this module has a display string.
00152     // getDisplayString() would create the object immediately which we want to avoid.
00153     bool hasDisplayString();
00154 
00155     // internal: checks consistency of signal listener flags
00156     void checkLocalSignalConsistency() const;
00157     void checkSignalConsistency() const;
00158 
00159     // internal: clears per-run signals-related data structures; to be invoked before each simulation run
00160     static void clearSignalState();
00161 
00162     // internal: clears signal registrations; to be invoked on exit
00163     static void clearSignalRegistrations();
00164 
00165     // internal: allocates a signalHasLocalListeners/signalHasAncestorListeners bit index to the
00166     // given signal and returns the corresponding mask (1<<index); returns 0 if there are no more
00167     // free bit indices. Result is remembered and returned in subsequent calls (until clearSignalState())
00168     static uint64 getSignalMask(simsignal_t signalID);
00169 
00170     // internal: controls whether signals should be validated against @signal declarations in NED files
00171     static void setCheckSignals(bool b) {checkSignals = b;}
00172     static bool getCheckSignals() {return checkSignals;}
00173 
00174   protected:
00194 
00199     virtual void initialize(int stage) {if (stage==0) initialize();}
00200 
00206     virtual int numInitStages() const  {return 1;}
00207 
00212     virtual void initialize();
00213 
00218     virtual void finish();
00219 
00238     virtual void handleParameterChange(const char *parname);
00240 
00241   public:
00251     cComponent(const char *name = NULL);
00252 
00256     virtual ~cComponent();
00258 
00264     virtual void forEachChild(cVisitor *v);
00266 
00274     virtual void finalizeParameters();
00275 
00282     virtual cProperties *getProperties() const = 0;
00283 
00287     cComponentType *getComponentType() const;
00288 
00296     virtual const char *getNedTypeName() const;
00297 
00301     virtual bool isModule() const  {return false;}
00302 
00306     bool isChannel() const  {return !isModule();}
00307 
00313     virtual cModule *getParentModule() const = 0;
00314 
00319     cRNG *getRNG(int k) const  {return ev.getRNG(k<rngmapsize ? rngmap[k] : k);}
00321 
00327 
00331     virtual void callInitialize() = 0;
00332 
00337     virtual bool callInitialize(int stage) = 0;
00338 
00343     virtual void callFinish() = 0;
00345 
00348 
00352     virtual int getNumParams() const  {return numparams;}
00353 
00358     virtual cPar& par(int k);
00359 
00364     const cPar& par(int k) const  {return const_cast<cComponent *>(this)->par(k);}
00365 
00370     virtual cPar& par(const char *parname);
00371 
00376     const cPar& par(const char *parname) const  {return const_cast<cComponent *>(this)->par(parname);}
00377 
00382     virtual int findPar(const char *parname) const;
00383 
00387     bool hasPar(const char *s) const {return findPar(s)>=0;}
00389 
00406     static simsignal_t registerSignal(const char *name);
00407 
00412     static const char *getSignalName(simsignal_t signalID);
00413 
00419     void emit(simsignal_t signalID, bool b);
00420 
00426     void emit(simsignal_t signalID, long l);
00427 
00433     void emit(simsignal_t signalID, unsigned long l);
00434 
00440     void emit(simsignal_t signalID, double d);
00441 
00451     void emit(simsignal_t signalID, const SimTime& t);
00452 
00458     void emit(simsignal_t signalID, const char *s);
00459 
00465     void emit(simsignal_t signalID, cObject *obj);
00466 
00468     void emit(simsignal_t signalID, const cObject *obj) { emit(signalID, const_cast<cObject *>(obj)); }
00469 
00471     void emit(simsignal_t signalID, char c) {emit(signalID,(long)c);}
00472 
00474     void emit(simsignal_t signalID, unsigned char c) {emit(signalID,(unsigned long)c);}
00475 
00477     void emit(simsignal_t signalID, short i) {emit(signalID,(long)i);}
00478 
00480     void emit(simsignal_t signalID, unsigned short i) {emit(signalID,(unsigned long)i);}
00481 
00483     void emit(simsignal_t signalID, int i) {emit(signalID,(long)i);}
00484 
00486     void emit(simsignal_t signalID, unsigned int i) {emit(signalID,(unsigned long)i);}
00487 
00489     void emit(simsignal_t signalID, float f) {emit(signalID,(double)f);}
00490 
00492     void emit(simsignal_t signalID, long double d) {emit(signalID,(double)d);}
00493 
00501     bool mayHaveListeners(simsignal_t signalID) const {
00502         uint64 mask = getSignalMask(signalID);
00503         return (~signalHasLocalListeners & ~signalHasAncestorListeners & mask)==0; // always true for mask==0
00504     }
00505 
00513     bool hasListeners(simsignal_t signalID) const {
00514         uint64 mask = getSignalMask(signalID);
00515         return mask ? ((signalHasLocalListeners|signalHasAncestorListeners) & mask) : computeHasListeners(signalID);
00516     }
00518 
00528     void subscribe(simsignal_t signalID, cIListener *listener);
00529 
00534     void subscribe(const char *signalName, cIListener *listener);
00535 
00540     void unsubscribe(simsignal_t signalID, cIListener *listener);
00541 
00546     void unsubscribe(const char *signalName, cIListener *listener);
00547 
00553     bool isSubscribed(simsignal_t signalID, cIListener *listener) const;
00554 
00559     bool isSubscribed(const char *signalName, cIListener *listener) const;
00560 
00564     std::vector<simsignal_t> getLocalListenedSignals() const;
00565 
00569     std::vector<cIListener*> getLocalSignalListeners(simsignal_t signalID) const;
00571 
00578     cDisplayString& getDisplayString();
00579 
00583     void setDisplayString(const char *dispstr);
00584 
00589     void bubble(const char *text);
00591 
00594 
00598     void recordScalar(const char *name, double value, const char *unit=NULL);
00599 
00603     void recordScalar(const char *name, SimTime value, const char *unit=NULL) {recordScalar(name, value.dbl(), unit);}
00604 
00610     void recordStatistic(cStatistic *stats, const char *unit=NULL);
00611 
00617     void recordStatistic(const char *name, cStatistic *stats, const char *unit=NULL);
00619 };
00620 
00621 NAMESPACE_END
00622 
00623 
00624 #endif
00625 
Generated on Tue Dec 2 11:16:27 2014 for OMNeT++ Simulation Library by  doxygen 1.6.3