Statistics
| Branch: | Revision:

root / include / cwatch.h @ fbe00e73

History | View | Annotate | Download (9.95 KB)

1
//==========================================================================
2
//  CWATCH.H - part of
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//
7
//  Declaration of the following classes:
8
//    cWatchBase etc: make primitive types, structs etc inspectable
9
//
10
//==========================================================================
11

    
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19

    
20
#ifndef __CWATCH_H
21
#define __CWATCH_H
22

    
23
#include <iostream>
24
#include <sstream>
25
#include "cownedobject.h"
26

    
27
NAMESPACE_BEGIN
28

    
29

    
30
/**
31
 * Utility class to make primitive types and non-cOwnedObject objects
32
 * inspectable in Tkenv. To be used only via the WATCH, WATCH_PTR,
33
 * WATCH_OBJ, WATCH_VECTOR etc macros.
34
 *
35
 * @ingroup Internals
36
 */
37
class SIM_API cWatchBase : public cNoncopyableOwnedObject
38
{
39
  public:
40
    /** @name Constructors, destructor, assignment */
41
    //@{
42
    /**
43
     * Initialize the shell to hold the given variable.
44
     */
45
    cWatchBase(const char *name)  : cNoncopyableOwnedObject(name) {}
46
    //@}
47

    
48
    /** @name New methods */
49
    //@{
50
    /**
51
     * Tells if changing the variable's value via assign() is supported.
52
     */
53
    virtual bool supportsAssignment() const = 0;
54

    
55
    /**
56
     * Changes the watched variable's value. May only be called if
57
     * supportsAssignment() returns true.
58
     */
59
    virtual void assign(const char *s) {}
60
    //@}
61
};
62

    
63

    
64
/**
65
 * Template Watch class, for any type that supports operator<<.
66
 * @ingroup Internals
67
 */
68
template<typename T>
69
class cGenericReadonlyWatch : public cWatchBase
70
{
71
  private:
72
    const T& r;
73
  public:
74
    cGenericReadonlyWatch(const char *name, const T& x) : cWatchBase(name), r(x) {}
75
    virtual const char *getClassName() const {return opp_typename(typeid(T));}
76
    virtual bool supportsAssignment() const {return false;}
77
    virtual std::string info() const
78
    {
79
        std::stringstream out;
80
        out << r;
81
        return out.str();
82
    }
83
};
84

    
85

    
86
/**
87
 * Template Watch class, for any type that supports operator<<,
88
 * and operator>> for assignment.
89
 * @ingroup Internals
90
 */
91
template<typename T>
92
class cGenericAssignableWatch : public cWatchBase
93
{
94
  private:
95
    T& r;
96
  public:
97
    cGenericAssignableWatch(const char *name, T& x) : cWatchBase(name), r(x) {}
98
    virtual const char *getClassName() const {return opp_typename(typeid(T));}
99
    virtual bool supportsAssignment() const {return true;}
100
    virtual std::string info() const
101
    {
102
        std::stringstream out;
103
        out << r;
104
        return out.str();
105
    }
106
    virtual void assign(const char *s)
107
    {
108
        std::stringstream in(s);
109
        in >> r;
110
    }
111
};
112

    
113
/**
114
 * Watch class, specifically for bool.
115
 * @ingroup Internals
116
 */
117
class SIM_API cWatch_bool : public cWatchBase
118
{
119
  private:
120
    bool& r;
121
  public:
122
    cWatch_bool(const char *name, bool& x) : cWatchBase(name), r(x) {}
123
    virtual const char *getClassName() const {return "bool";}
124
    virtual bool supportsAssignment() const {return true;}
125
    virtual std::string info() const
126
    {
127
        return r ? "true" : "false";
128
    }
129
    virtual void assign(const char *s)
130
    {
131
        r = *s!='0' && *s!='n' && *s!='N' && *s!='f' && *s!='F';
132
    }
133
};
134

    
135
/**
136
 * Watch class, specifically for char.
137
 * @ingroup Internals
138
 */
139
class SIM_API cWatch_char : public cWatchBase
140
{
141
  private:
142
    char& r;
143
  public:
144
    cWatch_char(const char *name, char& x) : cWatchBase(name), r(x) {}
145
    virtual const char *getClassName() const {return "char";}
146
    virtual bool supportsAssignment() const {return true;}
147
    virtual std::string info() const
148
    {
149
        std::stringstream out;
150
        out << "'" << ((unsigned char)r<32 ? ' ' : r) << "' (" << int(r) << ")";
151
        return out.str();
152
    }
153
    virtual void assign(const char *s)
154
    {
155
        if (s[0]=='\'')
156
            r = s[1];
157
        else
158
            r = atoi(s);
159
    }
160
};
161

    
162
/**
163
 * Watch class, specifically for unsigned char.
164
 * @ingroup Internals
165
 */
166
class SIM_API cWatch_uchar : public cWatchBase
167
{
168
  private:
169
    unsigned char& r;
170
  public:
171
    cWatch_uchar(const char *name, unsigned char& x) : cWatchBase(name), r(x) {}
172
    virtual const char *getClassName() const {return "unsigned char";}
173
    virtual bool supportsAssignment() const {return true;}
174
    virtual std::string info() const
175
    {
176
        std::stringstream out;
177
        out << "'" << (char)(r<' ' ? ' ' : r) << "' (" << int(r) << ")";
178
        return out.str();
179
    }
180
    virtual void assign(const char *s)
181
    {
182
        if (s[0]=='\'')
183
            r = s[1];
184
        else
185
            r = atoi(s);
186
    }
187
};
188

    
189
/**
190
 * Watch class, specifically for std::string.
191
 * @ingroup Internals
192
 */
193
class SIM_API cWatch_stdstring : public cWatchBase
194
{
195
  private:
196
    std::string& r;
197
  public:
198
    cWatch_stdstring(const char *name, std::string& x) : cWatchBase(name), r(x) {}
199
    virtual const char *getClassName() const {return "std::string";}
200
    virtual bool supportsAssignment() const {return true;}
201
    virtual std::string info() const;
202
    virtual void assign(const char *s);
203
};
204

    
205
/**
206
 * Watch class, specifically for objects subclassed from cObject.
207
 * @ingroup Internals
208
 */
209
class SIM_API cWatch_cObject : public cWatchBase
210
{
211
  private:
212
    cObject& r;
213
  public:
214
    cWatch_cObject(const char *name, cObject& ref) : cWatchBase(name), r(ref) {}
215
    virtual const char *getClassName() const {return r.getClassName();}
216
    virtual std::string info() const {return r.info();}
217
    virtual bool supportsAssignment() const {return false;}
218
    virtual cClassDescriptor *getDescriptor() {return r.getDescriptor();}
219
};
220

    
221
/**
222
 * Watch class, specifically for pointers to objects subclassed from cObject.
223
 * @ingroup Internals
224
 */
225
class SIM_API cWatch_cObjectPtr : public cWatchBase
226
{
227
  private:
228
    cObject *&rp;
229
  public:
230
    cWatch_cObjectPtr(const char *name, cObject *&ptr) : cWatchBase(name), rp(ptr) {}
231
    virtual const char *getClassName() const {return rp? rp->getClassName() : "n/a";}
232
    virtual std::string info() const {return rp ? rp->info() : "<null>";}
233
    virtual bool supportsAssignment() const {return false;}
234
    virtual cClassDescriptor *getDescriptor() {return rp ? rp->getDescriptor() : NULL;}
235
};
236

    
237

    
238
inline cWatchBase *createWatch(const char *varname, short& d) {
239
    return new cGenericAssignableWatch<short>(varname, d);
240
}
241

    
242
inline cWatchBase *createWatch(const char *varname, unsigned short& d) {
243
    return new cGenericAssignableWatch<unsigned short>(varname, d);
244
}
245

    
246
inline cWatchBase *createWatch(const char *varname, int& d) {
247
    return new cGenericAssignableWatch<int>(varname, d);
248
}
249

    
250
inline cWatchBase *createWatch(const char *varname, unsigned int& d) {
251
    return new cGenericAssignableWatch<unsigned int>(varname, d);
252
}
253

    
254
inline cWatchBase *createWatch(const char *varname, long& d) {
255
    return new cGenericAssignableWatch<long>(varname, d);
256
}
257

    
258
inline cWatchBase *createWatch(const char *varname, unsigned long& d) {
259
    return new cGenericAssignableWatch<unsigned long>(varname, d);
260
}
261

    
262
inline cWatchBase *createWatch(const char *varname, float& d) {
263
    return new cGenericAssignableWatch<float>(varname, d);
264
}
265

    
266
inline cWatchBase *createWatch(const char *varname, double& d) {
267
    return new cGenericAssignableWatch<double>(varname, d);
268
}
269

    
270
inline cWatchBase *createWatch(const char *varname, bool& d) {
271
    return new cWatch_bool(varname, d);
272
}
273

    
274
inline cWatchBase *createWatch(const char *varname, char& d) {
275
    return new cWatch_char(varname, d);
276
}
277

    
278
inline cWatchBase *createWatch(const char *varname, unsigned char& d) {
279
    return new cWatch_uchar(varname, d);
280
}
281

    
282
inline cWatchBase *createWatch(const char *varname, signed char& d) {
283
    return new cWatch_char(varname, *(char *)&d);
284
}
285

    
286
inline cWatchBase *createWatch(const char *varname, std::string& v) {
287
    return new cWatch_stdstring(varname, v);
288
}
289

    
290
// this is the fallback, if none of the above match
291
template<typename T>
292
inline cWatchBase *createWatch(const char *varname, T& d) {
293
    return new cGenericReadonlyWatch<T>(varname, d);
294
}
295

    
296
// to be used if T also has op>> defined
297
template<typename T>
298
inline cWatchBase *createWatch_genericAssignable(const char *varname, T& d) {
299
    return new cGenericAssignableWatch<T>(varname, d);
300
}
301

    
302
// for objects
303
inline cWatchBase *createWatch_cObject(const char *varname, cObject& obj) {
304
    return new cWatch_cObject(varname, obj);
305
}
306

    
307
// for pointers to objects.
308
// NOTE: this is a bit tricky. C++ thinks that (cObject*&) and
309
// (SomeDerivedType*&) are unrelated, so we have to force the cast
310
// in the WATCH_PTR() macro. But to stay type-safe, we include a 3rd arg
311
// of type cObject*: the compiler has to be able to cast that
312
// implicitly from SomeDerivedType* -- this way we do not accept pointers
313
// that are REALLY unrelated.
314
inline cWatchBase *createWatch_cObjectPtr(const char *varname, cObject *&refp, cObject *p) {
315
    ASSERT(refp==p);
316
    return new cWatch_cObjectPtr(varname, refp);
317
}
318

    
319

    
320
/**
321
 * @ingroup Macros
322
 * @defgroup MacrosWatch WATCH macros
323
 */
324
//@{
325

    
326
/**
327
 * Makes primitive types and types with operator<< inspectable in Tkenv.
328
 * See also WATCH_RW(), WATCH_PTR(), WATCH_OBJ(), WATCH_VECTOR(),
329
 * WATCH_PTRVECTOR(), etc. macros.
330
 *
331
 * @hideinitializer
332
 */
333
#define WATCH(variable)    createWatch(#variable,(variable))
334

    
335
/**
336
 * Makes types with operator\<\< and operator\>\> inspectable in Tkenv.
337
 * operator\>\> is used to enable changing the variable's value interactively.
338
 *
339
 * @hideinitializer
340
 */
341
#define WATCH_RW(variable) createWatch_genericAssignable(#variable,(variable))
342

    
343
/**
344
 * Makes classes derived from cObject inspectable in Tkenv.
345
 * See also WATCH_PTR().
346
 *
347
 * @hideinitializer
348
 */
349
#define WATCH_OBJ(variable) createWatch_cObject(#variable,(variable))
350

    
351
/**
352
 * Makes pointers to objects derived from cObject inspectable in Tkenv.
353
 * See also WATCH_OBJ().
354
 *
355
 * @hideinitializer
356
 */
357
#define WATCH_PTR(variable) createWatch_cObjectPtr(#variable,(cObject*&)(variable),(variable))
358
//@}
359

    
360
NAMESPACE_END
361

    
362

    
363
#endif
364

    
365