Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / nodetyperegistry.cc @ c87b95b0

History | View | Annotate | Download (5.53 KB)

1
//=========================================================================
2
//  NODETYPEREGISTRY.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 "commonutil.h"
19
#include "nodetyperegistry.h"
20
#include "stringtokenizer.h"
21
#include "arraybuilder.h"
22
#include "vectorfilereader.h"
23
#include "vectorfilewriter.h"
24
#include "indexedvectorfile.h"
25
#include "indexedvectorfilereader.h"
26
#include "indexedvectorfilereader2.h"
27
#include "filewriter.h"
28
#include "windowavg.h"
29
#include "slidingwinavg.h"
30
#include "filternodes.h"
31
#include "mergernodes.h"
32
#include "xyplotnode.h"
33
#include "diffquot.h"
34
#include "customfilter.h"
35
#include "stddev.h"
36
#include "teenode.h"
37

    
38
USING_NAMESPACE
39

    
40
NodeTypeRegistry *NodeTypeRegistry::inst;
41

    
42
NodeTypeRegistry *NodeTypeRegistry::getInstance()
43
{
44
    if (!inst)
45
        inst = new NodeTypeRegistry();
46
    return inst;
47
}
48

    
49
void NodeTypeRegistry::add(NodeType *nodetype)
50
{
51
    nodeTypeMap[nodetype->getName()] = nodetype;
52
}
53

    
54
void NodeTypeRegistry::remove(NodeType *nodetype)
55
{
56
    NodeTypeMap::iterator it = nodeTypeMap.find(nodetype->getName());
57
    if (it!=nodeTypeMap.end())
58
        nodeTypeMap.erase(it);
59
}
60

    
61
NodeTypeRegistry::NodeTypeRegistry()
62
{
63
    add(new ArrayBuilderNodeType());
64
    add(new StddevNodeType());
65
    add(new VectorFileReaderNodeType());
66
    add(new VectorFileWriterNodeType());
67
    add(new IndexedVectorFileWriterNodeType());
68
    add(new IndexedVectorFileReaderNodeType());
69
    add(new IndexedVectorFileReaderNode2Type());
70
    add(new FileWriterNodeType());
71
    add(new MergerNodeType());
72
    add(new AggregatorNodeType());
73
    add(new XYPlotNodeType());
74

    
75
    add(new WindowAverageNodeType());
76
    add(new TimeWindowAverageNodeType());
77
    add(new SlidingWindowAverageNodeType());
78
    add(new MovingAverageNodeType());
79
    add(new DifferenceQuotientNodeType());
80
    add(new NopNodeType());
81
    add(new AdderNodeType());
82
    add(new MultiplierNodeType());
83
    add(new DividerNodeType());
84
    add(new ModuloNodeType());
85
    add(new DifferenceNodeType());
86
    add(new TimeDiffNodeType());
87
    add(new SumNodeType());
88
    add(new TimeShiftNodeType());
89
    add(new LinearTrendNodeType());
90
    add(new CropNodeType());
91
    add(new MeanNodeType());
92
    add(new RemoveRepeatsNodeType());
93
    add(new CompareNodeType());
94
    add(new IntegrateNodeType());
95
    add(new TimeAverageNodeType());
96
    add(new DivideByTimeNodeType());
97
    add(new TimeToSerialNodeType());
98

    
99
    add(new ExpressionFilterNodeType());
100

    
101
    add(new TeeNodeType());
102
}
103

    
104
NodeTypeRegistry::~NodeTypeRegistry()
105
{
106
    for (NodeTypeMap::iterator it=nodeTypeMap.begin(); it!=nodeTypeMap.end(); it++)
107
        delete it->second;
108
}
109

    
110
bool NodeTypeRegistry::exists(const char *name)
111
{
112
    return nodeTypeMap.find(name)!=nodeTypeMap.end();
113
}
114

    
115
NodeType *NodeTypeRegistry::getNodeType(const char *name)
116
{
117
    NodeTypeMap::iterator it = nodeTypeMap.find(name);
118
    if (it==nodeTypeMap.end())
119
        throw opp_runtime_error("unknown node type `%s'", name);
120
    return it->second;
121
}
122

    
123
NodeTypeVector NodeTypeRegistry::getNodeTypes()
124
{
125
    NodeTypeVector vect;
126
    for (NodeTypeMap::iterator it=nodeTypeMap.begin(); it!=nodeTypeMap.end(); it++)
127
        vect.push_back(it->second);
128
    return vect;
129
}
130

    
131
Node *NodeTypeRegistry::createNode(const char *filterSpec, DataflowManager *mgr)
132
{
133
    // parse filterSpec
134
    std::string name;
135
    std::vector<std::string> args;
136
    parseFilterSpec(filterSpec, name, args);
137

    
138
    // look up node type
139
    NodeType *nodeType = getNodeType(name.c_str());
140

    
141
    // check number of args match
142
    StringMap attrs;
143
    nodeType->getAttributes(attrs);
144
    if (attrs.size()!=args.size())
145
        throw opp_runtime_error("error in filter spec `%s' -- %s expects %d parameters", filterSpec, name.c_str(), attrs.size());
146

    
147
    // fill in args map
148
    //FIXME this is completely unsafe! it would be better to match them by name, since ordering in Map is undefined...
149
    StringMap attrValues;
150
    for (StringMap::iterator it=attrs.begin(); it!=attrs.end(); ++it)
151
        attrValues[it->first] = ""; // initialize
152
    nodeType->getAttrDefaults(attrValues);
153
    int i=0;
154
    for (StringMap::iterator it=attrValues.begin(); it!=attrValues.end(); ++it, ++i)
155
        if (!args[i].empty())
156
            it->second = args[i];
157

    
158
    // create filter
159
    return nodeType->create(mgr, attrValues);
160
}
161

    
162
void NodeTypeRegistry::parseFilterSpec(const char *filterSpec, std::string& name, std::vector<std::string>& args)
163
{
164
    args.clear();
165
    const char *paren = strchr(filterSpec, '(');
166
    if (!paren) {
167
        // no left paren -- treat the whole string as filter name
168
        name = filterSpec;
169
        return;
170
    }
171

    
172
    // check that string ends in right paren
173
    if (filterSpec[strlen(filterSpec)-1]!=')')
174
        throw opp_runtime_error("syntax error in filter spec `%s'", filterSpec);
175

    
176
    // filter name is the part before the left paren
177
    name.assign(filterSpec, paren-filterSpec);
178

    
179
    // arg list is the part between the parens -- split it up along commas
180
    std::string arglist(paren+1, strlen(paren)-2);
181
    StringTokenizer tokenizer(arglist.c_str(), ",");
182
    const char *token;
183
    while ((token = tokenizer.nextToken())!=NULL)
184
        args.push_back(token);
185
}
186

    
187