-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCRateCommand.cpp
286 lines (237 loc) · 7.3 KB
/
CRateCommand.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*
This software is Copyright by the Board of Trustees of Michigan
State University (c) Copyright 2005.
You may use this software under the terms of the GNU public license
(GPL). The terms of this license are described at:
http://www.gnu.org/licenses/gpl.txt
Author:
Ron Fox
NSCL
Michigan State University
East Lansing, MI 48824-1321
*/
#include <config.h>
#include "CRateCommand.h"
#include <TCLInterpreter.h>
#include <TCLObject.h>
#include <SpecTcl.h>
#include "CRateList.h"
#include "CRateProcessor.h"
#include <stdint.h>
#ifdef HAVE_STD_NAMESPACE
using namespace std;
#endif
/*!
Construct the rate command. This is just constructing a command with the
name rate:
*/
CRateCommand::CRateCommand(CTCLInterpreter& interp) :
CTCLObjectProcessor(interp, "rate")
{}
CRateCommand::~CRateCommand() {}
/*!
Process the command. In this case we just figure out the
subcommand and dispatch it:
- create -to createRate
- delete -to deleteRate
- list -to listRates.
\param interp : CTCLInterpreter&
Interpreter that is executing this command.
\param objv : std::vector<CTCLObject>& objv
Reference to the Tcl_Obj items that are the command words.
Each Tcl_Obj* is encapsulated in a CTCLObject.
\return int
\retval TCL_OK - Command completed ok.
\retval TCL_ERROR - Command completed in error.
*/
int
CRateCommand::operator()(CTCLInterpreter& interp, vector<CTCLObject>& objv)
{
// We must have at least a single parameter, the subcommand keyword.
if (objv.size() < 2) {
string result = "Need to have at least a subcommand keyword\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
// Branch out depending on the subcommand keyword:
string subcommand = objv[1];
if (subcommand == "create") {
return createRate(interp, objv);
}
if (subcommand == "delete") {
return deleteRate(interp, objv);
}
if (subcommand == "list") {
return listRates(interp, objv);
}
string result = "Invalid command keyword: ";
result += subcommand;
result += "\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
/*!
create a rate object. The rate is created, added to the
beginning of the event processing pipeline (so that update triggers
are after it), and entered into the rate list.
The syntax of the command is:
\verbatim
rate create spectrum
\verbatim
The spectrum must already exist.
Parameters are the same as for operator() as is the return value.
The result will either be empty for success or a descriptive error message.
*/
int
CRateCommand::createRate(CTCLInterpreter& interp,
vector<CTCLObject>& objv)
{
if (objv.size() != 3) {
string result = "Incorrect number of parameters for rate create\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
string spectrumName = objv[2];
SpecTcl* api = SpecTcl::getInstance();
CSpectrum *pSpec = api->FindSpectrum(spectrumName);
if(!pSpec) {
string result = "Spectrum ";
result += spectrumName;
result += " does not exist in rate create command\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
// Now nothing is allowed to go wrong:
// duplications are not fatal and our script front end will prevent them
// in almost all cases.
//
// prepend to the pipeline.
CRateProcessor* processor = new CRateProcessor(*pSpec);
api->InsertEventProcessor(*processor,
api->ProcessingPipelineBegin(),
spectrumName.c_str());
// Add to the rate list.
CRateList* pList = CRateList::getInstance();
pList->addProcessor(*processor);
return TCL_OK;
}
/*!
Delete a rate processor. This
- removes the rate processor from the event processing pipeline
- removes the rate processor from the rate list.
- deletes the rate processor.
syntax is:
\verbatim
rate delete spectrum
\endverbatim
no action is taken unless the event processor can be found in both the
event pipeline and in the rate list..to prevent coincidental removal
of event processors named erroneously.
parameters are for operator() as is the resturn value. The result
is empty unless an error is detected in which case the error message
is set as the result.
*/
int
CRateCommand::deleteRate(CTCLInterpreter& interp,
vector<CTCLObject>& objv)
{
if (objv.size() != 3) {
string result = "Incorrect number of parameters for rate delete\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
string spectrumName = objv[2];
// The following must be true:
// - This must be the name of an event processor that is a
// CRateProcessor.
// - The rate processor must exist in the rate list.
//
SpecTcl* api = SpecTcl::getInstance();
CTclAnalyzer::EventProcessorIterator i = api->FindEventProcessor(spectrumName);
if (i == api->ProcessingPipelineEnd()) {
string result = "Spectrum ";
result += spectrumName;
result += " does not have a rate event processor\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
CEventProcessor* pProcessor = i->second;
CRateProcessor* pRate = dynamic_cast<CRateProcessor*>(pProcessor);
if (!pRate) {
string result = "While an event processor named ";
result += spectrumName;
result += " exists, it is not a rate processor";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
CRateList* pRates = CRateList::getInstance();
CRateList::RateListIterator rle = pRates->find(*pRate);
if (rle == pRates->end()) {
string result = "While a rates processor named ";
result += spectrumName;
result += " exists, it is not in the rates list!!\n";
interp.setResult(result);
return TCL_ERROR;
}
// Now evertying has worked out:
api->RemoveEventProcessor(i);
pRates->deleteProcessor(*pRate);
delete pRate;
return TCL_OK;
}
/*!
List the rates processors.
The following information is listed for each rate (list of sublists)
spectrum name.
- Spectrum name
- Delete pending flag (set by processor when the parameter was yanked out
from underneath it).
- Totals
- Last increments.
*/
int
CRateCommand::listRates(CTCLInterpreter& interp,
vector<CTCLObject>& objv)
{
if (objv.size() != 2) {
string result = "Invalid number of arguments for rate list\n";
result += Usage();
interp.setResult(result);
return TCL_ERROR;
}
CRateList* pList = CRateList::getInstance();
CRateList::RateListIterator i = pList->begin();
CTCLObject result;
result.Bind(interp);
while (i != pList->end()) {
CTCLObject element;
element.Bind(interp);
CSpectrum* pSpec = i->first->getSpectrum();
element += pSpec->getName();
element += (int)i->second;
element += (double)i->first->getTotals();
element += (double)i->first->getIncrements();
result += element;
i++;
}
interp.setResult(result);
return TCL_OK;
}
////// Create the usage string:
string
CRateCommand::Usage()
{
string result;
result = "Usage\n";
result += " rate create spectrum-name\n";
result += " rate delete spectrum-name\n";
result += " rate list\n";
return result;
}