Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Data Structures   File List   Namespace Members   Data Fields   Globals   Related Pages   Examples  

Port2.cpp

This example demonstrates a migration from ODEM to ODEMx. The original Port2 simulation was taken from ODEM and adjusted to run with ODEMx. Port2 simulates a port with tides. The original source-code is preserved in this file to show the differences.

//----------------------------------------------------------------------------
//      Copyright (C) 2002, 2003 Humboldt-Universitaet zu Berlin
//
//      This library is free software; you can redistribute it and/or
//      modify it under the terms of the GNU Lesser General Public
//      License as published by the Free Software Foundation; either
//      version 2.1 of the License, or (at your option) any later version.
//
//      This library is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//      Lesser General Public License for more details.
//
//      You should have received a copy of the GNU Lesser General Public
//      License along with this library; if not, write to the Free Software
//      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning(disable:4530) // exception handling disabled
#pragma warning(disable:4786) // 255 character truncation of debug information
#endif

/*
// Beispiel 4: Hafenabfertigung mit Gezeiten
#include "odem.h"

        ODEMx requires different include files than ODEM. The
        most simple solution is to include odemx.h. This file
        in turn includes other header from ODEMx. All classes
        of ODEMx are placed in the namespace ODEMx. In this simple
        example it is safe to use the whole namespace. 
*/
#include <odemx/odemx.h>

using namespace odemx;

/*
#ifdef _USE_GL
#include "grtrace.h"
#endif

        ODEMx does not support the GrTrace from ODEM.

        In ODEMx all model components require a pointer to the
        simulation. In general a user would provide a class for
        its special simulation which would inherit the ODEMx
        Simulation class. But for convenience ODEMx also contains
        a default simulation class. The function getDefaultSimulation()
        returns a pointer to an object of this class.
*/

Simulation* sim = getDefaultSimulation();

/*
        The names of the following classes have not been changed between
        ODEM and ODEMx.
*/
Res   *tugs;                            // Schlepper
Res   *jetties;                         // Anlegeplaetze
Condq *dockq;
Rdist *next, *discharge;

/*
class Boat : public Discrete {
public:
        int main ();
        Boat() : Discrete("boat"){}
};

        The ODEM base class Discrete for active model components
        has been replaced by the class Process in ODEMx. As in ODEM
        a user has to provide an implementation of the function
        virtual int main(). The constructor of Process requires,
        in addition to a name, a pointer to the simulation class.
        Another difference between ODEM and ODEMx is, that call-backs
        used for coding conditions or selections are member-functions
        (bool cond1()).
*/
class Boat : public Process {
public:
        int main ();
        Boat() : Process(sim, "boat"){}

        bool cond1();
};

/*
bool cond1();
*/

int Boat::main() {
// im Dock
        jetties->acquire(1);

        /*
        dockq->waituntil(cond1);

        The interface of Condq has changed. In this example
        we have to use wait(...) instead of waituntil(...).
        The cast is required because of the decision to use
        member functions for call-backs. We think the advantages
        outweigh the disadvantages of this cast.
        */
        dockq->wait((Condition)&Boat::cond1);

        tugs->acquire(2);

        /*
        hold(2.0);

        Most scheduling functions have been changed between ODEM and ODEMx.
        hold() for instance is now replaced by a holdFor().
        */
        holdFor(2.0);

        tugs->release(2);
        dockq->signal();

// Loeschen der Ladung
        /*
        hold(discharge->sample());
        */
        holdFor(discharge->sample());

// ablegen
        tugs->acquire(1);

        /*
        hold (2.0);
        */
        holdFor(2.0);

        tugs->release(1);
        jetties->release(1);
        dockq->signal();

        return 0;
}

/*
class Tide : public Discrete {
public:
        static bool low;
        Tide(): Discrete("tide") {}
        int main ();

        (see the comments for Boat)
};
*/
class Tide : public Process {
public:
        static bool low;
        Tide(): Process(sim, "tide") {}
        int main ();
};

bool Tide::low = false;

/*
bool cond1() {

        (see the comments for Boat)
*/
bool Boat::cond1() {
        /*
        return (tugs->avail() >=2) && !Tide::low;

        The function avail() is replaced by getTokenNumber()
        in ODEMx.
        */
        return (tugs->getTokenNumber() >=2) && !Tide::low;
}

int Tide::main() {
        for (;;) {
                // low
                low = true;

                /*
                hold(4.0);
                */
                holdFor(4.0);

                low = false;
                dockq->signal();

                // high
                /*
                hold(9.0);
                */
                holdFor(9.0);
        }
        return 0;
}

/*
class Arrival : public Discrete {
public:
        Boat *b;
        Arrival(): Discrete("arrival") {}
        int main ();
};

        (see the comments for Boat)
*/
class Arrival : public Process {
public:
        Boat *b;
        Arrival(): Process(sim, "arrival") {}
        int main ();
};


int Arrival::main() {
        for (;;) {
                b = new Boat;
                /*
                b->start(NOW);
                hold(next->sample());

                The function start() is not available in
                ODEMx. In ODEMx any hold* or activate* function
                can be used to start a new process.
                */
                b->hold();
                holdFor(next->sample());
        }
        return 0;
}

int main(unsigned int argc, const char* argv[]) {
/*
        InitializeOdemLib(argc, argv);

#ifdef _USE_GL
        trace().addClient(new GrTrace);
#endif
        trace().start();

        It is not necessary to initialise ODEMx.

        The trace system has changed between ODEM and ODEMx.
        The trace management is done by the simulation class.
        A new trace is added with the function addConsumer(...).
        The trace is controlled with startTrace(), stopTrace(),
        pauseTrace() and continueTrace(). HtmlTrace logs the
        simulation events in a html file. It also provides a simple
        filter to reduce the output. Without a filter the ODEMx trace
        logs much more events than its predecessor in ODEM. In
        this example the filter is set to produce an ODEM-like output.

        In ODEMx several reports are available in one simulation to the
        cost of explicitly creating report objects (the class
        HtmlReport is provided by ODEMx) and registering 
        model components to the different reports.

        The results of this simulation can be found in the files
        'Port2_Trace.html' and 'Port2_Report.html'. Trace and report
        of the original ODEM version have been added to the ODEMx package
        for you to compare output and results. They can be found
        along with the Port2.cpp file ('Port2_Trace.txt' and
        'Port2_Report.txt').
*/
        HtmlTrace trace(sim, "Port2_Trace.html");
        HtmlReport report(sim, "Port2_Report.html");
        
        trace.setFilter("all; mtn:changeState, changeExTime, create, time,\
                                         execute process, init, execute, changeTokenNumber,\
                                         current process, run until, sleep");
        sim->addConsumer(&trace);
        sim->startTrace();

        Arrival *a = new Arrival;
        Tide *t = new Tide;

/*
        next = new Negexp("next boat", 0.1);
        discharge = new Normal("discharge", 14.0, 3.0);
        tugs = new Res("tugs", 3);
        jetties = new Res("jetties", 2);
        dockq = new Condq("dockq");

        As already mentioned, in ODEMx most model components require
        a pointer to an object of the simulation class. Res in
        addition does need a maximum token number which can be larger
        than the initial number of available token.
*/
        next = new Negexp(sim, "next boat", 0.1);
        discharge = new Normal(sim, "discharge", 14.0, 3.0);
        tugs = new Res(sim, "tugs", 3, 3);
        jetties = new Res(sim, "jetties", 2, 2);
        dockq = new Condq(sim, "dockq");

        report.addProducer(next);
        report.addProducer(discharge);
        report.addProducer(tugs);
        report.addProducer(jetties);
        report.addProducer(dockq);

        /*
        a->start(NOW);
        t->start(DELAY,1);
        main_Discrete()->hold(50.0);

        (see Arrival::main comments as well)

        In ODEMx the global main function is not integrated as a
        process. The simulation control is instead realised by the
        functions run(), runUntil(...) and step().
        */
        a->activate();
        t->activateIn(1);
        sim->runUntil(50.0);

        /*
        trace().pause();
        */
        sim->pauseTrace();

        /*
        main_Discrete()->hold(28.0*24.0-50.0);
        */
        sim->runUntil(28.0*24.0);

        /*
        report();

        The function generateReport() has to be called for every report.
        Registered model components mustn't be deleted because
        generateReport() gathers data from them.
        */
        report.generateReport();

        return 0;
}


Generated on Mon Aug 11 10:36:06 2003 for ODEMx by doxygen1.3