cwatch.h Source File¶

API: cwatch.h Source File
API
cwatch.h
1//==========================================================================
2// CWATCH.H - part of
3// OMNeT++/OMNEST
4// Discrete System Simulation in C++
5//
6//==========================================================================
7
8/*--------------------------------------------------------------*
9 Copyright (C) 1992-2017 Andras Varga
10 Copyright (C) 2006-2017 OpenSim Ltd.
11
12 This file is distributed WITHOUT ANY WARRANTY. See the file
13 `license' for details on this and other legal matters.
14*--------------------------------------------------------------*/
15
16#ifndef __OMNETPP_CWATCH_H
17#define __OMNETPP_CWATCH_H
18
19#include <iostream>
20#include <sstream>
21#include <functional>
22#include "cownedobject.h"
23#include "cclassdescriptor.h"
24#include "cdynamicdescriptor.h"
25
26namespace omnetpp {
27
28class cWatchBase;
29
36class SIM_API cWatchProxyDescriptor : public cClassDescriptor {
37 protected:
38 cWatchBase *watch;
39 cClassDescriptor *targetDesc;
40
41 public:
42 cWatchProxyDescriptor(cWatchBase *watch, cClassDescriptor *targetDesc) :
43 cClassDescriptor(targetDesc ? targetDesc->getName() : "none"),
44 watch(watch), targetDesc(targetDesc) { }
45
46 void setTargetDescriptor(cClassDescriptor *desc) { targetDesc = desc; setName(desc ? desc->getName() : "none"); }
47
48 virtual const char **getPropertyNames() const override;
49 virtual const char *getProperty(const char *propertyname) const override;
50 virtual int getFieldCount() const override;
51 virtual const char *getFieldName(int field) const override;
52 virtual unsigned int getFieldTypeFlags(int field) const override;
53 virtual const char *getFieldTypeString(int field) const override;
54 virtual const char *getFieldStructName(int field) const override;
55 virtual const char **getFieldPropertyNames(int field) const override;
56 virtual const char *getFieldProperty(int field, const char *propertyname) const override;
57 virtual std::string getValueAsString(any_ptr object) const override;
58 virtual void setValueAsString(any_ptr object, const char *value) const override;
59 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override;
60 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override;
61 virtual cValue getFieldValue(any_ptr object, int field, int i) const override;
62 virtual void setFieldValue(any_ptr object, int field, int i, const cValue& value) const override;
63 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override;
64 virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override;
65 virtual int getFieldArraySize(any_ptr object, int field) const override;
66 virtual void setFieldArraySize(any_ptr object, int field, int size) const override;
67 virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override;
68};
69
77class SIM_API cWatchBase : public cNoncopyableOwnedObject
78{
79 protected:
80 mutable cWatchProxyDescriptor *proxyDesc = nullptr;
81
82 protected:
83 void forEachChildOf(cObject *obj, cVisitor *visitor);
84
85 public:
88
91 cWatchBase(const char *name) : cNoncopyableOwnedObject(name) {}
94
95 virtual std::string str() const override;
96
99
102 virtual any_ptr getValuePointer() const = 0;
104};
105
106
112template<typename T>
113class cWatch : public cWatchBase
114{
115 private:
116 const T& r;
117
118 public:
119 cWatch(const char *name, const T& x) : cWatchBase(name), r(x) {}
120 virtual const char *getClassName() const override {return getDescriptor()->getFullName();}
121
122 virtual void forEachChild(cVisitor *visitor) override {
123 if constexpr (std::is_base_of_v<cObject, T>)
124 forEachChildOf(const_cast<T*>(&r), visitor);
125 }
126
127 virtual any_ptr getValuePointer() const override {
128 if constexpr (std::is_base_of_v<cObject, T>)
129 return toAnyPtr(&r);
130 else
131 return any_ptr(&r);
132 }
133
134 virtual cClassDescriptor *getDescriptor() const override {
135 if (proxyDesc == nullptr) {
136 cClassDescriptor *targetDesc;
137 if constexpr (std::is_base_of_v<cObject, T>)
138 targetDesc = r.getDescriptor();
139 else
140 targetDesc = omnetpp::ensureDescriptor<T>();
141 auto *nonconst_this = const_cast<cWatch*>(this);
142 proxyDesc = new cWatchProxyDescriptor(nonconst_this, targetDesc);
143 nonconst_this->take(proxyDesc);
144 }
145 return proxyDesc;
146 }
147};
148
154template<typename T>
155class cPointerWatch : public cWatchBase
156{
157 private:
158 T *& p;
159 std::string declTypeName;
160
161 public:
162 cPointerWatch(const char *name, T *& x) : cWatchBase(name), p(x),
163 declTypeName(std::string(opp_typename(typeid(T))) + " *") {}
164
165 virtual const char *getClassName() const override {return declTypeName.c_str();}
166
167 virtual void forEachChild(cVisitor *visitor) override {
168 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
169 if (p) forEachChildOf(const_cast<cObject*>(static_cast<const cObject*>(p)), visitor);
170 }
171
172 virtual any_ptr getValuePointer() const override {
173 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
174 return toAnyPtr(static_cast<const cObject*>(p));
175 else
176 return any_ptr(p);
177 }
178
179 virtual cClassDescriptor *getDescriptor() const override {
180 if (proxyDesc == nullptr) {
181 cClassDescriptor *targetDesc;
182 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
183 targetDesc = p ? p->getDescriptor() : nullptr;
184 else
185 targetDesc = omnetpp::ensureDescriptor<std::remove_const_t<T>>();
186 auto *nonconst_this = const_cast<cPointerWatch*>(this);
187 proxyDesc = new cWatchProxyDescriptor(nonconst_this, targetDesc);
188 nonconst_this->take(proxyDesc);
189 }
190 else if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>) {
191 // watched pointer may now point to a different object, update descriptor
192 proxyDesc->setTargetDescriptor(p ? p->getDescriptor() : nullptr);
193 }
194 return proxyDesc;
195 }
196};
197
198
199template<typename T>
200inline cWatchBase *createWatch(const char *varname, T& d) {
201 return new cWatch<T>(varname, d);
202}
203
204template<typename T>
205inline cWatchBase *createWatch(const char *varname, T *& p) {
206 return new cPointerWatch<T>(varname, p);
207}
208
214template<typename T>
215class cComputedWatch : public cWatchBase
216{
217 private:
218 std::function<T()> fn;
219 mutable T cachedValue;
220
221 public:
222 cComputedWatch(const char *name, std::function<T()> f)
223 : cWatchBase(name), fn(f), cachedValue(f()) {}
224
225 virtual const char *getClassName() const override {
226 return getDescriptor()->getFullName();
227 }
228
229 virtual any_ptr getValuePointer() const override {
230 cachedValue = fn();
231 return any_ptr(&cachedValue);
232 }
233
234 virtual cClassDescriptor *getDescriptor() const override {
235 if (proxyDesc == nullptr) {
236 cClassDescriptor *targetDesc = omnetpp::ensureDescriptor<T>();
237 auto *nonconst_this = const_cast<cComputedWatch*>(this);
238 proxyDesc = new cWatchProxyDescriptor(nonconst_this, targetDesc);
239 nonconst_this->take(proxyDesc);
240 }
241 return proxyDesc;
242 }
243};
244
245template<typename F>
246inline cWatchBase *createLambdaWatch(const char *name, F&& fn) {
247 using T = std::invoke_result_t<F>;
248 return new cComputedWatch<T>(name, std::function<T()>(std::forward<F>(fn)));
249}
250
255
264#define WATCH(variable) omnetpp::createWatch(#variable,(variable))
265
266// Obsolete aliases to WATCH()
267#define WATCH_RW(variable) WATCH(variable)
268#define WATCH_OBJ(variable) WATCH(variable)
269#define WATCH_PTR(variable) WATCH(variable)
270#define WATCH_VECTOR(variable) WATCH(variable)
271#define WATCH_PTRVECTOR(variable) WATCH(variable)
272#define WATCH_LIST(variable) WATCH(variable)
273#define WATCH_PTRLIST(variable) WATCH(variable)
274#define WATCH_SET(variable) WATCH(variable)
275#define WATCH_PTRSET(variable) WATCH(variable)
276#define WATCH_MAP(variable) WATCH(variable)
277#define WATCH_PTRMAP(variable) WATCH(variable)
278
296#define WATCH_EXPR(name, expression) omnetpp::createLambdaWatch(name, [this]() { return (expression); })
297
312#define WATCH_LAMBDA(name, lambdaFunction) omnetpp::createLambdaWatch(name, lambdaFunction)
313
315
316} // namespace omnetpp
317
318
319#endif
320
321
A type-safe equivalent of the void* pointer.
Definition any_ptr.h:63
Abstract base class for class descriptors.
Definition cclassdescriptor.h:40
cClassDescriptor(const char *className, const char *baseClassName=nullptr)
virtual const char * getClassName() const override
Definition cwatch.h:225
virtual any_ptr getValuePointer() const override
Definition cwatch.h:229
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:234
virtual const char * getName() const override
Definition cnamedobject.h:111
virtual void setName(const char *s)
cObject is a lightweight class which serves as the root of the OMNeT++ class hierarchy....
Definition cobject.h:93
virtual const char * getFullName() const
Definition cobject.h:169
virtual cClassDescriptor * getDescriptor() const
Template Watch class that delegates to the type's cClassDescriptor for string conversion and inspecti...
Definition cwatch.h:156
virtual const char * getClassName() const override
Definition cwatch.h:165
virtual any_ptr getValuePointer() const override
Definition cwatch.h:172
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:179
virtual void forEachChild(cVisitor *visitor) override
Definition cwatch.h:167
A variant-like value class used during evaluating NED expressions.
Definition cvalue.h:48
Enables traversing the tree of (cObject-rooted) simulation objects.
Definition cvisitor.h:57
Helper class to make primitive types and non-cOwnedObject objects inspectable in Qtenv....
Definition cwatch.h:78
virtual any_ptr getValuePointer() const =0
cWatchBase(const char *name)
Definition cwatch.h:91
virtual std::string str() const override
Definition cwatch.h:36
virtual unsigned int getFieldTypeFlags(int field) const override
virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override
virtual void setValueAsString(any_ptr object, const char *value) const override
virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override
virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override
virtual int getFieldArraySize(any_ptr object, int field) const override
virtual const char ** getPropertyNames() const override
virtual const char * getProperty(const char *propertyname) const override
virtual const char * getFieldTypeString(int field) const override
virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override
virtual const char * getFieldStructName(int field) const override
virtual int getFieldCount() const override
virtual const char * getFieldName(int field) const override
virtual const char ** getFieldPropertyNames(int field) const override
virtual cValue getFieldValue(any_ptr object, int field, int i) const override
virtual void setFieldValue(any_ptr object, int field, int i, const cValue &value) const override
virtual void setFieldArraySize(any_ptr object, int field, int size) const override
virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override
virtual const char * getFieldProperty(int field, const char *propertyname) const override
virtual std::string getValueAsString(any_ptr object) const override
virtual const char * getClassName() const override
Definition cwatch.h:120
virtual any_ptr getValuePointer() const override
Definition cwatch.h:127
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:134
virtual void forEachChild(cVisitor *visitor) override
Definition cwatch.h:122
SIM_API const char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.