# API Changes

    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.

    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++ 3.3 (Oct 2006)
    ~~~~~~~~~~~~~~~~~~~~~~
            none

    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 flie 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.