Project

General

Profile

Statistics
| Branch: | Revision:

root / src / sim / cchannel.cc @ a3be1d55

History | View | Annotate | Download (5.26 KB)

1 01873262 Georg Kunz
//========================================================================
2
//  CCHANNEL.CC - part of
3
//
4
//                 OMNeT++/OMNEST
5
//              Discrete System Simulation in C++
6
//
7
//   Member functions of
8
//    cChannel : channel class
9
//
10
//========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#include "cchannel.h"
21
#include "cpar.h"
22
#include "cgate.h"
23
#include "cmessage.h"
24
#include "cmodule.h"
25
#include "cenvir.h"
26
#include "csimulation.h"
27
#include "globals.h"
28
#include "cexception.h"
29
30
#ifdef WITH_PARSIM
31
#include "ccommbuffer.h"
32
#endif
33
34
USING_NAMESPACE
35
36
using std::ostream;
37
38
Register_Class(cIdealChannel);
39
40
41
void cChannel::MessageSentSignalValue::error() const
42
{
43
    throw cRuntimeError("cChannel::MessageSentSignalValue: getter for unsupported value type called");
44
}
45
46
cChannel::cChannel(const char *name) : cComponent(name)
47
{
48
    srcgatep = NULL;
49
    connId = -1;
50
}
51
52
cChannel::~cChannel()
53
{
54
    releaseLocalListeners();
55
}
56
57
std::string cChannel::info() const
58
{
59
    // print all parameters
60
    std::stringstream out;
61
    for (int i=0; i<getNumParams(); i++)
62
    {
63
        cPar& p = const_cast<cChannel *>(this)->par(i);
64
        out << p.getFullName() << "=" << p.info() << " ";
65
    }
66
    return out.str();
67
}
68
69
void cChannel::forEachChild(cVisitor *v)
70
{
71
    cDefaultList::forEachChild(v);
72
}
73
74
void cChannel::parsimPack(cCommBuffer *buffer)
75
{
76
    throw cRuntimeError(this,"parsimPack() not implemented");
77
}
78
79
void cChannel::parsimUnpack(cCommBuffer *buffer)
80
{
81
    throw cRuntimeError(this,"parsimUnpack() not implemented");
82
}
83
84
void cChannel::finalizeParameters()
85
{
86
    if (!srcgatep)
87
        throw cRuntimeError(this,"finalizeParameters() may only be called when the channel is already installed on a connection");
88
    cComponent::finalizeParameters();
89
}
90
91
void cChannel::callInitialize()
92
{
93
    cContextTypeSwitcher tmp(CTX_INITIALIZE);
94
    int stage = 0;
95
    while (initializeChannel(stage))
96
        ++stage;
97
}
98
99
bool cChannel::callInitialize(int stage)
100
{
101
    // note: numInitStages() will be checked inside initializeChannel()
102
    cContextTypeSwitcher tmp(CTX_INITIALIZE);
103
    return initializeChannel(stage);
104
}
105
106
bool cChannel::initializeChannel(int stage)
107
{
108
    // channels don't contain further subcomponents, so just we just invoke
109
    // initialize(stage) in the right context here.
110
    if (simulation.getContextType()!=CTX_INITIALIZE)
111
        throw cRuntimeError("Internal function initializeChannel() may only be called via callInitialize()");
112
113
    if (stage==0)
114
    {
115
        if (initialized())
116
            throw cRuntimeError(this, "Channel already initialized");
117
118
        // call finalizeParameters() if user has forgotten to do it; this is needed
119
        // to make dynamic module/channel creation more robust
120
        if (!parametersFinalized())
121
            finalizeParameters();
122
    }
123
124
    int numStages = numInitStages();
125
    if (stage < numStages)
126
    {
127
        // switch context for the duration of the call
128
        cContextSwitcher tmp(this);
129
        ev.componentInitBegin(this, stage);
130
        try {
131
            initialize(stage);
132
        } catch (cException&) {
133
            throw;
134
        } catch (std::exception& e) {
135
            throw cRuntimeError("%s: %s", opp_typename(typeid(e)), e.what());
136
        }
137
    }
138
139
    bool moreStages = stage < numStages-1;
140
141
    // as a last step, call handleParameterChange() to notify the component about
142
    // parameter changes that occured during initialization phase
143
    if (!moreStages)
144
    {
145
        setFlag(FL_INITIALIZED, true);
146
        handleParameterChange(NULL);
147
    }
148
    return moreStages;
149
}
150
151
void cChannel::callFinish()
152
{
153
    // This is the interface for calling finish(). Channels don't contain further
154
    // subcomponents, so just we just invoke finish() in the right context here.
155
    cContextSwitcher tmp(this);
156
    cContextTypeSwitcher tmp2(CTX_FINISH);
157
    try {
158
        recordParametersAsScalars();
159
        finish();
160
        fireFinish();
161
    } catch (cException&) {
162
        throw;
163
    } catch (std::exception& e) {
164
        throw cRuntimeError("%s: %s", opp_typename(typeid(e)), e.what());
165
    }
166
}
167
168
cModule *cChannel::getParentModule() const
169
{
170
    // find which (compound) module contains this connection
171
    if (!srcgatep)
172
        return NULL;
173
    cModule *ownerMod = srcgatep->getOwnerModule();
174
    if (!ownerMod)
175
        return NULL;
176
    return srcgatep->getType()==cGate::INPUT ? ownerMod : ownerMod->getParentModule();
177
}
178
179
cProperties *cChannel::getProperties() const
180
{
181
    cModule *parent = getParentModule();
182
    cComponentType *type = getComponentType();
183
    cProperties *props;
184
    if (parent)
185
        props = parent->getComponentType()->getConnectionProperties(connId, type->getFullName());
186
    else
187
        props = type->getProperties();
188
    return props;
189
}
190
191
bool cChannel::isBusy() const
192
{
193
    // a default implementation
194
    return simTime() < getTransmissionFinishTime();
195
}
196
197
//----
198
199
cIdealChannel *cIdealChannel::create(const char *name)
200
{
201
    return dynamic_cast<cIdealChannel *>(cChannelType::getIdealChannelType()->create(name));
202
}