Loading...
Searching...
No Matches
Command.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31
32#ifndef DRAINLET_H_
33#define DRAINLET_H_
34
35//#include <map>
36//#include <set>
37//#include "drain/util/Debug.h"
38//#include "drain/util/ReferenceMap.h"
39
40#include <drain/Log.h>
41#include "drain/util/BeanLike.h"
42#include "drain/util/Flags.h"
43#include "drain/util/ReferenceMap.h"
44#include "drain/util/VariableMap.h"
45
46//#include "drain/util/Cloner.h"
47#include "Context.h"
48
49namespace drain {
50
52
55class Command : public Contextual {
56
57public:
58
59
60 inline
61 Command(): section(0){}; //
62
63 inline
64 Command(const Command & cmd) : section(cmd.section), lastParameters(cmd.lastParameters){
65 // setParameters(cmd.getParameters()); they do not exist yet!
66 }
67
68 virtual inline
69 ~Command(){};
70
71
73
76 virtual
77 const std::string & getName() const = 0;
78
79 virtual
80 const std::string & getDescription() const = 0;
81
82 virtual
83 const ReferenceMap & getParameters() const = 0;
84
85 static
86 const SprinterLayout cmdArgLayout; // = {",", "?", "=", ""};
87
88
89public:
90
91 virtual
92 void setParameters(const std::string & args) final;
93
94 // TODO: make this a loop calling set(key,val) - but then no
95 template <class T>
96 void setParameters(const T & args){
97 // TODO: set parameter X=Y ?
98 ReferenceMap & parameters = getParameters();
99 std::stringstream sstr;
100 char separator = 0;
101 for (const auto & entry: args){
102 parameters[entry.first] = entry.second;
103 // setParameter(entry.first, entry.second);
104 if (separator)
105 sstr << separator;
106 else
107 separator = ',';
108 sstr << entry.first << '=' << entry.second;
109 }
110 lastParameters = sstr.str();
111
112 }
113
115
119 template <class T>
120 void setParameter(const std::string & key, const T & value){
121 getParameters()[key] = value;
122 std::stringstream sstr;
123 sstr << key << '=' << value;
124 lastParameters = sstr.str();
125 }
126
127
128
129 // Could also need/replace void setParameters(const std::map<std::string,T> & p)
130
131 inline
132 bool hasParameters() const {
133
134 Logger mout(__FILE__, __FUNCTION__);
135
136 const ReferenceMap & params = this->getParameters();
137 //mout.warn(params );
138
139 const ReferenceMap::const_iterator it = params.begin();
140 if (it == params.end()) // empty
141 return false;
142 else
143 return it->second.getType() != typeid(void); // ???
144 };
145
147 /*
148 virtual inline
149 const std::string & getType() const {
150 static const std::string empty;
151 return empty;
152 };
153 */
154
155
157
160 virtual inline
161 void run(const std::string & params = "") final {
162 setParameters(params);
163 update();
164 exec();
165 }
166
168
171 virtual
172 void update(){
173 }
174
176 virtual inline
177 void exec() const {};
178
179
180 // Optional bit(s) marking the command type (compare with manual page sections)
184 typedef int cmd_section_type;
185 cmd_section_type section = 1;
186
187 inline
188 Command & addSection(int i){ // drain::FlaggerBase<>::ivalue_t
189 section |= i;
190 return *this;
191 }
192
193 inline
194 const std::string & getLastParameters() const {
195 return lastParameters;
196 };
197
198
199 virtual
200 void help(std::ostream & ostr = std::cout, bool DETAILED=false) const;
201
202 virtual
203 void getRelatedCommands(std::ostream & ostr = std::cout) const;
204
205
207
213 /*
214 template <class C, class ...CC>
215 Command & linkRelatedCommands(const C & cmd, const CC & ... cmds){
216 relatedCommands.insert(cmd);
217 linkRelatedCommands(cmds...);
218 return *this;
219 };
220 */
221
222 mutable
223 std::set<std::string> relatedCommands;
224
225
226protected:
227
228 // Terminal
229 inline
230 Command & linkRelatedCommands(){
231 return *this;
232 };
233
234
235 virtual
236 ReferenceMap & getParameters() = 0;
237
238 // Clumsy but useful
239 std::string lastParameters;
240
241};
242
243inline
244std::ostream & operator<<(std::ostream & ostr, const Command &cmd){
245 ostr << cmd.getName();
246 if (cmd.hasParameters()){
247 ostr << ' ' << cmd.getParameters(); // << ' ';
248 }
249 return ostr;
250}
251
252// See new implementations in CommandBank, CommandUtils.
253//typedef std::list<std::pair<Command &, std::string> > Script; // TODO: move
254
255
257/*
258template <class B>
259class BeanerCommand : public Command {
260
261public:
262
263 typedef B bean_t;
264
265 // Main
266 virtual
267 const bean_t & getBean() const = 0;
268
269 // Main
270 virtual
271 bean_t & getBean() = 0;
272
273
274
275
276 inline
277 const std::string & getName() const final {
278 return getBean().getName();
279 };
280
281 inline
282 const std::string & getDescription() const final {
283 return getBean().getDescription();
284 };
285
286 virtual inline
287 const drain::ReferenceMap & getParameters() const final {
288 return getBean().getParameters();
289 };
290
291protected:
292
293 virtual inline
294 drain::ReferenceMap & getParameters() final {
295 return getBean().getParameters();
296 };
297
298};
299*/
300
302
308template <class B, class B2=B>
309class BeanCommand : public Command {
310// class BeanCommand : public BeanerCommand<B> { // public Command {
311
312public:
313
314 BeanCommand(){
315 };
316
317 BeanCommand(const std::string & name, const std::string & description) : bean(name, description){
318 };
319
320
321 BeanCommand(const BeanCommand & cmd) : Command(cmd), bean(cmd.bean) {
322 // WARNING: this may have undesired beaviour:
323 // If B2 is (Bean &), also new instance of beanCmd.bean -> cmd.bean
324 };
325
326 BeanCommand(B & b) : bean(b) {
327 };
328
329 typedef B bean_t;
330
331// Consider private:
332 B2 bean;
333
334
335 virtual inline
336 const bean_t & getBean() const { // final
337 return bean;
338 };
339
340 // Main
341 virtual inline
342 bean_t & getBean() { // final
343 return bean;
344 };
345
346
347
348 inline
349 const std::string & getName() const final {
350 return getBean().getName();
351 };
352
353 inline
354 const std::string & getDescription() const final {
355 return getBean().getDescription();
356 };
357
358 virtual inline
359 const drain::ReferenceMap & getParameters() const final {
360 return getBean().getParameters();
361 };
362
363protected:
364
365 virtual inline
366 drain::ReferenceMap & getParameters() final {
367 return getBean().getParameters();
368 };
369
370
371 /*
372 virtual
373 void setAllParameters(const std::string & args) override {
374
375 Context & ctx = this->template getContext<>();
376 drain::Logger mout(ctx.log, __FUNCTION__, this->bean.getName() );
377
378 bean.setParameters(args,'=');
379 //mout.note() = "updating";
380 //this->update();
381 }
382 */
383
385 //virtual
386 /*
387 void setParameters(const VariableMap & params){
388 bean.setParameters(params);
389 // this->update();
390 }
391 */
392
393};
394
395
396
397template <class B>
398class BeanRefCommand : public drain::BeanCommand<B, B&> {
399
400public:
401
403 }
404
405 BeanRefCommand(const B & bean) : drain::BeanCommand<B,B&>(bean){
406 }
407
408 BeanRefCommand(const BeanRefCommand<B> & beanRefCmd) : drain::BeanCommand<B,B&>(beanRefCmd.bean){
409 }
410
411
412};
413
414
415
416
418
424class BasicCommand : public BeanCommand<BeanLike> { // Todo consider BeanLike
425
426public:
427
428 BasicCommand(const std::string & name, const std::string & description);
429
430 inline
431 //BasicCommand(const BasicCommand & cmd): Command(cmd), name(cmd.name), description(cmd.description) {
433 // remember to call importParameters()
434 }
435
436};
437
438
439//typedef BeanCommand<BeanLike> BasicCommand;
440
441
442
444
447template <class T = std::string>
449
450public:
451
452 T value;
453
454 SimpleCommand(const std::string & name, const std::string & description,
455 const std::string & key="value", const T & initValue = T(), const std::string & unit = "") : BasicCommand(name, description) {
456
457 getParameters().separator = '\0';
458 getParameters().link(key, value = initValue, unit);
459
460 if (key.empty()){
461 Context & ctx = getContext<Context>();
462 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
463 mout.warn("Empty value key in command ", name, " (", description, ")");
464 }
465
466
467 };
468
470 template <class S>
471 SimpleCommand(const std::string & name, const std::string & description,
472 const std::string & key, std::initializer_list<S> l , const std::string & unit = "") : BasicCommand(name, description) {
473 // parameters.separator = '\0';
474 value = l;
475 getParameters().link(key, value);
476
477 if (key.empty()){
478 Context & ctx = getContext<Context>();
479 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
480 mout.warn("Empty value key in command ", name, " (", description, ")");
481 }
482 };
483
484
485 SimpleCommand(const SimpleCommand & cmd): BasicCommand(cmd) {
486 getParameters().separator = '\0';
487 getParameters().copyStruct(cmd.getParameters(), cmd, *this);
488 /*
489 parameters.separator = '\0';
490 parameters.copyStruct(cmd.getParameters(), cmd, *this);
491 */
492 };
493
494 /*
495 void setParameters(const std::string & args){
496 const std::string & key = parameters.begin()->first;
497 Variable v(typeid(T));
498 if (key.empty()){
499 v = args;
500 }
501 else {
502 const std::string assignment = key+"=";
503 const size_t n = assignment.length();
504 if (args.compare(0,n,key)==0){
505 v = args.substr(n);
506 }
507 else
508 v = args;
509 }
510 value = v;
511 }
512 */
513
514
515
516};
517
519
522/*
523class DynamicCommand : public drain::Command {
524
525public:
526
527 virtual
528 void exec() const {
529 Context & ctx = getContext<Context>();
530 drain::Logger mout(ctx.log,__FILE__, __FUNCTION__);
531 mout.note("I am " , getName() , ", invoked as " , key );
532 }
533
534 virtual
535 void setKey(const std::string & cmdKey) const {
536 key = cmdKey;
537 }
538
539protected:
540
541 mutable
542 std::string key;
543
544};
545*/
546
547
548
549
550} // drain::
551
552#endif /* DRAINLET_H_ */
Simple implementation of Command: adds name , description and parameters .
Definition Command.h:424
Retrieves bean dynamically for each call.
Definition Command.h:309
const std::string & getName() const final
Returns the class name of this command, like "CmdVerbose".
Definition Command.h:349
Definition Command.h:398
Base class for commands: typically actions taking parameters but also plain variable assignments and ...
Definition Command.h:55
int cmd_section_type
Definition Command.h:184
std::set< std::string > relatedCommands
Add related command(s), to appear in help after "See-also:" phrase.
Definition Command.h:223
virtual const std::string & getName() const =0
Returns the class name of this command, like "CmdVerbose".
virtual void run(const std::string &params="") final
Description of result, comparable to a return type of a function. ?
Definition Command.h:161
virtual void exec() const
Run the command with current parameter values.
Definition Command.h:177
void setParameter(const std::string &key, const T &value)
Set a value to a single parameter.
Definition Command.h:120
virtual void setParameters(const std::string &args) final
Definition Command.cpp:40
virtual void update()
Optional method for preparing command to execution.
Definition Command.h:172
Definition Context.h:57
Definition Context.h:246
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Definition ReferenceMap.h:207
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:399
A single-parameter command.
Definition Command.h:448
SimpleCommand(const std::string &name, const std::string &description, const std::string &key, std::initializer_list< S > l, const std::string &unit="")
Constuctor designer for SimpleCommand<Unituple<> > .
Definition Command.h:471
char separator
Default character used for splitting input and output. See setValues.
Definition SmartMap.h:85
Definition DataSelector.cpp:1277
Definition Sprinter.h:137