API-Changes =========== This file summarizes the changes in OMNeT++/OMNEST across releases that affect backwards compatibility, to help you port models to more recent versions of the simulation framework. This file only describes changes that affect compiling and running models; for other changes or new features see WHATSNEW, and per source directory ChangeLog files. Legend: (+) new feature (!!!) incompatible change (old code will not compile or work as previously) (!) incompatible but minor change (change on a rarely used feature) (-) method/class became deprecated (possibly with a better replacement feature becoming available), or a method/class was renamed and a corresponding compatibility #define was added ('#define oldname newname') (x) removed a deprecated method, class or compatibility #define (i) information OMNeT++ 6.1 ~~~~~~~~~~~ (+) SimTime: Added constructors from primitive integer types: SimTime(short), SimTime(unsigned short), SimTime(int), etc. (!) SimTime: Removed SimTime(int64_t value, SimTimeUnit unit) constructor, and added similar constructors for double and all primitive integer types instead. Caveat: Expressions like SimTime(3.5, SIMTIME_MS) previously invoked the SimTime(int64_t value, SimTimeUnit unit) constructor, leading to precision loss and silently constructing a value of 3ms instead of the expected 3.5ms. This library change rectifies the problem, but, by fixing what was probably an error in the model code in the first place, it may cause simulation programs to behave differently. (!) SimTime: SimTime(cPar&) constructor was changed to SimTime(const cPar&). (-) cComponent: getAncestorPar() deprecated. Its use, and in general, accessing the containing modules' parameters, constitutes bad practice. (!) cConfigurationEx: Added the isAbstractConfig() pure virtual method. Most models are not affected; but if the model includes a custom configuration class that directly inherits from cConfigurationEx, it may need to be adjusted by adding an implementation of this method, otherwise the class becomes an abstract class. (!) cEnum: All methods that take or return the numeric value of an enum name now expect or return intval_t a.k.a. int64_t instead of int. (-) cEnum: The bulkInsert() method was deprecated, and the constructor with a similar vararg interface was deleted. Instead, add values one-by-one using the insert() method, or use one of the several Register_Enum() macro variants. (!) Register_Enum(): Implementation has changed, with the side effect that the first argument (the enum type name) must now be valid. Previously it was not used, so any identifier was accepted. (+) Added the Register_Enum_WithVar() and Register_Enum_Custom() enum registration macros. (-) Register_Enum2() became deprecated. (+) ContextType enum: Added new value CTX_SCHEDULER. The context being set to CTX_SCHEDULER indicates that the code is being run in the context of the simulation's the event scheduler. (+) cPar: Added getOwnerComponent() convenience function. (+) cPar: Added a resetEvalContext=true argument to parse(). (+) cOutVector: Added constructor that accepts vector attributes, too: cOutVector(const char *name, const opp_string_map& attributes). (+) cOutVector: Added methods setAttributes(), setAttribute(), registerVector(). (!) cOutVector: In order to make empty vectors show up in the output vector file, either a call to registerVector() must be added, or the code code must be changed to use new methods that include vector registration, such as the 2-arg constructor or setAttributes(). (!) cEnvir: interface change: Removed setVectorAttribute(), added attributes map arg to registerOutputVector() instead. Most models are not affected; but if the model contains a custom environment class that directly inherits from cEnvir, it may need to be adjusted. (!) cEnvir: interface change: added getOutputStream(). (!) cFingerprintCalculator: interface change: addVectorResult() was split to registerVectorResult() and a (changed) addVectorResult(). Most models are not affected; but if the model includes a custom fingerprint computing class that directly inherits from cFingerprintCalculator, it may need to be adjusted. (+) cResultFilter: Added removeDelegate(); keep the order of delegates. (!) cXMLElement: Now it subclasses from cOwnedObject instead of cObject. (+) cPar: New cPar methods: getSourceLocation(), getBaseDirectory(). (!) cEnum: getNameValueMap() now returns const reference to an internal data structure instead of returning a copy. (!) cKSplit: Added 'const' qualifiers to CritFunc and DivFunc function signatures OMNeT++ 6.0 ~~~~~~~~~~~ (!) cVisitor: Return type of visit(cObject *obj) method changed from void to bool. Implementations can return false to indicate that the called forEachChild() method may skip calling it for further child objects. EndTraversalException, which used to serve a similar purpose, was removed. The motivation was that using exceptions for control flow is not recommended in C++, and it also made it difficult to use some debuggers. (!) cIEventlogManager: stopRecording() renamed to resume(), stopRecording() to suspend(); added endRun(). (!!!) cPar: Setting the parameter will now result in a call to the component's handleParameterChange() method during initialize() as well. At the same time, the handleParameter(nullptr) call at the end of the initialization was removed. In model code, handleParameterChange() needs to be implemented carefully, being aware that the module may not have completed initialization yet. Also: if an existing model relied on handleParameter(nullptr) being ported, it needs to be changed. (!!!) cValue: doubleValue()/intValue() will now throw an exception when called on a value which has a measurement unit. Call either doubleValueInUnit()/ intValueInUnit(), or doubleValueRaw()/intValueRaw() plus getUnit() to read the value from a cValue object with a measurement unit. (!) cSoftOwner: removed setPerformFinalGC()/getPerformFinalGC(). It was meant for internal use, and pretty much unused by model code. (!) Renames related to the ownership management mechanism: - cDefaultOwner -> cSoftOwner - defaultOwner -> owningContext - cOwnedObject::setDefaultOwner() -> setOwningContext() - cOwnedObject::getDefaultOwner() -> getOwningContext() - defaultList (global variable) -> globalOwningContext - cSoftOwner::defaultListSize() -> getNumOwnedObjects() - cSoftOwner::defaultListGet() -> getOwnedObject() (!) cSoftOwner: defaultListContains() removed. (There were no known usages.) (+) cObject: Added getClassAndFullPath() and getClassAndFullName(). They are mostly useful in logging and error messages. (+) cAbstractTextFigure: Added getAlignment() ad setAlignment() method; cFigure: added Alignment enum. (+) cFigure::RGBA: the Added RGBA(const Color& color, double opacity=1) constructor, and the toAlpha() method. (+) cFigure::Color, cFigure::Font, cFigure::RGBA: Added missing copy constructors. (+) cHasher: Added add(const std::string&). (+) cHasher: Added operator<< for feeding values into the hasher. (!) cHasher: Due to a bugfix in add(const char *), fingerprints that involve hashing strings have changed. (!) cFigure: The protected internal methods hashGeometry() and hashGeometryRec(), have been removed, and replaced with the new hashTo() method. (+) cCanvas: Added getHash(). (-) Removed USE_OMNETPP4x_FINGERPRINTS. (+) cComponent: Added preDelete(), a method that can be overridden by user code to simplify network or module deletion in a complex simulation. (+) Added opp_component_ptr<T>, which is a smart pointer to a cComponent. When the respective component is deleted, the pointer becomes nullptr. (!) cIOutputScalarManager: Recording methods changed to return a bool, indicating whether the value was actually recorded. This was done for consistency with cIOutputVectorManager's record method. (!) IdentityFilter: do not convert signal values to numeric. (!) cObject: Added printOn() method, and changed stream output (<<) operators to delegate to that. The new operator<< is template-based which makes it applicable to all subclasses of cObject, and both references and pointers. The old operator<< for cOwnedObject was removed. (!!!) cIListener destructor changed to unsubscribe from all places it is currently subscribed to, instead of insisting on being already unsubscribed. (!) cMessage: Changed isMessage() from private to protected. (+) Added DemuxFilter, a result filter that demultiplexes its input to several outputs. (+) cResultRecorder: added setDemuxLabel(). (+) cResultListener: Added clone(). (!) cResultListener: receiveSignal() methods changed from protected to public. (+) cSimpleModule: Added scheduleAfter(), rescheduleAt() and rescheduleAfter(). (!) cSimulation: Process ordinary events via cMessage::execute(). cMessage:: execute() delegates to the (newly created) cSimpleModule::doMessageEvent() method. (!) cMessage: execute() changed from private to protected. (+) Introduced SendOptions as a way to pass options to send() and its variants in cSimpleModule. send() and sendDirect() now accept a SendOptions; sendDelayed() and the sendDirect() variant with delay and duration now convert their extra args to a SendOptions, and delegate to the "standard" send()/sendDirect() versions. This change is part of the "transmission updates" API. (+) cDatarateChannel now allows overriding the packet duration computed by the channel. To do so, supply a duration to send() via SendOptions. This change is part of the "transmission updates" API. (!) cDatarateChannel: non-packet messages now pass through without interfering with packets. This change is part of the "transmission updates" API. (+) cDatarateChannel: added setMode(), which controls whether the channel allows multiple concurrent transmissions, and if so, how. Available modes are SINGLE, MULTI and UNCHECKED. The operation and result of the isBusy() and getTransmissionFinishTime() methods report now depend on the channel mode. (!) cGate::deliver() and cModule::arrived() signature change: SendOptions was added to the argument list. This change is part of the "transmission updates" API. (!) cChannel::processMessage() signature change: SendOptions was added to the argument list; result_t was renamed cChannel::Result, and it is no longer an output parameter but a proper return value. Also, result now contains remainingDuration. This change is part of the "transmission updates" API. (+) cDatarateChannel: datarate is now optional. Set it to 0 or NaN (nan in NED) to leave it unspecified. This change is part of the "transmission updates" API. (-) cChannel, cDatarateChannel: forceTransmissionFinishTime() deprecated. Model code should use the new SendOptions::updateTx() instead. This change is part of the "transmission updates" API. (!) cGate: setDeliverOnReceptionStart() renamed to setDeliverImmediately(). This change is part of the "transmission updates" API. (+) cSimpleModule: Added setTxUpdateSupport() and supportsTxUpdates(). This change is part of the "transmission updates" API. (+) cPacket: Added getRemainingDuration() and isReceptionEnd(). This change is part of the "transmission updates" API. (!) cEnvir method signature changes: beginSend() takes SendOptions as additional argument; messageSendHop() and messageSendDirect() take cChannel::Result instead of separate args. This change is part of the "transmission updates" API. (!) cPacket: str() overhauled to reflect new fields and uses. (!) cModule, cSimulation: getModuleByPath() now always returns a valid (non-null) module pointer. Therefore, it no longer accepts an empty string, a path with syntax error, or path to an nonexistent module; such inputs result in an exception being thrown. (+) cModule, cSimulation: Added findModuleByPath(), which can be used instead of getModuleByPath() in cases where the module may not exist. (+) cModule: Modules may now be created and deleted (including self-deletion) during initialization. (+) cEvent: Added isPacket() utility method. (+) cChannel: Added isDisabled(). Before that, only cDelayChannel and cDatarateChannel had this method; now those override cChannel's. (!) cParsimCommunications: init() method signature change (added numPartitions argument). (+) cConfiguration: Added getConfigValue()/getPerObjectConfigValue() overloads that take cConfigOption pointer instead of the option name. (x) Removed the PI define. Use M_PI instead. (!) eventnumber_t, intval_t, uintval_t are now in the omnetpp namespace. (They were outside by mistake.) (!) Require at least C++14 for OMNeT++. (+) cConfigurationEx: getKeyValuePairs() made smarter with an extra flags parameter be able to handle the various use cases. (-) cConfigurationEx: Removed getParameterKeyValuePairs(), use getKeyValuePairs() with flags=cConfigurationEx::FILT_PARAM instead. (+) cConfiguration: Added new config variable names as constants: CFGVAR_DATETIMEF, CFGVAR_ITERATIONVARSD. (+) cObject: getDescriptor() made public API. (+) Added cValueArray and cValueObject classes, to be used with JSON-style parameter values. (+) cPar: add OBJECT as parameter type. New constant: cPar::Type::OBJECT. New methods: setObjectValue(), objectValue(), operator=(cObject*), operator cObject*. (!) cDefaultList renamed to cDefaultOwner. (+) takeAllObjectsFrom() moved from cDefaultList to cObject. (+) isSoftOwner() moved from cOwnedObject to cObject. (+) cClassDescriptor: Added methods setFieldArraySize() and setFieldStructValuePointer(). (!) cClassDescriptor: setFieldValueAsString(), setFieldArraySize(), setFieldStructValuePointer(): Changed return type from void to bool. (They now report errors via exceptions instead of returning false.) (+) cPolyline, cPolygon: Added setNumPoints(). (+) cNedValue: added type 'OBJECT'. Type 'XML' became a deprecated synonym of 'OBJECT'. (!) cNedValue renamed to cValue. (cNedValue still exists as a compatibility typedef.) (+) Added NedFunctionExt, which is like NedFunction, but takes cExpression::Context * instead of Component * as context argument. (+) cNedFunction: Added constructor which accepts NedFunctionExt instead of NedFunction. (+) cNedFunction::invoke(): type of first argument (context) changed from cComponent * to cExpression::Context *. (+) cComponentType: added getSourceFileDirectory(). (!) cExpression::Context: added baseDirectory. (+) cPar::parse(): added optional baseDirectory argument (+) cFigure::Point: Added getAngle(). (!) intpar_t renamed to intval_t. Affects cPar, cNedValue, cExpression, etc. (+) Added uintval_t. (!) cListener: receiveSignal() overloads for the long and unsigned long data types have been changed to use intval_t and uintval_t instead. Signal listener classes that override those methods will need to be updated. (!) SimsignalType enum: added SIMSIGNAL_INT and SIMSIGNAL_UINT, deprecated SIMSIGNAL_LONG and SIMSIGNAL_ULONG. (!) cITimestampedValue: constructors that take long and unsigned long were changed to take intval_t and uintval_t instead. Also, the methods longValue() and unsignedLongValue() were deprecated, and methods intValue() and uintValue() were added instead. (!) cResultFilter: fire() method overloads for the long and unsigned long data types have been changed to use intval_t and uintval_t instead. Result filter classes that override those methods will need to be updated. (+) cHistogram methods getBinEdges(), getBinValues() added to base class cAbstractHistogram. (+) Added cPostModuleBuildNotification. (+) Added cPostComponentInitializeNotification. (+) Added cFingerprint::addVisuals(). (+) Added cFigure::hashGeometry(). (+) cEnvir: Added methods recordComponentType(), recordParameter(), getConnectionLine(). (+) cModule::ChannelIterator: added postfix ++ and -- operators. (+) cMatchExpression: Change in the expression syntax: 'field(pattern)' should now be written as 'field =~ pattern'. (+) Added cSimulation::callRefreshDisplay(). (!) cDynamicExpression: Added inner classes: IResolver, ResolverBase, SymbolTable; added parse() overloads that take an IResolver or a symbol table; added parseNedExpr() (!) cDynamicExpression: Removed inner classes Elem, Functor, and enum OpType; removed setExpression() method. (+) cSimulation: Added exclusionPath parameter to loadNedSourceFolder(). (+) cResultFilter: Added hasDelegate(). (!) cComponent: Disallow emitting nullptr in the const char * overload of emit(). (!) cModuleType, cChannelType: protected methods changed to be internal: createModuleObject(), addParametersAndGatesTo(), setupGateVectors(), buildInside(), instantiateModuleClass(). (-) cIListener: removed support for the WITH_OMNETPP4x_LISTENER_SUPPORT macro and the receiveSignal() overloads it added (those without the cObject *details argument). (-) cExpression, cDynamicExpression, cParImpl: Removed method containsConstSubexpressions() and evaluateConstSubexpressions(). (-) cSimpleModule: Removed deprecated legacy constructor. (-) Removed cStatistic deprecated methods getWeights(),collect2(), random(), clearResult(). Replacements: getSumWeights(), collectWeighted(), draw(), clear(). (-) Removed cAbstractHistogram (ex-cDensityEstBase) deprecated methods: isTransformed(), transform(), getNumCells(), getBasepoint(), getCellValue(), getCellPDF(), getUnderflowCell(), getOverflowCell(), getCellInfo(). Replacements: binsAlreadySetUp(), setUpBins(), getNumBins(), getBinEdge(), getBinValue(), getBinPDF(), getNumUnderflows(), getNumUnderflows(), getBinInfo(). (-) Removed cFigure/cCanvas deprecated methods: addFigureAbove(), addFigureBelow(). Replacements: insertBelow(), insertAbove(). (-) Removed cPar/cNedValue deprecated method longValue(); use intValue() instead. (-) Removed cObject deprecated method info(), detailedInfo(); use str() instead. (-) Removed cModule deprecated method size(); use getVectorSize() instead. (-) Removed deprecated operator() of iterator classes in cArray, cModule, cQueue. Use operator* instead. (-) Remove cHistogram deprecated methods: setRangeAuto(), setRangeAutoLower(), setRangeAutoUpper(), setNumCells(), setCellSize(). Replacements: setNumPrecollectedValues()+setRangeExtensionFactor()+setRange(), setNumBins(), setBinSize(). (-) Removed deprecated cDensityEstBase class. Replacement: cAbstractHistogram. (-) Removed deprecated cWeightedStdDev class. Use cStddev in weighted mode instead. (-) Removed deprecated timeval_*() functions: timeval_usec(), to_timeval(), timeval_add(), timeval_addto(), etc. Use opp_get_monotonic_clock_usecs() or opp_get_monotonic_clock_nsecs() instead, and perform arithmetic in int64_t. (-) Removed obsolete histogram classes: cVarHistogram, cLegacyHistogram, cLongHistogram, cDoubleHistogram. Use cHistogram with the appropriate histogram strategy instead. OMNeT++ 5.7 ~~~~~~~~~~~ No API change. OMNeT++ 5.6 ~~~~~~~~~~~ (+) SimTime: Added the fromRaw() method. (+) cGate: Added the isGateHalf() and getOtherHalf() methods. (!) The deleteModule() method was moved from cSimpleModule to cModule. (+) The deleteModule() method's functionality has has been extended: it is now allowed for a running module to delete itself, also as part of a module tree. (+) cLabelFigure: Added setAngle() and getAngle() methods. OMNeT++ 5.5 ~~~~~~~~~~~ (+) API in resultfilters.h and resultrecorders.h made public: Filters: WarmupPeriodFilter, CountFilter, TotalCountFilter, ConstantFilter, Constant0Filter, Constant1Filter, IdentityFilter, SkipNanFilter, SumFilter, MeanFilter, MinFilter, MaxFilter, AverageFilter, TimeAverageFilter, RemoveRepeatsFilter, PacketBytesFilter, SumPerDurationFilter, TimeFilter, ErrorNanFilter, CountNanFilter Recorders: VectorRecorder, CountRecorder, LastValueRecorder, SumRecorder, MeanRecorder, Minrecorder, MaxRecorder, AverageRecorder, TimeAverageRecorder, StatisticsRecorder, StatsRecorder, HistogramRecorder, TimeWeightedHistoramrecorder, PSquareRecorder, KSplitRecorder, ErrorNanRecorder (+) cKSplit, cPSquare: added clear() method. (+) cHistogram: Now collects the number of positive and negative infinity values. getNumNegInfs(), getNumPosInfs(), getNumNegInfSumWeights(), getNumPosInfSumWeights() (x) cSimpleModule: Removed a legacy, deprecated constructor. cSimpleModule(const char *dummy1, cModule *dummy2, unsigned stacksize) (+) cModule: Added containsModule() method. (+) cComponent: Added intuniformexcl() returning a random integer with uniform distribution over [a,b) (i.e. [a,b-1]). (+) SimTime: Added preciseDiv() for a precise division of an integer and a simulation time. (+) cQueue, cPacketQueue: added a constructor that accepts a comparator object (not just a function). (+) Register_ResultFilter2(), Register_ResultRecorder2(): new macros that allow for registering result filters and recorders together with a description string. (!) cXMLElement: internally used constructor now ignores the source location parameter. It should be set separately using the setSourceLocation() method. OMNeT++ 5.4 ~~~~~~~~~~~ (+) SimTime: added ustr() (+) cNedValue: convertToDouble() made public (!) cExpression, cDynamicExpression: evaluate(), boolValue(), intValue() and other evaluator methods now internally delegate to similar functions that take a Context *context pointer instead of cComponent *. (!) cEnvir: attachDebugger() replaced with ensureDebugger() (!) NedSupport namespace renamed to lowercase (nedsupport) for consistency (+) nedsupport: added Exists and Typename classes OMNeT++ 5.3 ~~~~~~~~~~~ (!) cResultListener is now also public cObject (+) cKSplit: Added support for weighted case (2nd constructor arg: bool weighted=false) (!) Renamed cDensityEstBase to cAbstractHistogram. (Compatibility typedef added.) (!) cObject: default parsimPack/parsimUnpack implementations to throw E_CANTPACK exception (!) Renamed several methods in cStatistic and subclasses: - cHistogram::HistogramMode -> cHistogram::Mode - getWeights() -> getSumWeights() - collect2() -> collectWeighted() - transform() -> setUpBins() - isTransformed() -> binsAlreadySetUp() - clearResult() -> clear() - getNumCells() -> getNumBins() - getBasepoint(k) -> getBinEdge(k) - getCellValue(k) -> getBinValue(k) - getCellInfo(k) -> getBinInfo(k) - getCellPDF(k) -> getBinPDF(k) - getUnderflowCell() -> getNumUnderflows() - getOverflowCell() -> getNumOverflows() Old names are still available as deprecated methods. (!) cHistogram replaced with a new implementation. Existing cHistogram class renamed to cLegacyHistogram, to make room for new implementation while retaining old class for users who rely on its exact behavior. (+) Added new cHistogram, and cHistogramStrategy classes. Motivation: There were too many histogram classes that really only differred in the way histogram bins are stored and set up initially: cHistogram, cLongHistogram, cDoubleHistogram, cVarHistogram. It is better to use composition instead of inheritance, and express bin layouting as a histogram setup strategy into separate (polymorphic) class. To simplify code, merge all histogram classes (cHistogramBase, cHistogram, cVarHistogram, cLongHistogram, cDoubleHistogram) into one, cHistogram, which explicitly stores the bin breaks as a double array. The only difference between them is the setup policy, which can be factored out to separate class. cVarhistogram can now be just another setup policy. The precollectedValues array also becomes internal matter of respective setup polici(es). (!) Removed transient detection and result accuracy detection classes (!) cDynamicExpression: added support to perform computations in integers: - Integers are represented as intpar_t. - Integers with units are now possible. When adding integer quantities with different units, care is taken so that the result can be represented in integer without precision loss. E.g. 1km-1m results in 999m (and not 0.999km or 0km). - Arithmetic operations (+,-,*,%,^): if both arguments are integers, computation is performed using integer arithmetic and result is integer; if one is integer and the other is double, the integer one is promoted to double. - Division: always performed in double and the result is also double. - Shift operators (<<,>>): requires integer arguments. Arbitrary integers are accepted as 2nd argument; negative values cause shifting in the opposite direction. - Exponentiation (^): if both arguments are integers, it performs precise computation using integer multiplications, and negative exponent causes an error. - Integer overflows are reported as errors. - There is no implicit conversion from double to integer, as it incurs precision loss. Use the int() operator to cast. - Conversion from integer to double is implicit, as long as the double can represent the integer precisely (practically for <= 52-bit integers). If the implicit conversion would cause precision loss, it is reported as an error. Use the double() operator to ignore the precision loss. (+) NED functions (Register_NED_Function()): Added support for integers with measurement unit: use "intquantity" as type in the function signature. (!) cNedValue: added INT type (!) cEnvir: Add getZoomLevel(). Access to the zoom level in the GUI sometimes allows better visualization. (!) Renamed cNEDValue, cNEDFunction, NEDFunction, cNEDMathFunction to cNedValue, cNedFunction, NedFunction, cNedMathFunction (NED->Ned). Old names can still be used via compatibility typedefs. (!) cMessage: setControlInfo() made virtual (!) cNEDValue: similar changes as to cPar: use intpar_t instead of long; renamed longValue() to intValue() and setLongValue() to setIntValue(); renamed enum values (DBL->DOUBLE, STR->STRING); added overflow check to integer cast operators; added conversions for the long long and unsigned long long types as well. (!) cPar: renamed longValue() to intValue(), setLongValue() to setIntValue(), cLongParImpl to cIntParImpl, and LONG (enum value in cPar) to INT. Similarly named methods in cExpression, cParImpl were renamed too. The old names can still be used but cause deprecation warnings. (!) cPar: Integer cast operators (operator int(), operator unsigned int(), operator short(), etc.) now check for overflow. That is, if the value doesn't fit into the target integer type, a runtime error will be raised. Until now, such data losses were ignored. BEST PRACTICE: For the above reason, cast operators should now be preferred over .intValue()/.longValue(): int numBytes = par("numBytes").longValue(); // UNSAFE: implicit cast, see below int numBytes = par("numBytes"); // SAFE: operator int() raises error when value overflows In the first example when .longValue() is used, the compiler emits an unchecked cast from intpar_t to int, so overflows go undetected. In the second case, the compiler will generate a call to cPar's operator int() which performs overflow check. (!) cPar: use intpar_t (currently an alias of int64_t) instead of long int to represent integers. The main motivation is that long is only 32 bits on some platforms (namely on Windows). cExpression, cDynamicExpression, and the cParImpl classes are affected too. cPar: added conversion operators to/from the "long long" and "long long int" types so that 64-bit value can be accessed on Windows as well. (Note: intpar_t could not be added because it would conflict with "long" on most platforms.) (!) cMessagePrinter: Extended with tags and column names. As part of that, printMessage() argument list was extended with a const Options *options argument. New methods: getSupportedTags(), getDefaultEnabledTags(), getColumnNames(). OMNeT++ 5.2 ~~~~~~~~~~~ (!) Figure classes: zIndex is now additive: the effective zIndex is the sum of the zIndex values of the figure and all its ancestors up to the root figure. This provides more flexibility, as the figure tree is no longer constrained by stacking order. (+) cFigure: added getEffectiveZIndex(). (+) Figure classes: Added cPanelFigure that allows for creating visual elements that are not affected by zooming. (+) cStddev: added support for weighted statistics. To make a weighted cStddev, pass weighted=true in the constructor. The weighted-ness of an cStddev instance cannot be changed afterwards. getMean() and getStddev() now return the weighted mean / stddev if the object is weighted. Note: getSum() and getSqrSum() are not available when collectecting weighted statistics (they throw an exception). (-) Deprecated cWeightedStddev, use cStddev with the weighted=true setting instead. Temorarily, cWeightedStddev has been reimplemented as a trivial subclass of cStddev with weighted=true. (!) cWeightedStddev: getSum() and getSqrSum() methods are no longer available, due to the deprecated cWeightedStddev class having been temporarily reimplemented as a trivial subclass of cStddev. (+) Histogram classes: added support for weighted statistics to histogram classes (cHistogramBase and subclasses: cHistogram, cVarHistogram, cLongHistogram, cDoubleHistogram). Pass weighted=true to the constructor to create weighted versions. To support weighted histograms, the data type of bin values were changed from int to double; they now store sum of weights instead of observation counts. The unweighted case is treated simply as a special case of weighted where all weights are 1.0. (+) New cDensityEstBase methods: getUnderflowSumWeights(), getOverflowSumWeights(). They return sum of weights for observations that are outside the histogram range. Note: the slightly misnamed getUnderflowCell()/getOverflowCell() methods that return overflow/underflow counts are still available. (i) cOsgCanvas: Refactoring necessary for allowing the OSG Viewer to be factored out from Qtenv into as separate support library, loaded on demand at runtime. The simulation kernel kernel (and cOsgCanvas) now does NOT depend on the OSG libraries: does not include OSG header files at all, and does not reference any symbols in the OSG libraries. cOsgCanvas now treats osg::Node* as opaque pointers, no attempt is made to dereference it. cOsgCanvas now performs osg::Node reference counting via cEnvir's new refOsgNode()/unrefOsgNode() methods instead of Node's methods. (+) cModule::getOsgCanvas() is now always available (never throws "No OSG" exception). This is a direct consequence of the change above. (!) cOsgCanvas: arg/return value of setEarthViewpoint()/getEarthViewpoint() have been changed from osgEarth::Viewpoint to cOsgCanvas::EarthViewpoint, a similar new class. This change was made because cOsgCanvas now cannot include or link with any OSG code, see above. (!) To use the cObjectOsgNode class, you must explicitly include the omnetpp/osgutil.h header file into your sources. It is no longer included in the omnetpp/omnetpp.h file. (+) opp_string: Added operator==() OMNeT++ 5.1 ~~~~~~~~~~~ (!!!) cObject and subclasses: renamed info() to str(). A deprecated info() that delegates to str() was added back for compatibility. See include/omnetpp/ ChangeLog for more information. (!!!) Use the new Register_Figure(NAME, CLASSNAME) macro instead of Register_Class() to register custom figure classes. (+) Added Register_Figure(NAME, CLASSNAME) macro. (+) Canvas: added setPosition(position, anchor) to the cArcFigure, cRectangleFigure, cOvalFigure, cRingFigure, and cPiesliceFigure classes. (+) cFigure: added refreshDisplay() method that can be overridden to implement self-refreshing figures. (+) cFigure: added setZIndex()/getZIndex(). In @figure, "zIndex" replaces "childZ" which was only used at parse time but not stored in figures afterwards. (!) cFigure: change in the behavior of the raiseAbove()/lowerBelow()/raiseToTop()/ lowerToBottom() methods: with the appearance of zIndex, they need to update the Z-index as well to be able to do their jobs. (+) cFigure: added insertAfter()/insertBefore(), isAbove()/isBelow() methods that take zIndex into account. (-) cFigure: deprecated addFigureAbove()/addFigureBelow(); use insertAfter()/ insertBefore() instead. (+) cAbstractTextFigure: added setHalo() method. (+) cFigure: added setTooltip() and setAssociatedObject(). (!) cPathFigure: some path item classes renamed (HorizLineTo/VertLineTo to HorizontalLineTo/VerticalLineto; same for corresponding ...Rel classes). (+) cAbstractImage/cAbstractText: added getBounds() method. (+) cImageFigure: added getImageNaturalWidth()/getImageNaturalHeight(). (+) cCanvas: added setAnimationSpeed(), holdSimulationFor() that control smooth animation. (+) cEnvir: added getAnimationTime(), getAnimationSpeed(), getRemaining- AnimationHoldTime() methods that can be used in implementing smooth animation. (+) cModule: added setBuiltinAnimationsAllowed(bool enabled) and getBuiltinAnimationsAllowed() methods. (+) cEnvir: added appendToImagePath(), loadImage() to allow custom images to be loaded. (+) cEnvir: added getSubmodulePosition(). (+) cEnvir: added getImageSize() and getTextExtent() methods to support related figure functionality. (!) cEnvir: messageSendHop(): added "discard" parameter. (!) cEnvir: removed messageSent_OBSOLETE(), a relic from OMNeT++ 3.x. (!) cStaticFlag: isSet() method renamed to isMainRunning(). (+) cModule: getModuleByPath() now accepts "<root>" to mean the toplevel module. (Previously there was no syntax accessing the toplevel module apart from spelling out its module name.) (!) cEnvir interface changes: - askYesNo() no longer has a printf-style arg list - askyesno() (lower-case, protected version) removed - putsmsg() removed - alert() added as replacement for putsmsg() (!) cIEventlogManager: added getFileName() for consistency with other output file recorder classes. (!) cConfiguration: getter methods made const. (+) cConfigOption: added public static find() and get() lookup methods. (!) cConfigurationEx: unrollConfig() signature change to allow it return more information: return type changed from std::vector<std::string> to std::vector<RunInfo>; 'bool detailed' argument removed. (!) cConfigurationEx: added getKeyValuePairs() method. (!) Removed ${iterationvars2} inifile variable and corresponding CFGVAR_ITERATIONVARS2 symbol. (+) Added ${iterationvarsf} inifile variable and corresponding CFGVAR_ITERATIONVARSF symbol. (+) SimTime: added SIMTIME_AS (= -18) to SimTimeUnit enum. (!) cISimulationLifecycleListener: destructor removes the listener from cEnvir. (Has no effect is it was already deregistered.) (+) cComponentType: added getNedSource() method. (!) cPacket: getDisplayString() changed to fall back to the encapsulated packet's display string. (!) cXMLElement now subclasses from cObject. (+) cXMLElement: added str() and getXML() methods. (!) cXMLElement: debugDump() was removed; use EV << element->getXML() instead. (!) cObject and subclasses: detailedInfo() method removed with no replacement; see include/omnetpp/ChangeLog for more information. (+) Selection of coroutine library (USE_WIN32_FIBERS/USE_POSIX_COROUTINES/ USE_PORTABLE_COROUTINES) moved to platdefs.h, and now can be overridden from the compiler command line (-D). (+) cProperty: getValue(key,index) now has a default value for the key argument too. (+) cEvent: added shouldPrecede() method. (!) cComponent: mayHaveListeners() now has a constant cost but may return false positive, due to change implementation strategy. See sim/ChangeLog for details. (!) cClassDescriptor: added getFieldDynamicTypeString() that returns the dynamic type of an object. (!) cModule: buildInside() return type changed from int to void (+) cModule: arrived() made public. Overriding arrived() makes it possible to do custom processing at the destination module of a send() call immediately, still within the send() call. (+) cResultListener: added getClassName() and str() methods. Rationale: it was not added to cIListener, because multiple inheritance with cObject (e.g. module classes that are also listeners) would cause compile errors in existing code due to method ambiguity. (!) cResultListener, cResultFilter, cResultRecorder: reduced the visibility (public -> protected) of inherited processing methods. (!) cResultRecorderDescriptor renamed to cResultRecorderType; cResultFilterDescriptor renamed to cResultFilterType (Reason: collision with message compiler generated descriptor classes). (+) Added cStatisticBuilder internal class, as part of the change where setting up statistics recording was moved from EnvirBase into the sim. kernel. (+) cFigure: added insertBelow() / insertAbove(). (+) cFigure: parse(cProperty*) and getAllowedPropertyKeys() are now public API. (+) Added opp_get_monotonic_clock_usecs(). This should be used for measuring wall-clock intervals instead of gettimeofday() which is not monitonic. (!) Return type of send() and snapshot() methods changed to 'void' (!) OppErrorCode renamed to ErrorCode (+) opp_string: added str() method. OMNeT++ 5.0 ~~~~~~~~~~~ (!!!) OMNeT++ classes are now in the "omnetpp" namespace. Models need to be modified in order to compile, e.g. by adding "using namespace omnetpp". If you don't want to change the model source code, define the AUTOIMPORT_OMNETPP_NAMESPACE macro on the compiler command line (add -DAUTOIMPORT_OMNETPP_NAMESPACE to CFLAGS), which will basically add the using namespace directive at the end of <omnetpp.h>. (!!!) ev << is no longer legal, use EV << instead. (!!!) ev.printf() was removed, use the stream API (EV <<) instead. (!!!) Random variate generation functions (normal(), etc.) signature change: trailing "int rng" (RNG index of context module) argument changed to cRNG*, and moved to the front. Motivation: break the functions' dependence on the context module. Affected functions: uniform(), exponential(), normal(), truncnormal(), gamma_d(), beta(), erlang_k(), chi_square(), student_t(), cauchy(), triang(), weibull(), pareto_shifted(), intuniform(), binomial(), geometric(), negbinomial(), poisson(), intrand(), dblrand(). (!!!) Random variate generation functions (normal(), etc; see above) with their original signatures have been added to cComponent as members. Motivation: convenience for users; lessen the impact of signature change. (!!!) Revised cScheduler interface. The main methods in cScheduler are now takeNextEvent() and guessNextEvent(). (!!!) Removed the "simulation" and "ev" macros, to reduce pollution of the global namespace; use the new getSimulation() and getEnvir() functions instead. (!!!) Fingerprint computation has changed. To compute OMNeT++ 4.x fingerprints, compile OMNeT++ and models with USE_OMNETPP4x_FINGERPRINTS. (!!!) Signal listener interface change: A cObject *details (default-nullptr) argument has been added to emit() methods, and consequently, to cIListener::receiveSignal() methods as well. The motivation was to allow simulation models to provide some extra information with primitive data types (double, long, etc) they emit, without the need to switch over to emitting cObject altogether. Compiling OMNeT++ and models with WITH_OMNETPP4x_LISTENER_SUPPORT defined will set up cIListener to delegate to the old methods, so existing listeners will work. (!!!) Result filter/recorder interface change: Related to the listener interface change, a cObject *details argument has been added to several cResultFilter and cResultRecorder methods as well. (x) Removed double-simtime support (WITH_DOUBLE_SIMTIME) (!) Removed WITHOUT_CPACKET feature (it was a compatibility macro to help code migration from OMNeT++ 3.x to 4.0) (!) cEnvir::recordEventlog was not in use by simkernel, moved into EnvirBase (!) cEnvir: Renamed getRNGMappingFor(component) to preconfigure(component) (!) cStatistic now subclasses from cRandom, and its random() has been deprecated in favour of cRandom's draw() (!) Iterators: changed increment/decrement operators to make them more similar to STL iterators. (!) SimTime: conversion from double now uses rounding instead of truncation (plain C-style cast). This change may alter simulation results. (!) cSimulation: getLastModuleId() renamed to getLastComponentId() (as cSimulation now stores cComponent pointers, not cModule pointers) (!) The following macros were removed: SIMTIME_RAW(), STR_SIMTIME(), SIMTIME_TTOA(). They were compatibility macros that had been introduced in 4.0 to allow writing models that work with both the then-new int64-based SimTime class and the legacy "double" simtime_t. (!) MAXTIME was renamed to SIMTIME_MAX. (!) SimTime change: Replaced "int exponent" with "SimTimeUnit unit" in the two-argument constructor and several other methods, with the aim of making the API more user-friendly, and model code easier to read. Affected SimTime methods: - SimTime(int64_t value, SimTimeUnit unit) - int64_t inUnit(SimTimeUnit unit) const - SimTime trunc(SimTimeUnit unit) const - SimTime remainderForUnit(SimTimeUnit unit) const - void split(SimTimeUnit unit, int64_t& outValue, SimTime& outRemainder) const (!) Several methods made virtual in cComponent, cModule, cSimpleModule, cChannel, cArray, cQueue, cTopology, cStatistic, etc. (!) cPar: read() and finalize() conceptually changed to be internal methods (they are still declared public for technical reasons) (!) Define USE_OMNETPP4x_FINGERPRINT at compile-time to get back OMNeT++ 4.x fingerprints. (!) cSimulation: removed getHasher() and setHasher(), added getFingerprintCalculator() and setFingerprintCalculator(). (!) cSimpleModule::scheduleAt() return type changed from int (a dummy) to void. (!) cObject::getDescriptor() was changed to const (!) Some cComponent/cModule methods were changed to const to facilitate calling them from refreshDisplay(): - cComponent: getDisplayString() - cModule: findSubmodule(), getSubmodule(), getModuleByPath(), getCanvas(), getOsgCanvas() (!) M_PI has been added to <omnetpp/platdep/platmisc.h> (!) Renamed cOutputVectorManager, cOutputScalarManager and cSnapshotManager to cIOutputVectorManager, cIOutputScalarManager and cISnapshotManager. (!) Renamed cMessageHeap to cEventHeap (!) cSimulation: removed msgQueue and getMessageQueue(); added getFES() as replacement (returns cFutureEventSet*) (!) cEventHeap: peek(k) renamed to get(k) (!) cException: getContextModuleID() renamed to getContextComponentId() (!) cStatistic: methods renamed: - addTransientDetection() -> setTransientDetectionObject() - addAccuracyDetection() -> setAccuracyDetectionObject() (!) cDensityEstBase: methods renamed: - getNumFirstVals() -> getNumPrecollectedValues() - setNumFirstVals() -> setNumPrecollectedValues() (!) cKSplit: method rename: rangeExtension(bool) to setRangeExtension() (!) cVarHistogram: unnamed enum of HIST_TR_xxx constants became cVarHistogram::TransformType (!) cObject: parsimPack() became const (!) Register_Enum(): implementation changed, so now the 1st arg must name an existing C++ enum. Before this change any string would suffice. (!) VoidDelFunc and VoidDupFunc became inner types of cMsgPar, as only cMsgPar used them. (!) cEnvir: new method log(cLogEntry&) replaces earlier stream operators, getOStream() and sputn() methods as the mechanism underlying EV <<. New class cLogEntry captures much more context of the log statement than previously available. (!) cResultListener: added callFinish(), so that invoking finish() multiple times can be eliminated at the cost of one additional flag. (!) cModule: changeParentTo() will now assign a new ID to the module. This usually causes no problem in the simulation's operation, but if your model stores module IDs somewhere, you'll need to invalidate or update them manually. (!) cSimulation: getModule(id) also returns NULL if the ID is valid but refers to a non-module (that is, channel) object. Previously it only returned NULL if the ID was invalid or referred to a deleted module. (!) Renamed error codes: eXXX to E_XXX (!) Removed nonstandard fixed-size integer typedefs: int8, uint8, etc. Use the standard ones with the _t suffix. Note that the removed types were never advertised as API. (!) cClassDescriptor interface cleanup: - removed redundant "void *object" first argument from methods that referred to the class and not instance: getFieldName(), getFieldProperty(), getFieldStructName(), etc. - added getPropertyNames() and getFieldPropertyNames() - renamed getArraySize() to getFieldArraySize() - renamed getFieldAsString() to getFieldValueAsString() - similarly, renamed setFieldAsString() to setFieldValueAsString() - renamed getFieldStructPointer to getFieldStructValuePointer() - old methods still exist as deprecated ones (-) Iterators: deprecated operator(); use operator* and operator-> instead. (-) cQueue: deprecated length() and empty(); use getLength() and isEmpty() instead (-) cModule: size() deprecated, use getVectorSize() instead (x) cClassDescriptor: removed deprecated compatibility methods that emulated pre-4.2 API, i.e. certain overloaded versions of: getFieldCount(), getFieldName(), findField(), getFieldTypeFlags(), getFieldIsArray(), getFieldIsCompound(), getFieldIsPointer(), getFieldIsCObject(), getFieldIsCOwnedObject(), getFieldIsEditable(), getFieldDeclaredOn(), getFieldTypeString(), getFieldProperty(), getArraySize(), getFieldAsString(), getFieldAsString(), setFieldAsString(), getFieldStructName(), getFieldStructPointer() (x) Removed deprecated methods: - cGate::setChannel(); use reconnectWith() instead - cMessage::setArrival() - cMessage::addPar(cMsgPar&); use addPar(cMsgPar*) instead - cMsgPar::getAsText(); use str() instead - cMsgPar::setFromText(); use parse() instead - cPacket::getEncapsulatedMsg(); use getEncapsulatedPacket() instead - cModule::getModuleByRelativePath() (x) Removed deprecated types/typedefs and constants: - cSubModIterator: use cModule::SubmoduleIterator instead - cSimpleChannel typedef; use cDatarateChannel - cPolymorphic typedef; use cObject instead - Simtime::SCALEEXP_S and other SCALEEXP_xxx constants; use SIMTIME_xxx constants instead (x) Removed deprecated functions: genk_intrand(), genk_dblrand(). Use the updated intrand/dblrand instead. (x) cEventHeap::Iterator removed (not much advantage over get(i)) (x) cEventHeap: removed length() and empty(); use getLength() and isEmpty() instead (x) Removed deprecated opp_error(), opp_terminate(), opp_warning() functions (x) Removed deprecated class cLinkedList. Use std::list instead. (x) Removed deprecated operator[] from cSimulation. Use getModule(id) or getComponent(id) instead. (x) Removed deprecated macros: Define_Function(), Define_Function2(), Define_Function3(), Define_Function4(). Use Define_NED_Math_Function() instead. (+) Introduced cRandom, which encapsulates a random number stream into an object. Random numbers can be extracted with the draw() method. (+) Added cIEventlogManager. (+) cConfigOption: Refined per-object config option kinds (added COMPONENT and CHANNEL). (+) Added cOsgCanvas and cObjectOsgNode. (+) cComponent: added the refreshDisplay() method which is called by graphical user interfaces (Qtenv, Tkenv) whenever GUI contents need to be refreshed after processing some simulation events. (+) cEnvir: added isExpressMode() that can be used to tailor the operation of refreshDisplay(). (+) cEnvir: added resolveResourcePath() for finding data or other files needed by the model. (+) cComponent: added resolveResourcePath(). It delegates to cEnvir's similar method. (+) The *, /, *=, /= operations involving a SimTime and an integer type now do the computation using integer arithmetic (instead of double), and also check for overflow. (+) Added SimTime::isZero() (+) Added div(SimTime, SimTime) (+) Added cFingerprintCalculator and subclasses. (+) Added the following cRandom subclasses: cUniform, cExponential, cNormal, cTruncNormal, cGamma, cBeta, cErlang, cChiSquare, cStudentT, cCauchy, cTriang, cWeibull, cParetoShifted, cIntUniform, cBernoulli, cBinomial, cGeometric, cNegBinomial, cPoisson. They encapsulate the similarly named functions (e.g. exponential()) with their parameters and the random number generator (cRNG). (+) Iterators (cModule::GateIterator, cModule::SubmoduleIterator, cModule::ChannelIterator, cQueue::Iterator, etc.): added operator* and operator-> to make them behave more similar to STL iterators. (+) An abstract cFutureEventSet base class has been introduced, and cEventHeap now extends cFutureEventSet (+) cEnum: added getNameValueMap() method (+) Remove the deprecated status of some cChannelType methods: createIdealChannel(), createDelayChannel() and createDatarateChannel() (+) cException: added getContextComponentKind() (+) cComponent: added getComponentKind() (and isModule()/isChannel() changed to rely on it) (+) New global functions: getSimulation(), getEnvir() (+) New methods: - cComponent::getSimulation() - cComponent::getSystemModule() - cScheduler::getSimulation() (+) Added cComponent::hasGUI() to replace ev.isGUI() calls (+) Added OMNETPP_BUILDNUM (+) cObjectFactory: the static find() and get() methods received two extra args with default values, namely const char *contextNamespace=nullptr and bool fallbackToOmnetpp=true (+) Added the canvas API for 2D figure-based drawing. - Principal classes: cCanvas, cFigure. - cFigure inner classes: Point, Rectangle, Color, Font, Transform, RGBA, Pixmap. - cFigure subclasses: cGroupFigure, cAbstractLineFigure, cLineFigure, cArcFigure, cPolylineFigure, cAbstractShapeFigure, cRectangleFigure, cOvalFigure, cRingFigure, cPieSliceFigure, cPolygonFigure, cPathFigure, cAbstractTextFigure cTextFigure, cLabelFigure, cAbstractImageFigure cImageFigure, cPixmapFigure. (+) Added log channel macros for 6 log levels: EV_FATAL, EV_ERROR, EV_WARN, EV_INFO, EV_DETAIL, EV_DEBUG, EV_TRACE. EV is equivalent to EV_INFO. (+) Macros for logging with category strings: EV_C(category), EV_FATAL_C(category), EV_ERROR_C(category), EV_WARN_C(category), EV_INFO_C(category), EV_DETAIL_C(category), EV_DEBUG_C(category), EV_TRACE_C(category). (+) Added EV_STATICCONTEXT macro, needed for being able to log from static member functions. (+) Added GLOBAL_COMPILETIME_LOGLEVEL. Define it at compile time to control which log statements are compiled into the code. (+) check_and_cast<> may now be used to convert across arbitrary types, i.e. argument no longer needs to be cObject*. (+) Added check_and_cast_nullable<> that accepts NULL pointer as input (+) Introduced cEvent as a base class of cMessage. cEvent allows scheduling of execution of code that's not tied to a module. (+) Added putBackFirst(cEvent *event) to cMessageHeap (+) New class: cISimulationLifecycleListener (+) New enum: SimulationLifecycleEventType. Values: LF_ON_STARTUP, LF_PRE_NETWORK_SETUP, LF_POST_NETWORK_SETUP, LF_PRE_NETWORK_INITIALIZE, LF_POST_NETWORK_INITIALIZE, LF_ON_SIMULATION_START, LF_ON_SIMULATION_PAUSE, LF_ON_SIMULATION_RESUME, LF_ON_SIMULATION_SUCCESS, LF_ON_SIMULATION_ERROR, LF_PRE_NETWORK_FINISH, LF_POST_NETWORK_FINISH, LF_ON_RUN_END, LF_PRE_NETWORK_DELETE, LF_POST_NETWORK_DELETE, LF_ON_SHUTDOWN. (+) cEnvir: added addLifecycleListener() and removeLifecycleListener(). (+) getId() moved from cModule to cComponent, so now it's inherited by cChannel as well (+) cSimulation: added getComponent(id) and getChannel(id) to complement getModule(id) (+) cTopology: added factory methods for links and edges (+) cTopology: added methods to manipulate the graph (e.g. build a graph from scratch): int addNode(Node *node); void deleteNode(Node *node); void addLink(Link *link, Node *srcNode, Node *destNode); void addLink(Link *link, cGate *srcGate, cGate *destGate); void deleteLink(Link *link); (+) cEnvir: added addHttpRequestHandler() and removeHttpRequestHandler() (+) New classes: cHttpRequestHandler, cHttpRequest (+) Added Register_Enum2() macro, which registers an enum and at the same time makes it accessible via a global cEnum* pointer. (+) cEnum: added resolve() and bulkInsert() (+) cGate: added getConnectionId(), mostly useful for tools. (+) opp_string: added size() method OMNeT++ 4.6 ~~~~~~~~~~~ None. OMNeT++ 4.5 ~~~~~~~~~~~ (+) Added cMessagePrinter and the Register_MessagePrinter() macro. (+) Simple module classes can be used for compound modules (with @class), and doing so will make the module behave as a normal simple module would. (!) Compound modules are now represented with cModule, and the (almost empty) cCompoundModule class was removed. This change was made to allow simple module classes to be used for compound modules. OMNeT++ 4.4 ~~~~~~~~~~~ (!) cIListener: added receiveSignal() overload for the bool type. Most code containing listeners don't have to be changed as they subclass from cListener, a do-nothing listener implementation. (!) cComponent: added emit(simsignal_t, const cObject*). This was necessary because otherwise the compiler silently casts 'const cObject *' pointers to long (!) and calls that emit(). The new method delegates to the const-less version. It would have been cleaner to do it the other way round (let the non-const version delegate to the const version); for that, however, existing listeners would have had to be changed to accept const pointer, a painful change. (!) cITimestampedValue::Type replaced by SimsignalType (+) cObjectFactory: added isInstance() method (+) Added Register_Abstract_Class() macro (+) cNEDValue: added two static parseQuantity() functions (+) cEnvir: added attachDebugger() method (+) cEnvir: added addResultRecorders() method that allows for setting up declarative statistics collection on dynamically created signals (see manual for details) (!) cResultRecorder: init() method signature change (!) In embedding uses, ExecuteOnStartup::executeAll() should be replaced by CodeFragments::executeAll(CodeFragments::STARTUP), and the cleanup code at the end of main() should be replaced by CodeFragments:: executeAll(CodeFragments::SHUTDOWN). OMNeT++ 4.3 ~~~~~~~~~~~ (+) Signals implementation now allows static initialization of simsignal_t variables, i.e. the signal registration table is no longer cleared between simulation runs. (+) cModule: added getModuleByPath(), that understands both relative and absolute module paths, and also navigate up in the hierarchy (^). (-) cModule: deprecated getModuleByRelativePath(), due to the availability of a better variant, getModuleByPath() (+) cTopology: added calculateWeightedSingleShortestPathsTo() (+) cPacket: added hasEncapsulatedPacket() (+) cPatternMatcher, cMatchExpression: new utility classes (+) cGate: added getBaseId() (+) SimTime: added SimTime(int64 value, int base10exponent) constructor to allow specifying precise constants (+) SimTime: added functions for getting the value out in various time units (sec, msec, etc): inUnit(), trunc(), remainderForUnit(), split() OMNeT++ 4.2 ~~~~~~~~~~~ (+) Users can now extend @statistic with new result filters and result recorders. See the cResultFilter, cNumericResultFilter, cObjectResultFilter, cResultRecorder, and cNumericResultRecorder classes, and the Register_ResultFilter() and Register_ResultRecorder() macros. (!) The Define_Function() macros have been renamed to Define_NED_Math_- Function(). For backwards compatibility, the old macro definitions remain, but issue a deprecation warning. The underlying registration class cMathFunction was also renamed to cNEDMathFunction. Note that the recommended way of defining new NED functions is now the Define_NED_Function() macro, which provides more functionality. (!) cDynamicExpression::Value, used by user-defined NED functions (see Define_NED_Function() macro), has been factored out to a cNEDValue class, and its external interface has changed. Data members are no longer public, they can be manipulated via various methods. Existing user-defined NED functions will need to be revised; you can find code examples in src/sim/nedfunctions.cc. (+) cPar: setExpression() now accepts an evaluationcontext parameter; new methods: getEvaluationContext(), setEvaluationContext() (!) The Register_PerObjectConfigOption() and Register_PerObjectConfigOptionU() macros now take one more argument (inserted into the 3rd place), the object kind. (!) cRegistrationList::get() was renamed to find(), for consistency with similarly named methods in other classes (!) Removed #include <winsock.h> from <platdep/timeutil.h>; the reason is that it conflicted with lwIP code recently integrated into INET. <platdep/sockets.h> still includes <winsock.h>, but now <platdep/sockets.h> MUST precede <omnetpp.h> in all source files. (i) cChannel::MessageSentSignalValue: getMessage() return type fixed (changed from cObject to cMessage) (+) New cEnvir methods: getParsedXMLString(), forgetParsedXMLString(), flushXMLParsedContentCache(). OMNeT++ 4.1 ~~~~~~~~~~~ (+) Introduced the signals mechanism; see the new "Signals" section in the Manual. Implementation comprises new classes cIListener and cListener; new cComponent methods registerSignal(), getSignalName(), emit(), mayHaveListeners(), hasListeners(), subscribe(), unsubscribe(), isSubscribed(), getLocalListenedSignals(), getLocalSignalListeners(); constants PRE_MODEL_CHANGE and POST_MODEL_CHANGE; new class cModelChangeNotification and subclasses. Signal-based result recording uses @statistic properties in NED files. (!!!) cGate: removed isBusy() and getTransmissionFinishTime(), as they were confusing (they ignored any propagation delay up to the transmission channel); they had bad performance characteristics (they linerarly searched for the transmission channel every time); and they threw an error if the path didn't contain a transmission channel at all. (!!!) cChannel: change in the programming model. The old deliver() method's semantics has changed, the method was renamed to processMessage() and its and argument list changed. The reason is to decrease the amount of code that needs to be written when implementing a new channel class, and to improve reusability via subclassing. See documentation in the code. (+) cChannel: added forceTransmissionFinishTime(simtime t), so that channels can support aborted transmissions (needed e.g. for Ethernet). (+) cChannel: added getNominalDatarate(). This is often needed in models, for example in INET to fill in the interface entry. (+) cGate: added utility functions findTransmissionChannel(), getIncomingTransmissionChannel(), findIncomingTransmissionChannel(). (+) cComponent: added isChannel() utility method (it already had an isModule() method) (!) cComponent: handleParameterChange() is now called for each component with parameterName=NULL after the last stage of the initialization phase. This allows the components to refresh their cached parameter values if some parameters were changed during the initialization phase. This is necessary because handleParameterChange() is not called during the component's initialization phase. (!) cPar: added a note to the xmlValue() method that the lifetime of the returned objects may be limited. Modules should NOT hang on to cXMLElement pointers between events! (+) cGate: added getNameSuffix() method. (+) cSimulation: added getSimulationStage() (+) cException: exception object now stores simulation stage, event number and simulation time as well; also added getFormattedMessage() method that puts together the complete error message from its pieces. (+) cMessage, cPacket: several methods were made virtual, most notably encapsulate() and decapsulate(), to allow customizing the behavior in subclasses (!) cPacket: getEncapsulatedMsg() was renamed to getEncapsulatedPacket() to better describe its function. The old method was left there for backward compatibility; it is deprecated and delegates to the new method. (+) Enter_Method_Silent() now may take arguments (printf-like arg list). Also, it now logs the call into the eventlog file (and the resulting string (if given) is recorded as the method name). (+) cModule::addGate() now returns the gate pointer whenever a single gate is created (for inout gates [~gate pair] and vectors it returns NULL) (+) cModuleType: added isSimple() method (+) New NED function: expand(). It substitutes ${} config variables into a string. Possible use: in NED parameters like the following: string fname = default(expand("${resultdir}/${configname}-${runnumber}.txt")); (+) Created cHistogram class by merging cDoubleHistogram and cLongHistogram functionality. (i) When recording a histogram object into the scalars file (see cComponent::recordStatistic(), cStatistics::record(), etc.), its transform() method gets invoked to force it set up the histogram cells, provided it was not already invoked. (!) cVarHistogram: createEquiProbableCells() renamed to createEquiprobable- Cells() (lowercase "p") (+) cOutVector: added setRecordDuringWarmupPeriod() and getRecordDuring- WarmupPeriod() methods. (+) cArray: added setCapacity(), getCapacity(). setCapacity() can be used to trim back the internally allocated array after a large number of items have been removed from it. (!) cProperty: getNumValues() to return 0 (instead of thowing an error) when the property does not contain the given property key. (+) cClassDescriptor: added findField() method (+) cConfiguration: substituteVariables() made public (+) cEnvir: added forgetXMLDocument(filename) and flushXMLDocumentCache() (see bug #131) (!) cClassFactory was renamed to cObjectFactory (+) cStringTokenizer: added copy constructor and assignment operator (i) Corrected the definition of NULL according to C++ rules (i) FES performance improvement: cMessageHeap was changed to more efficiently handle the insertion and removal of events scheduled for the current simulation time. Such events are actually quite common due to plain (zero delay, zero datarate) connections between modules. For more info, see src/sim/ChangeLog. (i) Performance improvement: cMessage::getArrivalTime() was consuming 10-20% of CPU time in many configurations, see bug #22, http://dev.omnetpp.org/bugs/view.php?id=22. Solution: change return type of getArrivalTime() and other methods from simtime_t to simtime_t_retval (which is a new typedef that maps to const simtime_t&). Reason: on some platforms and configurations, esp. in debug builds, returning a const reference is more efficient than returning by value (even though SimTime is only 64 bits and would fit in register(s)). On 64-bit architectures and optimized builds (-O2/-O3) this change may actually decrease performance; this is to be investigated, and simtime_t_retval conditionally defined as plain simtime_t. OMNeT++ 4.0 ~~~~~~~~~~~ (!!!) Lots of breaking changes. We opted for doing all necessary changes at once (3.3 -> 4.0) instead of scattering them over multiple releases after 4.0. This way only one porting is needed, and API can be kept more stable over the coming releases. If you need to convert models from 3.x to 4.0, see the Migration Guide first! General: - "get" verb added to the names of nearly all getter methods; notable exceptions are STL-like names like size(), empty(), length(), end(), str(), c_str(); par() and gate() methods of cModule; boolValue(), longValue(), stringValue() etc methods of cPar (already consistent with Java); info(), detailedInfo(); intRand(), dblRand() and other cRNG methods. Methods returning bools begin with "is", "has", "contains" or a similar verb. [Change decided by voting on the mailing list] - <omnetpp.h> now provides the C99 integer types and limit macros, even on systems that don't have <stdint.h> (for example, MSVC does not have it). This includes int8_t, uint8_t,..int64_t, uint64_t types; INT8_MAX, UINT64_MAX, etc. In addition, it also provides shorter names (int8, uint8,...); they are provided as macros, so if they collide with definitions in some external code, they can be undefined after including <omnetpp.h>. cObject, cPolymorphic: - cObject renamed to cOwnedObject, cPolymorphic renamed to cObject - cNamedObject introduced between cObject and cOwnedObject - note: cArray, cQueue still handle cObject (old cPolymorphic), that is, they handle non-owned objects as well - removed writeContents() altogether - covariant return types for dup(): the return type of X::dup() is no longer cPolymorphic* or cObject* but X*. This was made possible by dropping support for Visual C++ 6.0. The change might cause incompatibility with customized message classes (.msg file with customize=true). If the hand-coded class still contains cPolymorphic* return type not the real class type, that results in compiler errors like this: ../Transport\TCP\TCPSegment.h(68) : error C2555: 'TCPSegment::dup': overriding virtual function return type differs and is not covariant from 'TCPSegment_Base::dup' The fix: change dup()'s return type to the real class. Exception handling: - now all our exceptions subclass from std::exception (cException also extends std::exception). Hint: catch std::exception if you don't need the exception to be of a specific type - exceptions are now thrown by value not by pointer (all "throw new" in the code must be replaced with "throw") Simulation time: - simtime_t is now not double but class SimTime (64-bit fixed point number) - simtime exponent is base 10, and set globally - there is no implicit conversion from SimTime to double. However, to alleviate this pain, at many places overloaded functions have been added that take simtime_t. - simtimeToStr(), strToSimtime() are no longer (use SimTime methods instead, or the compatibility macros described below!) - simTime() was moved out of the cSimpleModule class: it became a global function which delegates to simulation.getSimTime() Simtime compatibility mode: - if needed, the simkernel can be compiled with simtime_t = double. For that, compile everything with USE_DOUBLE_SIMTIME defined (add -DUSE_DOUBLE_SIMTIME to CFLAGS). If you want to ensure that models compile with both int64-based and double simtime_t, use the following macros to convert simtime_t from/to double and string: SIMTIME_STR(t), SIMTIME_DBL(t), STR_SIMTIME(s), SIMTIME_TTOA(buf,t). MAXTIME is also defined correctly for both simtime types. Converting source code to the new int64-based simtime_t: - for the large part, code is supposed to compile without much change - most errors come from using "double" variables which should really be "simtime_t". E.g. if you see variables like double timeout, double interval, double age, etc, they should all be changed to simtime_t. This applies to message fields within .msg files as well: some of the "double" ones may need to be changed to "simtime_t". - when conversion to double is still needed, use SIMTIME_DBL(t) or t.dbl(). - ev << simtimeToStr(t) is to be changed to: ev << t; Gate handling: - introduced inout gates, which resulted in some changes listed below - with inout gates, gate("gatename") does not work, use gate("gatename$i") or gate("gatename$o") instead - if a gate vector is zero size, there's no cGate object for it at all. But hasGate(), gateType(), isGateVector(), gateSize() do work. - for gate direction, use the new cGate::Type enum instead of the 'I' and 'O' characters (though characters continue to work) - setGateSize() return type changed from int to void (when resizing an inout gate, it would have to return the two ids) - addGate() return type changed to void (when an inout gate is created, it would have to return two cGate* pointers) - gate("xxx") now throws error if gate is not found, instead of returning NULL - gate("xxx") now won't return gate "xxx[0]" - gate("out")->size() does not work, because gate("out") throws an error ("not found") if "out" is a vector gate; gate("out",0)->size() will work, but only if out[] is of nonzero size (otherwise you'll get the "gate out[0] not found" error). Best is to use gateSize("out"), a cModule member function. - removed setTo(), setFrom() methods; use connectTo() instead! - isRouteOK() renamed to isPathOK() - fromGate()/toGate() renamed to getPreviousGate()/getNextGate() - sourceGate()/destinationGate() renamed to getPathStartGate()/getPathEndGate() - dynamic gate creating changed: - removed cGate::setOwnerModule() and setIndex() - now there is addGate() and setGateSize() - to help connecting gate vectors, two utility methods were added: - getOrCreateFirstUnconnectedGate() - getOrCreateFirstUnconnectedGatePair() - added setDeliverOnReceptionStart() flag, which may be invoked only on simple module input gates. It defines whether a packet that travelled through a channel with datarate (i.e. has nonzero duration) is delivered to the module at the time reception begins, or when reception ends. (In OMNeT++ 3.x, only the latter option was available). - added getTransmissionChannel() which returns *the* transmission channel in the path - transmissionFinishes() renamed to getTransmissionFinishTime() - gates that have the @loose or @directIn property set in the NED file may remain unconnected (ie no error will be raised, even if "allowunconnected" is not specified in the connections section) Channels: - channels became first-class citizens: they have a common base class (cComponent) with cModule, they participate in the initialize()/ finish() protocol, and so on. - cBasicChannel renamed to cDatarateChannel - added calculateDuration(cMessage *msg) method into channels - removed delay(), setDelay(), error(), setError(), dataRate(), setDataRate() methods from cGate: please use methods from the gate's channel instead: check_and_cast<cDatarateChannel *>(gate->channel())->setDelay(0.1); or use generic component parameter access instead: gate->channel()->par("delay")=0.1. - "error" parameter renamed to "ber" (bit error rate or BER, cDatarateChannel methods getBitErrorRate/setBitErrorRate) - added "per" parameter (packet error rate or PER, cDatarateChannel methods getPacketErrorRate/setPacketErrorRate) - added cIdealChannel which lets messages through without any change and without any delay. - added cDelayChannel - getFromGate() renamed to getSourceGate() - breaking change in cDatarateChannel behaviour: implicit queueing is no longer supported: sending on a busy gate (that is, when simTime() < gate->transmissionFinishTime()) results in an error. Thus, using a special transmitter module (with an internal queue) is now sort of mandatory when channels with data rate are in use. - setting channel parameters from the ini file: add <fromgate-fullpath>.channel.<paramname> = <value>, e.g.: **.a.out.channel.delay = 10ms - now a connection path may only contain one cDatarateChannel (more precisely, only one channel whose isTransmissionChannel() method returns true) - likewise, a sendDirect() call with nonzero duration may only be sent onto a gate whose connection path does NOT contain any cDatarateChannel (or channel whose isTransmissionChannel() method returns true) Dynamic module/channel creation: - finalizeParameters() must be called (for channels, this reads input params from omnetpp.ini; for modules, also creates gates [since gate vector sizes may depend on parameter values]) - global connect() function removed (use cGate::connectTo() instead) cQueue: - head()/tail() removed, back()/front() added (insert at back, pop from front!); because of head/tail change, iterator direction and meaning of insertBefore/insertAfter has changed - boolean flag to specify ascending/descending order removed (because the earlier default ascending=false was inconvenient, and silently changing the default is not a good idea) - compat.h typedef cQueueIterator removed, as iterator semantic was changed in a non-compatible way anyway - new class: cPacketQueue cArray: - items() became size() cBag class removed Display strings: - connection display string is now stored in the channel, not the source gate - setDisplayString() methods removed - displayString() delegates to channel()->displayString(); if there's no channel, it creates a cIdealChannel - module and channel display string access functions are now in the common base class, cComponent - display string objects are now only created (from @display) when first accessed cDisplayString: - parse() no longer interprets literal "\t", "\n" escape sequences; it is the job of the NED or C++ compiler to convert those to 0x09, 0x0a etc. "\;", "\=", "\," can still be used to escape those special characters, but they have to be entered into the NED or C++ source with *double* backslashes like "t=hello\\,world" (one will be eaten by the NED/C++ compiler, the other by the display string parser). - parse() now throws an error if the display string has invalid syntax. It used to return a boolean which practically no one checked. - getString() was renamed to str() Introduced cComponent, a common base class for cModule and cChannel - new methods to mention: isModule(), nedTypeName(), etc - final garbage object collection can be turned on per module, by invoking setPerformFinalGC(true) cModule: - removed backgroundDisplayString()/setBackgroundDisplayString() and its compat #defines displayStringAsParent()/setDisplayStringAsParent() - removed deprecated methods phase(), setPhase() - added isPlaceholder() to cModule - cPlaceHolderModule: renamed to cPlaceholderModule (lowercase h) - gate handling reorganized, so that gate IDs are stable (do not change when the gate vector gets resized). Gate IDs are now interpreted as a bitfield, so they cannot be used for iterating over all gates of a module; cModule::GateIterator was introduced for this purpose. - gates() removed, as gate IDs are no longer integers in the 0..gates()-1 interval (use the new cModule::GateIterator for enumerating the gates). - added gateNames() method - className() for cModule (or cComponent in general) no longer lies the NED type name, but returns the real C++ class name - deprecated cSubmodIterator -- use cModule::SubmoduleIterator instead! - added cModule::ChannelIterator cModuleType: - cModuleType::buildInside(mod) became protected (was deprecated anyway) cSimpleModule: - cSimpleModule::end() -- removed, as there was little value in it. To terminate an activity() module, simply return from the activity() method, or call the new halt() method (the latter preserves local variables for inspection) - added cSimpleModule::halt() - cSimpleModule::deleteModule() -- in handleMessage()-based modules, this no longer throws exception. That is, execution will continue normally after the deleteModule() call. - removed cSimpleModule::moduleState() - removed: pause(), backtomod, pause_in_sendmsg (they were obsolete) - removed: breakpoint(), and its callback method in cEnvir, in Tkenv, etc.. - sendDirect(): added overloaded methods that accept transmissionDelay - cancelEvent() now only allows cancelling self-messages cMessage changes: - the length, bit error flag and encapsulated message cMessage fields got factored out from cMessage, into the cPacket class (which extends cMessage). All network packets (frames, datagrams, etc) are now supposed to be subclassed from cPacket, not directly cMessage. To port simulations into 4.0, in message descriptions (.msg files) change relevant "message" keywords to "packet" (this will cause the base class to be cPacket), and use casts to convert cMessage* to cPacket* where needed: cPacket *pkt = check_and_cast<cPacket *>(msg). We hope that on the long run this change will result in clearer code in simulation models. To help porting, it is possible to compile everything in a "backward compatibility mode" when cPacket is just an alias to cMessage, and cMessage contains all fields. For that, compile everything having WITHOUT_CPACKET defined (add -DWITHOUT_CPACKET to CFLAGS). - the C++ type for message kind and priority changed from "int" to "short", and priority was renamed to scheduling priority (methods setSchedulingPriority/getSchedulingPriority) - added some extra fields required by sequence chart drawing: cause event number, message id, message tree id, etc. - removed two static methods of limited usefulness: cmpbydelivtime(), cmpbypriority(). cPacket: - existing obsolete fields (protocol and pdu codes) were removed - the length, bit error flag and encapsulated message fields were moved from cMessage into cPacket - methods associated with "length" got renamed, new method names are: getBitLength(), setBitLength(), addBitLength() - length changed from long to int64 (reason: message length was limited to 2 gigabits=256 megabytes on 32-bit architectures). Affected functions: setLength() / setByteLength() / addLength() / addByteLength() length() / byteLength() - added getDuration() and isReceptionStart() methods, which are related to the last send over a channel with datarate, and to cGate's deliverOnReceptionStart flag. cMessageHeap: - renamed getFirst() to removeFirst(), and get(cMessage*) to remove(cMessage*) Message parameters: - deprecated; type changed: cMsgPar instead of cPar - cMsgPar is the same as the old cPar, but features which are not needed for message parameter objects have been removed: - removed support for interactively prompting the user for a value: input flag, prompt, read() method - removed indirection (redirection) support - removed support for storing expressions Module parameters (cPar): - implementation changed: now cPar is only a thin wrapper around an object that actually holds the value (cParImpl and subclasses); typically several cPars will share the same cParImpl object - setFromText() renamed to parse() - getAsText() renamed to str() - added method stdstringValue() and operator std::string: they must be used with "volatile string" parameters cOutVector: - removed half-hearted tuple=2 support from cOutVector and underlying infrastructure - added methods for metadata annotation: setEnum(), setUnit(), setType(), setInterpolationMode(), setMin(), setMax() recordScalar() methods (cSimpleModule, cStatistic): - added optional "const char *unit" argument to all respective methods - cStatistic::recordScalar() renamed and split to record(), recordAs() and recordWithUnit() - cSimpleModule::recordScalar() methods moved to cComponent - see also: **.param-record-as-scalar = true Statistics classes: - cStatistic: renamed samples() to count(). This affects cStdDev, cWeightedStdDev and basically all statistics classes (they all inherit from cStatistic) - cWeightedStdDev: implemented stddev(); also fixed min() and max() (they bogusly returned min/max of the weight*value products). For stddev(), code is based on the patch from Peter Woitek. - cStatistic: added 3 new functions, to access values underlying weighted statistics: weightedSum(), sqrSumWeights(), weightedSqrSum() - cStatistic: added isWeighted() - cStatistic: added merge(cStatistic *) for aggregating statistics, and implemented it in subclasses - cDensityEstBase etc: transformed() renamed to isTransformed(); added setCellSize() - cLongHistogram: revised the way histogram cells are set up. Now it throws an error if all given constraints cannot be satisfied (so that numCells*cellSize==rangeMax-rangeMin, all integers) - cDensityEstBase: added cellInfo() method cTopology changes: - added extractFromNetwork(Predicate*), to support specifying conditions in a type-safe way (without void* casts) - extractByModuleType() not longer exists, use the new extractByNedTypeName() method instead. Code like topo.extractByModuleType("Host", "Router", NULL); should be replaced by something like topo.extractByModuleType(cStringTokenizer("Host Router").asVector()); - extractByParameter() arg list changed cEnvir refactoring: - motivation: break sim_std.dll dependence on envir.dll (mainly the "ev" global variable) - "ev" is no longer a variable, but a macro which expands to (*evPtr) - cEnvir no longer subclasses from std::ostream, but instead redirects all ev<< calls to an internal std::ostream instance - cEnvir is no longer a concrete class, but an abstract base class with lots of pure virtual methods - removed puts(const char *) and gets(const char *) - run numbers are now entirely the internal business of cEnvir; runNumber was removed from the arg list of cEnvir callback functions. - created cRunnableEnvir by factoring out run() method from cEnvir; simulation user interfaces like Cmdenv or Tkenv subclass from cRunnableEnvir, but other custom environment objects do not need to. - added cNullEnvir, a default do-nothing implementation for cEnvir. - several functions changed/renamed cConfiguration: - configuration handling rewritten, including cConfiguration; methods completely changed - cConfiguration split to a smaller cConfiguration plus a cConfigurationEx class that adds the rest of the methods. When the simulation kernel is used as library, only cConfiguration needs to be implemented. cConfigurationEx is needed only when one wants to plug in a different configuration object into the existing Envir library, replacing SectionBasedConfig. cSimulation: - cSimulation now creates a cSequentialScheduler by default (no need to do it manually); if it's not good, a different scheduler object can be installed with the setScheduler() method. - support for multiple instances of cSimulation. "simulation" is no longer a global variable but a macro that expands to cSimulation::getActiveSimulation(). Multiple cSimulation objects may coexist; before invoking any function in the simulation library, the correct cSimulation instance must be activated with cSimulation::setActiveSimulation(). - multiple environment objects may coexist; in fact, there must be exactly one associated with every cSimulation instance. "ev" now maps to cSimulation::getActiveEnvir() which is short for cSimulation::getActiveSimulation->getEnvir(). cSimulation:: setActiveSimulation() which activates a cSimulation instance also activates its corresponding environment object. - added cSimulation::loadNedText(), to facilitate creating self-contained executables by embedding NED source as string literals; also added cSimulation::clearLoadedNedFiles() function - cSimulation::runNumber() got removed, as run numbers are now entirely the internal matter of cEnvir. - added method getHasher() to provide access to fingerprint calculation for simulation models. cCommBuffer: - added pack/unpack methods for int64 - array packing methods now take const pointers - doPacking()/doUnpacking() methods moved out of opp_msgc-generated code into the simkernel headers (packing.h, included by omnetpp.h) NED functions: - introduced cNEDFunction and Define_NED_Function(), to make it possible to write NED functions that take arguments of various types, not only double Misc changes: - global findXXX(const char *name) functions turned into static find(const char *name) functions of corresponding classes. This applies to: findLink(), findFunction(), findEnum(), findChannelType(), findNetworkType(), findModuleType() - removed macros Min() and Max(), use std::min/std::max instead (<algorithm>); also removed sgn() - removed min(double,double), max(double,double), equal(double,double,double). Use std::min and std::max instead. - internal class cStructDescriptor refactored and renamed to cClassDescriptor - several internal classes got removed/reorganized - calls to myxxx() functions should be replaced with opp_xxx() in the code: myrandomize(...) genk_myrandomize(...) mystrdup(...) mystrcpy(...) mystrcmp(...) mystrmatch(...) fastconcat(...) indexedname(...) - calls to genk_xxx() functions should be replaced with their "genk_"-less counterparts (and the first arg dropped or moved to the last place): genk_uniform(double gen_nr, double a, double b); genk_intuniform(double gen_nr, double a, double b); genk_exponential(double gen_nr, double p); genk_normal(double gen_nr, double mean, double variance); genk_truncnormal(double gen_nr, double mean, double variance); - other: correct(const char *) got renamed to opp_nulltoempty(const char *) - compat.h: removed some very old compatibility #defines - cStringTokenizer: added asIntVector() and asDoubleVector() methods - cXMLElement, xmldoc(): mini-XPath expressions made more tolerant to whitespace - added cHasher for calculation of simulation fingerprints - snapshot file became XML - marked deprecated methods with the new _OPPDEPRECATED macro, which results in warnings during compilation of code that uses deprecated API. _OPPDEPRECATED relies on gcc's __attribute__((__deprecated__)) and MSVC's __declspec(deprecated) features. - several header files got renamed; this should not affect simulation model code, as such code should #include <omnetpp.h> only. Microsoft Visual C++: - MSVC 6.0 support dropped (the compiler is over 10+ years old, and does not support many modern C++ features like covariant return types) - VC++ libs compiled with /MT (mulTithreaded C lib) with VC7.1 as well OMNeT++ 3.3 ~~~~~~~~~~~ no changes in public APIs OMNeT++ 3.2 (Oct 2005) ~~~~~~~~~~~~~~~~~~~~~~ (!) user-written module classes: expected signature of module constructors simplified, from cModule(const char *name, cModule *parent) and cSimpleModule(const char *name, cModule *parent, unsigned stack) to cModule() and cSimpleModule(unsigned stack=0) The purpose is to ease writing constructors, e.g. for a handleMessage() module class "PacketSink : public cSimpleModule", the constructor is just PacketSink() {} instead of the former PacketSink(const char *name, cModule *parent) : cSimpleModule(name, parent, 0) {} Backwards compatibility: module classes using Module_Class_Members() (95%) are not affected. For module classes using hand-coded constructors, adding NULL as a default value to the "name" and "parent" ctor arguments will make the class work with both OMNeT++ 3.2 and earlier versions: PacketSink(const char *name=NULL, cModule *parent=NULL) : cSimpleModule(name, parent, 0) {} This affects very few modules, e.g. two in the current INET Framework release. Motivation: since cleanup-time garbage collection is off by default in OMNeT++ 3.2, users are encouraged to write proper destructors. However, destructors can only be written if constructors set pointer members of the class to NULL. (This is currently customarily done in the initialize() method; however, pointers must be initialized to NULL even if initialize() doesn't get called due to a runtime error earlier in another module's initialize(), otherwise the destructor will crash.) The Module_Class_Members() macro (currently used in 95% of the cases) defines an empty constructor, one cannot put statements into it -- so one must use hand-coded constructors. The new signature of constructors makes it possible to write much more compact code, and will make it more comfortable for users. (-) deprecated Module_Class_Members() -- see above (+) cModule: modules can now get notified when a module parameter changes, by redefining the new handleParameterChange(const char *parname) virtual method of cModule. (+) cSimpleModule: added method cancelAndDelete(cMessage *msg), for use in simple module destructors. (!) dup() method of cObject moved up to cPolymorphic, and the return type changed to cPolymorphic. Once we drop MSVC 6.0 support, return types can be changed to class itself, i.e. in class Foo it can be defined as Foo *dup(). Unfortunately MSVC 6.0 doesn't support covariant return types. Other compilers do. (!) cMessage: implemented reference counting of encapsulated messages. There is one implication: ONE MUST NOT CHANGE ANYTHING IN A MESSAGE ENCAPSULATED IN ANOTHER MESSAGE! That's because the encapsulated message might be shared among several other messages. (+) cMessage length can now be get/set in bytes as well, not only in bits: added byteLength(), setByteLength(), addByteLength() convenience functions. They just invoke the length(), setLength(), addLength() methods, combined with a multiplication or division by 8. (+) cMessage: added cModule *senderModule() method (!) cMessage: if "vector" is a vector gate, msg->arrivedOn("vector") now checks if msg arrived one of the vector's gates. (+) cOutVector: added recordWithTimestamp() method, to make it possible to record values into output vectors with a timestamp other than simTime(). Increasing timestamp order is still enforced. (+) cPar: added isConstant() member to cPar (+) cPar: added default value to type parameter of setFromText() (+) WATCH() implementation changed: now anything can be watched that has operator<<. If it also has operator>> and it gets watched via WATCH_RW(), it can also be modified from the GUI. Objects and pointers to objects can also be watched with WATCH_OBJ() and WATCH_PTR(). (+) added macros to watch STL containers: WATCH_VECTOR(), WATCH_PTRVECTOR(), WATCH_LIST(), WATCH_PTRLIST(), WATCH_SET(), WATCH_PTRSET(), WATCH_MAP(), WATCH_PTRMAP(). (+) cDisplayString: added setTagArg() method for numeric (long) argument as well. Just converts it to string and calls the other setTagArg(). (+) cXMLElement: added getFirstChildWithTagName(const char *tagname) and getNextSiblingByTagName(const char *tagname) methods (!) cXMLElement: several member functions made const (+) added cStringTokenizer::hasMoreTokens() convenience method (+) added simtimeToStrShort() (!) moved packObject(), unpackObject(), checkFlag(), isNull() methods (last one renamed to packFlag) into cCommBuffer (!) cOutputVectorManager, cOutputScalarManager interfaces: added flush() OMNeT++ 3.1 (Mar 2005) ~~~~~~~~~~~~~~~~~~~~~~ Simulation library: (+) added cStringTokenizer class (+) extended cScheduler interface, added cRealTimeScheduler class (!) cDisplayString's getTagArg() method now never return NULLs (returns empty string "" instead) (+) added getBaseDirectoryFor() and getLocation() to cConfiguration (+) introduced cRuntimeError class, a subclass of cException OMNeT++ 3.0 (Dec 2004) ~~~~~~~~~~~~~~~~~~~~~~ Simulation library: (x) removed setOwner() with no replacement. Use take() from within objects, e.g. foo->setOwner(this) should be replaced with this->take(foo) or just take(foo). Some existing simulation models used setOwner() to "work around" (hack) message ownership problems instead of tracking them down and fixing them properly -- the intent of removing setOwner() is to close this backdoor. (x) removed putAsideQueue, receiveOn(), receiveNewOn(), receiveNew(); only receive() remained. (!!!) wait() throws an exception if a message arrives during the hold period. If messages should be allowed, use waitAndEnqueue(). (!!!) fullPath() return value changed from const char * to std::string. If it occurs in a printf-like function as "%s" (sprintf, ev.printf,...) it has to be changed to fullPath().c_str(), otherwise printf may crash. (!) signature of info(char buf, int buflen) changed to std::string info(). (!) cSimpleModule::recordScalar() for writing const char* data removed, with no replacement. (!) cSimpleModule::recordStats(cStatistic *x) was removed. Replacement is x->recordScalar(). (+) added setControlInfo(), controlInfo(), removeControlInfo() methods to cMessage. Control info is the preferred way of passing info (additional to the packet itself) between protocol layers. (!) cMessage default length changed from 1 to 0 (bits). (!) NED: default gate vector size (e.g. if gatesizes is omitted) changed from 1 to 0 (x) removed cGate::link() (+) added cChannelType class and findChannelType() function (+) added cGate::disconnect() (!) cGate::connect() semantics slightly changed (see API documentation) (+) added cModule::gateSize() (+) added cModule::changeParentTo() (+) added cSimulation::getUniqueNumber(). Useful in models for ID generation, and (unlike incrementing global vars) it also works with parallel execution (-) cDisplayStringParser renamed to cDisplayString (compatibility typedef exists) (+) displayString() methods of cModule and cGate return reference to internally stored cDisplayString objects which can now be manipu- lated directly (no need for setDisplayString(const char *)). (+) ev.isGUI() added. Returns true if simulation runs under Tkenv. Display string updates and bubble() calls can be made conditional on this. (+) added method bool disabled() to cEnvir (to ev object); returns true when ev<< output is disabled, such as in Express mode in Tkenv and Cmdenv. (+) cModule::bubble() added. It displays a transient "bubble" over the module icon in Tkenv, does nothing in Cmdenv. (-) discouraged use of classes cBag and cLinkedList. STL classes such as std::vector, std::list or std::deque should be used instead. (+) cStatistic::recordScalar() added (+) New random number architecture: added cRNG interface and subclasses cMersenneTwister and cLCG32; added cRNG *cEnvir::rng(k) and cRNG *Module::rng(k) (!) New random number architecture. Following symbols/functions fell victim: #define NUM_RANDOM_GENERATORS -- this is now in omnetpp.ini #define INTRAND_MAX -- different for every RNG class; cRNG::intRandMax() returns it int testrand() -- see cRNG::selfTest() long opp_nextrand(long& seed) -- no replacement void opp_randomize() -- no replacement long randseed() -- no replacement (Mersenne Twister state doesn't fit in 32 bits!) long randseed(long seed) -- no replacement (seeding from C++ not supported) long intrand() -- see cRNG::intRand() void genk_opp_randomize(int gen_nr) -- no replacement (see above) long genk_randseed(int gen_nr) -- no replacement (see above) long genk_randseed(int gen_nr, long seed) -- no replacement (see above) long genk_intrand(int gen_nr) -- see cRNG::intRand() (+) added two utility functions to cTopology: void extractByModuleType(const char **types) void extractByModuleType(const std::vector<std::string> types) (+) added class cXMLElement, to support NED's new XML parameter type (+) added methods to cPar: setXMLValue(cXMLElement*), cXMLElement *xmlValue(), op=(cXMLElement*), op cXMLElement*(). (+) added cConfiguration class, an abstract base class for configuration managers (generalization of omnetpp.ini). cConfiguration makes it possible to use different sources than omnetpp.ini, e.g. database or XML. (+) added method cConfiguration *config() to cEnvir (i.e. ev object) (-) deprecated classes cBag and cLinkedList. STL classes such as std::vector, std::list or std::deque are recommended instead. OMNeT++ 2.3 (June 16, 2003) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Simulation library: (-) deprecated cPacket. Please do not use it in new models. Protocol should be represented in the message subclass (i.e. instances of class IPv6Packet represent IPv6 packets, and/or in the message kind value. PDU is usually represented as a field inside the message class (a protocol header field). See rationale in User Manual. (-) deprecated setOwner(). In constructors of new classes, use take(obj) to take ownership of a member/contained object. Other than that, there should be no reason to use setOwner()! setOwner() will probably be removed as early as the next release of OMNeT++. (+) message subclassing: generated message classes now accept message kind in the constructor. OMNeT++ 2.3b1 (Jan 13, 2003) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Simulation library: (+) new distributions: continuous distributions gamma_d(), beta(), erlang_k(), chi_square(), student_t(), cauchy(), triang(), lognormal(), weibull(), pareto_shifted(); discrete distributions bernoulli(), binomial(), geometric(), negbinomial(), poisson(). [contributed by Werner Sandmann] (+) exceptions are used throughout the simulation library to signal errors. You can also use try...catch in your code. (+) RTTI (Run-time Type Information) is also turned on, so you can use dynamic_cast in your code. (+) added check_and_cast<T>(cObject *p) template function -- it can be used to assert that a pointer is of the given T type. It does dynamic_cast<T> and throws exception if the result is NULL (ie. pointer types are incompatible). Useful with message subclassing. (!!!) MSVC compile flags change: exception handling and RTTI MUST be ON from now. You must compile EVERY source file using /GR, otherwise simulations will crash with RTTI exception! (!) redefining className() in your classes is now not necessary (because the simulation kernel can figure it out in cObject::className()). (+) because of the introduction of C++ exception handling, methods like end(), endSimulation() and deleteModule() as well as any runtime error cause handleMessage() to exit immediately. (In earlier versions, handleMessage() went through in any case.) (-) deprecated genk_* functions. The RNG should be given as an extra optional attribute of "genk"-less functions instead. (-) rarely-used methods cSimpleModule::error(), opp_error() and opp_warning() were deprecated; they will be removed at some point in the future. (+) cWatch now supports 'bool' (+) new method waitAndEnqueue() added to cSimpleModule -- this function should be used instead of wait() in places where messages may arrive at the module during the wait interval. (see next items) (!) use wait() ONLY where you do NOT expect other messages to arrive at the module, and receiveOn() only where you expect the mext message to arrive on the specified gate. In a later release, wait() will throw an error if a message arrives to it (or, with receiveOn(), if the message arrives on the wrong gate), assuming it's an error in the model logic. Where necessary, replace wait() with waitAndEnqueue(). putAsideQueue will be removed some time in the future (see next item). (-) deprecated putAsideQueue. putAsideQueue has been only used by the methods wait(), receiveOn() (and receiveNewOn()). It stored "wrong" messages (that arrive during the wait period or not on the specified gate). Because of putAsideQueue, the receive() methods had to have 2 versions: receive..() and receiveNew..(). Practice has shown that the usefulness of putAsideQueue was marginal, its purpose was more often misunderstood than not, its implicit use by wait() and the message receiving functions was highly error-prone. It also bloated the API (receiveNew functions wouldn't have been needed without it). On the other hand, it is easy to provide the needed behavior of wait() using waitAndEnqueue(), or a loop with receive(). putAsideQueue will be removed at some point in the future. (!) do not use the receiveNew..() functions as they will be made redundant when putAsideQueue goes away. (+) added ev.flush(), although in most cases using the autoflush=yes/no ini file option is a better idea (-) cSimplemodule: deprecated phase() (nobody really used it) (+) added macro Define_Function2 (!) several smaller auxiliary classes were made inner classes to their 'main' classes. (Examples: cQueueIterator --> cQueue::Iterator, sTopoNode --> cTopology::Node, etc; full list in include/ChangeLog.) Compatibility typedefs exist for old names but they will be removed at some point in the future. (!) refactoring on dynamic module creation: instead of modtype->buildInside(mod), one should now write mod->buildInside(), which is more natural. (Former syntax still works -- a cModuleType::buildInside() is still provided for backward compatibility). buildInside() delegates task to doBuildInside() (a new method), so it's doBuildInside() which should be redefined in subclasses, and also nedc generates now doBuildInside() code. (i) container objects are now more consistent in what they do when the requested object doesn't exist: * Convention 1: methods returning an object reference (e.g. cPar&) now always throw an exception if the object is not found. (Until now, some methods issued a warning and returned null reference, i.e. *(cPar*)NULL). * Convention 2: methods returning a pointer (e.g. cGate*) return NULL pointer if the object is not found. (Until now, some methods issued a warning and returned NULL pointer.) These conventions necessitated some changes (see next items): (!) par() of cModule and cMessage now throws an exception if parameter was not found. (Check for existence of a parameter before accessing it can now be replaced with try..catch if you want!) (!) cModule: cGate *gate() methods no longer issue a warning if the gate is not found, just return NULL. (!) cArray::remove(cObject *) and cQueue::remove(cObject *) methods now return NULL instead of the original pointer if the object was not found. (+) cArray: new set(cObject*) method adds optional hashtable-like behaviour to cArray: this method replaces the object with the same name in the array. (!) cSimulation changes: lastModuleIndex() renamed to lastModuleId(); del() renamed to deleteModule(); add() renamed to addModule() (-) cSimulation: operator[] deprecated (use module(int) method instead to access a module by id) (+) channels are now represented by real objects (subclassed from cChannel) rather than parameters in cGate. Channels can be assigned to connections via cGate's setChannel() method; (-) deprecated cGate's setDelay(), setError(), setDatarate(), setLink() methods (these attributes should be now set on the channel object). (-) cSubModIterator: operator[] deprecated (use operator()(int) method instead) (+) cGate: added isConnectedOutside() and isConnectedInside() utility methods (+) cGate: added connectTo() method (setFrom() and setTo() got deprecated, see next item) (-) deprecated cGate's setFrom() and setTo() methods (use connectTo() instead) (+) cMessage: added convenience methods for attaching objects to a message: addObject(), getObject(), hasObject(), removeObject(). User interfaces: (!) Cmdenv: obsoleted omnetpp.ini entries: display-update=, verbose-simulation=; they should be replaced with simplified and more powerful options, see next item: (+) Cmdenv: introduced express-mode=yes/no (default: no) switch, with meaning similar to Tkenv (non-express mode: detailed information printed; express mode: only periodic status updates). (+) Cmdenv: in normal mode (express-mode=no), the following new ini file entries are understood: module-messages=yes/no (default: yes) printing module ev<< output on/off (as before) event-banners=yes/no (default: yes) printing event banners on/off; replaces verbose-simulation= message-trace=yes/no (default: no) log message sending (by send(),scheduleAt(), etc) and delivery on standard output (+) Cmdenv: in express mode, following new entries are supported: status-frequency=<integer> (default: 100000) print status update every n events (on today's computers, and for a typical simulation model, default value will produce an update perhaps in every few seconds) performance-display=yes/no (default: yes) print detailed (2-line) performance status (+) Cmdenv: new ini file option: autoflush=yes/no (default: no). Causes fflush(stdout) to be called after each output (event banner, status update, ev<< output, etc). This affects both express and normal mode. (+) Cmdenv: new ini file option: message-trace=yes/no (default: no). This causes logging each message sending (by send(),scheduleAt(), etc) and message delivery on the standard output; effective only in normal mode. (+) Envir (Cmdenv+Tkenv): integrated Steffen Sroka's Akaroa extension that supports multiple independent simulation runs. Akaroa can be activated by specifying [General] outputvectormanager-class=AkOutputVectorManager in the ini file. By default, all output vectors are under Akaroa control; the <modulename>.<vectorname>.akaroa=false setting can be used to make Akaroa ignore specific vectors. For more info see the Akaroa home page and the OMNeT++ documentation. (+) Envir (Cmdenv+Tkenv): added fname-append-host=true/false ini file setting. When turned on, appends the host name to the names of the output files (output vector, output scalar, snapshot files). This is useful when the simulation is run on multiple machines concurrently (parallel independent runs (Akaroa) or parallel/distributed simulation), and all running instances write to the same directory (e.g. shared via NFS mount). [Idea from Steffen Sroka's Akaroa extension] (i) Tkenv: with "ring" layout, changed display order of modules from clockwise to the more natural counter-clockwise (!) Tkenv: changed positioning of vector modules with display string "p=x,y" (that is, with position, but no explicit layout parameter). "p=x,y" now ALWAYS means "p=x,y,exact", that is, the module is placed at (x,y). Before, "p=x,y" meant "p=x,y,row" or "p=x,y,ring" (where "row or ring" is a default layout) if the module was in a vector, and this caused counterintuitive displacements if a module was placed individually, because a (dx,dy) shift coming from the layout was superponed onto the position (x,y)). OMNeT++ 2.2 (May 2002) ~~~~~~~~~~~~~~~~~~~~~~ (+) The simulation kernel was made const-correct; because of this, older code may need changes (especially where one didn't use the Module_Class_Members() macro to define module classes.) (!) cModule's display string methods were reorganized: the displayString(int type) method was split into displayString() and displayStringAsParent(), eliminating the type parameter. Similar change was made to the set...() methods. (Old methods remained but are now deprecated.) (+) New methods: opp_nextrand(long& seed); opp_strlen(..); opp_strprettytrunc(..); opp_mkindexedname(..) (the latter was formerly called indexedname()). (+) fullName() no longer uses a static buffer; with fullPath(), it is possible to avoid static buffers by using the new fullPath(buffer,buflen) method. (+) In NED, an expression may now refer to a submodule parameter with the following syntax: submod.par or submod[index].par. The index may not be an expression itself. OMNeT++ 2.1 (May 2001) OMNeT++ 2.0 patch 1 (March 2001) OMNeT++ 2.0 (February 2001) OMNeT++ 2.0b5 (June 2000) No changes affecting code portability across versions. OMNeT++ 2.0b4 (May 2000) ~~~~~~~~~~~~~~~~~~~~~~~~ Simulation library: (!) The source was made 'const char *'-correct (-) deprecated TRUE/FALSE: the C++ true/false keywords should be used instead (+) multi-stage module initialization support via cModule's initialize(int stage) and int numInitStages() functions. (+) the send...() functions now have versions which take cGate* pointers. (+) sum() and sqrSum() members added to the statistics classes (cStdDev and subclasses) (+) isNumeric() member added to cPar (+) remove(cObject *) added to cArray. (+) functions added to cModule to facilitate navigating the module hierarchy: int findSubmodule(...), cModule *submodule(...) and cModule *moduleByRelativePath(...). User interfaces: (+) you may link more than one user interfaces into the simulation executable, and select one at runtime with the [General]/user-interface=Tkenv (or =Cmdenv) ini file option or the -u Tkenv (or -u Cmdenv) command-line argument to the simulation executable. (+) The per-module extra stack size needed by the user interface libraries can now be configured from the ini file: [Cmdenv]/extra-stack= and [Tkenv]/extra-stack= options.