Statistics
| Branch: | Revision:

root / src / scave / compoundfilter.cc @ e1750c09

History | View | Annotate | Download (6.33 KB)

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

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17
18
#include <string.h>
19
#include "commonutil.h"
20
#include "compoundfilter.h"
21
#include "filternodes.h"
22
#include "nodetyperegistry.h"
23
24
USING_NAMESPACE
25
26
27
bool CompoundFilterType::Subfilter::operator==(const CompoundFilterType::Subfilter& other) const
28
{
29
    return _nodetype==other._nodetype &&
30
           _comment==other._comment &&
31
           _attrassignments==other._attrassignments;
32
}
33
34
const char *CompoundFilterType::getName() const
35
{
36
    return _name.c_str();
37
}
38
39
const char *CompoundFilterType::getDescription() const
40
{
41
    return _description.c_str();
42
}
43
44
void CompoundFilterType::setName(const char *s)
45
{
46
    _name = s;
47
}
48
49
void CompoundFilterType::setDescription(const char *s)
50
{
51
    _description = s;
52
}
53
54
CompoundFilterType& CompoundFilterType::operator=(const CompoundFilterType& other)
55
{
56
    _name = other._name;
57
    _description = other._description;
58
    _hidden = other._hidden;
59
    _attrs = other._attrs;
60
    _defaults = other._defaults;
61
    _subfilters = other._subfilters;
62
    return *this;
63
}
64
65
bool CompoundFilterType::equals(const CompoundFilterType& other)
66
{
67
    // ignore name (they're surely different)
68
    // ignore "hidden" flag too
69
    return _description==other._description &&
70
           _attrs==other._attrs &&
71
           _defaults==other._defaults &&
72
           _subfilters==other._subfilters;
73
}
74
75
void CompoundFilterType::getAttributes(StringMap& attrs) const
76
{
77
    attrs = _attrs;
78
}
79
80
void CompoundFilterType::getAttrDefaults(StringMap& attrs) const
81
{
82
    attrs = _defaults;
83
}
84
85
void CompoundFilterType::setAttr(const char *name, const char *desc, const char *defaultval)
86
{
87
    _attrs[name] = desc;
88
    _defaults[name] = defaultval;
89
}
90
91
void CompoundFilterType::removeAttr(const char *name)
92
{
93
    _attrs.erase(std::string(name));
94
    _defaults.erase(std::string(name));
95
}
96
97
int CompoundFilterType::getNumSubfilters() const
98
{
99
    return _subfilters.size();
100
}
101
102
CompoundFilterType::Subfilter& CompoundFilterType::getSubfilter(int pos)
103
{
104
    if (pos<0 || pos>=(int)_subfilters.size())
105
        throw opp_runtime_error("%s: invalid subfilter index %d", getName(), pos);
106
    return _subfilters[pos];
107
}
108
109
const CompoundFilterType::Subfilter& CompoundFilterType::getSubfilter(int pos) const
110
{
111
    if (pos<0 || pos>=(int)_subfilters.size())
112
        throw opp_runtime_error("%s: invalid subfilter index %d", getName(), pos);
113
    return _subfilters[pos];
114
}
115
116
void CompoundFilterType::insertSubfilter(int pos, const Subfilter& f)
117
{
118
    if (pos<0 || pos>(int)_subfilters.size())
119
        throw opp_runtime_error("%s: invalid subfilter insert index %d", getName(), pos);
120
    _subfilters.insert(_subfilters.begin()+pos, f);
121
}
122
123
void CompoundFilterType::removeSubfilter(int pos)
124
{
125
    if (pos<0 || pos>=(int)_subfilters.size())
126
        throw opp_runtime_error("%s: invalid subfilter index %d", getName(), pos);
127
    _subfilters.erase(_subfilters.begin()+pos);
128
}
129
130
Node *CompoundFilterType::create(DataflowManager *mgr, StringMap& attrs) const
131
{
132
    CompoundFilter *node = new CompoundFilter();
133
    node->setNodeType(this);
134
    mgr->addNode(node);
135
    node->_attrvalues = attrs;
136
137
    int n = getNumSubfilters();
138
    if (n==0)
139
    {
140
        FilterNode *subnode = new NopNode();
141
        mgr->addNode(subnode);
142
        node->first = node->last = subnode;
143
    }
144
    Node *prevsubnode = NULL;
145
    for (int i=0; i<n; i++)
146
    {
147
        Subfilter& subfilt = const_cast<CompoundFilterType *>(this)->getSubfilter(i);
148
149
        // get type
150
        const char *subnodetypename = subfilt.getNodeType();
151
        NodeType *subnodetype = NodeTypeRegistry::getInstance()->getNodeType(subnodetypename);
152
153
        // collect parameters for subfilter
154
        StringMap subattrs;
155
        StringMap subattrsall = subfilt.attrAssignments();
156
        // pick needed attrs
157
        StringMap allowedattrs;
158
        subnodetype->getAttributes(allowedattrs);
159
        for (StringMap::iterator aattr=allowedattrs.begin(); aattr!=allowedattrs.end();++aattr)
160
            subattrs[aattr->first] = subattrsall[aattr->first];
161
        // now perform param substitutions
162
        for (StringMap::iterator subattr1=subattrs.begin(); subattr1!=subattrs.end(); ++subattr1)
163
        {
164
            StringMap::iterator attrfound = attrs.find(subattr1->second);
165
            if (attrfound!=attrs.end())
166
                subattr1->second = attrfound->second;
167
        }
168
169
        // create and add instance
170
        FilterNode *subnode = dynamic_cast<FilterNode *>(subnodetype->create(mgr,subattrs));
171
        if (!subnode)
172
            throw opp_runtime_error("%s: subfilter type %s is not subclassed from FilterNode", getName(), subnodetypename);
173
        if (i==0)
174
            node->first = subnode;
175
        if (i==n-1)
176
            node->last = subnode;
177
178
        // connect to next one
179
        if (prevsubnode)
180
        {
181
            Port *port1 = prevsubnode->getNodeType()->getPort(prevsubnode,"out");
182
            Port *port2 = subnode->getNodeType()->getPort(subnode,"in");
183
            mgr->connect(port1, port2);
184
        }
185
        prevsubnode = subnode;
186
    }
187
188
    return node;
189
}
190
191
Port *CompoundFilterType::getPort(Node *node, const char *name) const
192
{
193
    CompoundFilter *compound = dynamic_cast<CompoundFilter *>(node);
194
    Node *subnode = !strcmp(name,"in") ? compound->getFirstNode() :
195
                    !strcmp(name,"out") ? compound->getLastNode() :
196
                    NULL;
197
    if (!subnode)
198
        throw opp_runtime_error("no such port `%s'", name);
199
    return subnode->getNodeType()->getPort(subnode, name);
200
}
201
202
void CompoundFilterType::mapVectorAttributes(/*inout*/StringMap &attrs, /*out*/StringVector &warnings) const
203
{
204
    int n = getNumSubfilters();
205
    for (int i=0; i<n; i++)
206
    {
207
        const char *nodetypename = getSubfilter(i).getNodeType();
208
        NodeType *nodeType = NodeTypeRegistry::getInstance()->getNodeType(nodetypename);
209
        nodeType->mapVectorAttributes(attrs, warnings);
210
    }
211
}