Project

General

Profile

Statistics
| Branch: | Revision:

root / include / cpar.h @ 0e7ff5c8

History | View | Annotate | Download (14.4 KB)

1
//==========================================================================
2
//   CPAR.H  - 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
#ifndef __CPAR_H
19
#define __CPAR_H
20

    
21
#include "cownedobject.h"
22
#include "cexpression.h"
23
#include "cexception.h"
24

    
25
NAMESPACE_BEGIN
26

    
27
class cParImpl;
28
class cExpression;
29
class cXMLElement;
30
class cProperties;
31
class cComponent;
32

    
33
/**
34
 * Represents a module or channel parameter.
35
 *
36
 * When a module or channel is created, parameter objects are added
37
 * automatically, based on the NED declaration of the module/channel.
38
 * It is not possible to create further parameters (or to remove parameters)
39
 * at runtime. This is enforced by the cPar constructor being private.
40
 *
41
 * Parameters get their initial values automatically, from the NED
42
 * declarations and the configuration. It is possible to change the
43
 * parameter value during runtime (see various setter methods and
44
 * operator='s), but not the type of the parameter (see getType()).
45
 * The type correspond to NED types (bool, double, long, string, xml),
46
 * and cannot be changed at runtime.
47
 *
48
 * The module or channel object can get notified when a parameter is
49
 * changed; one has to override cComponent::handleParameterChange()
50
 * for that.
51
 *
52
 * <b>Note:</b> In earlier versions of \opp, cPar could be used as a
53
 * general value storage object, and attached to cMessages as well.
54
 * From the 4.0 version, simulation models should use cMsgPar for that.
55
 *
56
 * <b>Implementation note:</b> from the 4.0 version, almost all methods
57
 * of cPar delegates to an internal cParImpl object, which actually stores
58
 * the value, and generally does the real job. This was done to allow
59
 * sharing parameter objects which have the same name, same value, etc.
60
 * among module/channel instances. This significantly reduces memory
61
 * consumption of most simulation models. Because cPar is just a thin
62
 * wrapper around cParImpl, cPar is not meant for subclassing, and
63
 * none if its methods are virtual. cParImpl and subclasses should also
64
 * be regarded as internal data structures, and they should not be
65
 * directly accessed or manipulated from model code.
66
 *
67
 * @ingroup SimCore
68
 */
69
class SIM_API cPar : public cObject
70
{
71
    friend class cComponent;
72
  public:
73
    enum Type {
74
        BOOL = 'B',
75
        DOUBLE = 'D',
76
        LONG = 'L',
77
        STRING = 'S',
78
        XML = 'X'
79
    };
80

    
81
  private:
82
    cComponent *ownercomponent;
83
    cParImpl *p;
84

    
85
  private:
86
    // private constructor -- only cComponent is allowed to create parameters
87
    cPar() {ownercomponent = NULL; p = NULL;}
88
    // internal, called from cComponent
89
    void init(cComponent *ownercomponent, cParImpl *p);
90
    // internal
91
    void moveto(cPar& other);
92
    // internal: called each time before the value of this object changes.
93
    void beforeChange();
94
    // internal: called each time after the value of this object changes.
95
    void afterChange();
96

    
97
  public:
98
    // internal: applies the default value if there is one
99
    void acceptDefault();
100
    // internal
101
    void setImpl(cParImpl *p);
102
    // internal
103
    cParImpl *impl() const {return p;}
104
    // internal
105
    cParImpl *copyIfShared();
106

    
107
  public:
108
    /**
109
     * Destructor.
110
     */
111
    virtual ~cPar();
112

    
113
    /**
114
     * Returns the parameter name.
115
     */
116
    virtual const char *getName() const;
117

    
118
    /**
119
     * Returns a one-line description of the object.
120
     * @see detailedInfo()
121
     */
122
    virtual std::string info() const;
123

    
124
    /**
125
     * Returns a long description of the object.
126
     */
127
    virtual std::string detailedInfo() const;
128

    
129
    /**
130
     * Returns the component (module/channel) this parameter belongs to.
131
     * Note: return type is cObject only for technical reasons, it can be
132
     * safely cast to cComponent.
133
     */
134
    virtual cObject *getOwner() const;
135

    
136
    /**
137
     * Assignment
138
     */
139
    void operator=(const cPar& other);
140
    //@}
141

    
142
    /** @name Type, flags. */
143
    //@{
144
    /**
145
     * Returns the parameter type
146
     */
147
    Type getType() const;
148

    
149
    /**
150
     * Returns the given type as a string.
151
     */
152
    static const char *getTypeName(Type t);
153

    
154
    /**
155
     * Returns true if the stored value is of a numeric type.
156
     */
157
    bool isNumeric() const;
158

    
159
    /**
160
     * Returns true if this parameter is marked in the NED file as "volatile".
161
     * This flag affects the operation of setExpression().
162
     */
163
    bool isVolatile() const;
164

    
165
    /**
166
     * Returns false if the stored value is a constant, and true if it is
167
     * an expression. (It is not examined whether the expression yields
168
     * a constant value.)
169
     */
170
    bool isExpression() const;
171

    
172
    /**
173
     * Returns true if the parameter value expression is shared among several
174
     * modules to save memory. This flag is purely informational, and whether
175
     * a parameter is shared or not does not affect operation at all.
176
     */
177
    bool isShared() const;
178

    
179
    /**
180
     * Returns true if the parameter is assigned a value, and false otherwise.
181
     * Parameters of an already initialized module or channel are guaranteed to
182
     * assigned, so this method will return true for them.
183
     */
184
    bool isSet() const;
185

    
186
    /**
187
     * Returns true if the parameter is set (see isSet()) or contains a default
188
     * value, and false otherwise. Parameters of an already initialized module or
189
     * channel are guaranteed to be assigned, so this method will return true for them.
190
     */
191
    bool containsValue() const;
192

    
193
    /**
194
     * Return the properties for this parameter. Properties cannot be changed
195
     * at runtime.
196
     */
197
    cProperties *getProperties() const;
198
    //@}
199

    
200
    /** @name Setter functions. Note that overloaded assignment operators also exist. */
201
    //@{
202

    
203
    /**
204
     * Sets the value to the given bool value.
205
     */
206
    cPar& setBoolValue(bool b);
207

    
208
    /**
209
     * Sets the value to the given long value.
210
     */
211
    cPar& setLongValue(long l);
212

    
213
    /**
214
     * Sets the value to the given double value.
215
     */
216
    cPar& setDoubleValue(double d);
217

    
218
    /**
219
     * Sets the value to the given string value.
220
     * The cPar will make its own copy of the string. NULL is also accepted
221
     * and treated as an empty string.
222
     */
223
    cPar& setStringValue(const char *s);
224

    
225
    /**
226
     * Sets the value to the given string value.
227
     */
228
    cPar& setStringValue(const std::string& s)  {setStringValue(s.c_str()); return *this;}
229

    
230
    /**
231
     * Sets the value to the given cXMLElement.
232
     */
233
    cPar& setXMLValue(cXMLElement *node);
234

    
235
    /**
236
     * Sets the value to the given expression. This object will assume
237
     * the responsibility to delete the expression object.
238
     *
239
     * Note: if the parameter is marked as non-volatile (isVolatile()==false),
240
     * one should not set an expression as value. This is not enforced
241
     * by cPar though.
242
     */
243
    cPar& setExpression(cExpression *e);
244
    //@}
245

    
246
    /** @name Getter functions. Note that overloaded conversion operators also exist. */
247
    //@{
248

    
249
    /**
250
     * Returns value as a boolean. The cPar type must be BOOL.
251
     */
252
    bool boolValue() const;
253

    
254
    /**
255
     * Returns value as long. The cPar type must be LONG or DOUBLE.
256
     */
257
    long longValue() const;
258

    
259
    /**
260
     * Returns value as double. The cPar type must be LONG or DOUBLE.
261
     */
262
    double doubleValue() const;
263

    
264
    /**
265
     * Returns the parameter's unit ("s", "mW", "Hz", "bps", etc),
266
     * as declared with the \@unit property of the parameter in NED,
267
     * or NULL if no unit was specified. Unit is only valid for LONG and DOUBLE
268
     * types.
269
     */
270
    const char *getUnit() const;
271

    
272
    /**
273
     * Returns value as const char *. The cPar type must be STRING.
274
     * This method may only be invoked when the parameter's value is a
275
     * string constant and not the result of expression evaluation, otherwise
276
     * an error is thrown. This practically means this method cannot be used
277
     * on parameters declared as "volatile string" in NED; they can only be
278
     * accessed using stdstringValue().
279
     */
280
    const char *stringValue() const;
281

    
282
    /**
283
     * Returns value as string. The cPar type must be STRING.
284
     */
285
    std::string stdstringValue() const;
286

    
287
    /**
288
     * Returns value as pointer to cXMLElement. The cPar type must be XML.
289
     *
290
     * The lifetime of the returned object tree is undefined, but it is
291
     * valid at least until the end of the current simulation event or
292
     * initialize() call. Modules are expected to process their XML
293
     * configurations at once (within one event or within initialize()),
294
     * and not hang on to pointers returned from this method. The reason
295
     * for the limited lifetime is that this method may return pointers to
296
     * objects stored in an internal XML document cache, and the simulation
297
     * kernel reserves the right to discard cached XML documents at any time
298
     * to free up memory, and re-load them on demand (i.e. when xmlValue() is
299
     * called again).
300
     */
301
    cXMLElement *xmlValue() const;
302

    
303
    /**
304
     * Returns pointer to the expression stored by the object, or NULL.
305
     */
306
    cExpression *getExpression() const;
307
    //@}
308

    
309
    /** @name Miscellaneous utility functions. */
310
    //@{
311

    
312
    /**
313
     * This method does the final touches on the parameter. It is invoked
314
     * at some point on all parameter objects before we start the simulation.
315
     *
316
     * - if the parameter is not set, gets the value from omnetpp.ini or
317
     *   interactively from the user, or sets the default value.
318
     *
319
     * - if the parameter is non-volatile, (isVolatile()==false), converts
320
     *   possible expression value to a constant (see convertToConst()).
321
     *
322
     * - if the parameter is volatile but contains "const" subexpressions,
323
     *   these parts are converted to a constant value.
324
     */
325
    void read();
326

    
327
    /**
328
     * For non-const values, replaces the stored expression with its
329
     * evaluation.
330
     */
331
    void convertToConst();
332

    
333
    /**
334
     * Returns the value in text form.
335
     */
336
    std::string str() const;
337

    
338
    /**
339
     * Converts the value from string, and stores the result.
340
     * If the text cannot be parsed, an exception is thrown, which
341
     * can be caught as std::runtime_error& if necessary.
342
     *
343
     * Note: this method understands expressions too, but does NOT handle
344
     * the special values "default" and "ask".
345
     */
346
    void parse(const char *text);
347
    //@}
348

    
349
    /** @name Overloaded assignment and conversion operators. */
350
    //@{
351

    
352
    /**
353
     * Equivalent to setBoolValue().
354
     */
355
    cPar& operator=(bool b)  {return setBoolValue(b);}
356

    
357
    /**
358
     * Converts the argument to long, and calls setLongValue().
359
     */
360
    cPar& operator=(char c)  {return setLongValue((long)c);}
361

    
362
    /**
363
     * Converts the argument to long, and calls setLongValue().
364
     */
365
    cPar& operator=(unsigned char c)  {return setLongValue((long)c);}
366

    
367
    /**
368
     * Converts the argument to long, and calls setLongValue().
369
     */
370
    cPar& operator=(int i)  {return setLongValue((long)i);}
371

    
372
    /**
373
     * Converts the argument to long, and calls setLongValue().
374
     */
375
    cPar& operator=(unsigned int i)  {return setLongValue((long)i);}
376

    
377
    /**
378
     * Converts the argument to long, and calls setLongValue().
379
     */
380
    cPar& operator=(short i)  {return setLongValue((long)i);}
381

    
382
    /**
383
     * Converts the argument to long, and calls setLongValue().
384
     */
385
    cPar& operator=(unsigned short i)  {return setLongValue((long)i);}
386

    
387
    /**
388
     * Equivalent to setLongValue().
389
     */
390
    cPar& operator=(long l)  {return setLongValue(l);}
391

    
392
    /**
393
     * Converts the argument to long, and calls setLongValue().
394
     */
395
    cPar& operator=(unsigned long l) {return setLongValue((long)l);}
396

    
397
    /**
398
     * Equivalent to setDoubleValue().
399
     */
400
    cPar& operator=(double d)  {return setDoubleValue(d);}
401

    
402
    /**
403
     * Converts the argument to double, and calls setDoubleValue().
404
     */
405
    cPar& operator=(long double d)  {return setDoubleValue((double)d);}
406

    
407
    /**
408
     * Equivalent to setStringValue().
409
     */
410
    cPar& operator=(const char *s)  {return setStringValue(s);}
411

    
412
    /**
413
     * Equivalent to setStringValue().
414
     */
415
    cPar& operator=(const std::string& s)  {return setStringValue(s);}
416

    
417
    /**
418
     * Equivalent to setXMLValue().
419
     */
420
    cPar& operator=(cXMLElement *node)  {return setXMLValue(node);}
421

    
422
    /**
423
     * Equivalent to boolValue().
424
     */
425
    operator bool() const  {return boolValue();}
426

    
427
    /**
428
     * Calls longValue() and converts the result to char.
429
     */
430
    operator char() const  {return (char)longValue();}
431

    
432
    /**
433
     * Calls longValue() and converts the result to unsigned char.
434
     */
435
    operator unsigned char() const  {return (unsigned char)longValue();}
436

    
437
    /**
438
     * Calls longValue() and converts the result to int.
439
     */
440
    operator int() const  {return (int)longValue();}
441

    
442
    /**
443
     * Calls longValue() and converts the result to unsigned int.
444
     */
445
    operator unsigned int() const  {return (unsigned int)longValue();}
446

    
447
    /**
448
     * Calls longValue() and converts the result to short.
449
     */
450
    operator short() const  {return (short)longValue();}
451

    
452
    /**
453
     * Calls longValue() and converts the result to unsigned short.
454
     */
455
    operator unsigned short() const  {return (unsigned short)longValue();}
456

    
457
    /**
458
     * Equivalent to longValue().
459
     */
460
    operator long() const  {return longValue();}
461

    
462
    /**
463
     * Calls longValue() and converts the result to unsigned long.
464
     */
465
    operator unsigned long() const  {return longValue();}
466

    
467
    /**
468
     * Equivalent to doubleValue().
469
     */
470
    operator double() const  {return doubleValue();}
471

    
472
    /**
473
     * Calls doubleValue() and converts the result to long double.
474
     */
475
    operator long double() const  {return doubleValue();}
476

    
477
    /**
478
     * Equivalent to stringValue().
479
     */
480
    operator const char *() const  {return stringValue();}
481

    
482
    /**
483
     * Equivalent to stdstringValue().
484
     */
485
    operator std::string() const  {return stdstringValue();}
486

    
487
    /**
488
     * Equivalent to xmlValue(). NOTE: The lifetime of the returned object tree
489
     * is limited; see xmlValue() for details.
490
     */
491
    operator cXMLElement *() const  {return xmlValue();}
492
    //@}
493
};
494

    
495
NAMESPACE_END
496

    
497

    
498
#endif
499

    
500

    
501

    
502