Statistics
| Branch: | Revision:

root / src / sim / clistener.cc @ e26d3d25

History | View | Annotate | Download (4.29 KB)

1 01873262 Georg Kunz
//=========================================================================
2
//  CLISTENER.CC - part of
3
//
4
//                  OMNeT++/OMNEST
5
//           Discrete System Simulation in C++
6
//
7
//=========================================================================
8
9
/*--------------------------------------------------------------*
10
  Copyright (C) 1992-2008 Andras Varga
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16
17
#include "clistener.h"
18
#include "ccomponent.h"
19
#include "cmodule.h"
20
#include "cchannel.h"
21
#include "csimulation.h"
22
23
USING_NAMESPACE
24
25
26
struct Subscription {cComponent *component; simsignal_t signalID;};
27
typedef std::vector<Subscription> SubscriptionList;
28
29
static void findListenerOccurences(cComponent *component, cIListener *listener, SubscriptionList& result)
30
{
31
    std::vector<simsignal_t> signals = component->getLocalListenedSignals();
32
    for (unsigned int i = 0; i < signals.size(); i++)
33
    {
34
        simsignal_t signalID = signals[i];
35
        if (component->isSubscribed(signalID, listener))
36
        {
37
            result.push_back(Subscription());
38
            result.back().component = component;
39
            result.back().signalID = signalID;
40
        }
41
    }
42
43
    if (component->isModule())
44
    {
45
        cModule *module = (cModule *)component;
46
        for (cModule::SubmoduleIterator submod(module); !submod.end(); submod++)
47
            findListenerOccurences(submod(), listener, result);
48
        for (cModule::ChannelIterator chan(module); !chan.end(); chan++)
49
            findListenerOccurences(chan(), listener, result);
50
    }
51
}
52
53
//---
54
55
cIListener::cIListener()
56
{
57
    subscribecount = 0;
58
}
59
60
cIListener::~cIListener()
61
{
62
    if (subscribecount)
63
    {
64
        // note: throwing an exception would is risky here: it would typically
65
        // cause other exceptions, and eventually crash
66
        if (subscribecount < 0)
67
        {
68
            ev.printfmsg("cListener destructor: internal error: negative subscription "
69
                         "count (%d) in listener at address %p", subscribecount, this);
70
            return;
71
        }
72
73
        // subscribecount > 0:
74
        ev.printfmsg("cListener destructor: listener at address %p is still added to "
75
                "%d listener list(s). This will likely result in a crash: "
76
                "Listeners must be fully unsubscribed before deletion. "
77
                "Trying to determine components where this listener is subscribed...",
78
                this, subscribecount);
79
80
        // print components and signals where this listener is subscribed
81
        std::stringstream out;
82
        SubscriptionList list;
83
        findListenerOccurences(simulation.getSystemModule(), this, list);
84
        for (int i=0; i<(int)list.size(); i++) {
85
            out << "- signal \"" << cComponent::getSignalName(list[i].signalID) << "\" (id=" << list[i].signalID << ") ";
86
            out << "at (" << list[i].component->getClassName() << ")" << list[i].component->getFullPath() << "\n";
87
        }
88
        ev.printfmsg("Subscriptions for listener at address %p:\n%s", this, out.str().c_str());
89
    }
90
}
91
92
//---
93
94
void cListener::unsupportedType(simsignal_t signalID, const char *dataType)
95
{
96
    const char *signalName = cComponent::getSignalName(signalID);
97
    throw cRuntimeError("%s: Unsupported signal data type %s for signal %s (id=%d)",
98
                        opp_typename(typeid(*this)), dataType, signalName, (int)signalID);
99
}
100
101
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, long l)
102
{
103
    unsupportedType(signalID, "long");
104
}
105
106
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, unsigned long l)
107
{
108
    unsupportedType(signalID, "unsigned long");
109
}
110
111
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, double d)
112
{
113
    unsupportedType(signalID, "double");
114
}
115
116
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, const SimTime& t)
117
{
118
    unsupportedType(signalID, "simtime_t");
119
}
120
121
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, const char *s)
122
{
123
    unsupportedType(signalID, "const char *");
124
}
125
126
void cListener::receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj)
127
{
128
    unsupportedType(signalID, "cObject *");
129
}
130