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 protected:
42 any_ptr getNonNullValuePointer(const char *what) const;
43
44 public:
45 cWatchProxyDescriptor(cWatchBase *watch, cClassDescriptor *targetDesc) :
46 cClassDescriptor(targetDesc ? targetDesc->getName() : "none"),
47 watch(watch), targetDesc(targetDesc) { }
48
49 void setTargetDescriptor(cClassDescriptor *desc) { targetDesc = desc; setName(desc ? desc->getName() : "none"); }
50
51 virtual const char **getPropertyNames() const override;
52 virtual const char *getProperty(const char *propertyname) const override;
53 virtual int getFieldCount() const override;
54 virtual const char *getFieldName(int field) const override;
55 virtual unsigned int getFieldTypeFlags(int field) const override;
56 virtual const char *getFieldTypeString(int field) const override;
57 virtual const char *getFieldStructName(int field) const override;
58 virtual const char **getFieldPropertyNames(int field) const override;
59 virtual const char *getFieldProperty(int field, const char *propertyname) const override;
60 virtual std::string getValueAsString(any_ptr object) const override;
61 virtual void setValueAsString(any_ptr object, const char *value) const override;
62 virtual std::string getFieldValueAsString(any_ptr object, int field, int i) const override;
63 virtual void setFieldValueAsString(any_ptr object, int field, int i, const char *value) const override;
64 virtual cValue getFieldValue(any_ptr object, int field, int i) const override;
65 virtual void setFieldValue(any_ptr object, int field, int i, const cValue& value) const override;
66 virtual any_ptr getFieldStructValuePointer(any_ptr object, int field, int i) const override;
67 virtual void setFieldStructValuePointer(any_ptr object, int field, int i, any_ptr ptr) const override;
68 virtual int getFieldArraySize(any_ptr object, int field) const override;
69 virtual void setFieldArraySize(any_ptr object, int field, int size) const override;
70 virtual std::string getFieldArrayIndexString(any_ptr object, int field, int arrayIndex) const override;
71};
72
80class SIM_API cWatchBase : public cNoncopyableOwnedObject
81{
82 protected:
83 mutable cWatchProxyDescriptor *proxyDesc = nullptr;
84
85 protected:
86 void forEachChildOf(cObject *obj, cVisitor *visitor);
87
88 public:
91
94 cWatchBase(const char *name) : cNoncopyableOwnedObject(name) {}
97
98 virtual std::string str() const override;
99
102
105 virtual any_ptr getValuePointer() const = 0;
107};
108
109
115template<typename T>
116class cWatch : public cWatchBase
117{
118 private:
119 const T& r;
120
121 public:
122 cWatch(const char *name, const T& x) : cWatchBase(name), r(x) {}
123 virtual const char *getClassName() const override {return getDescriptor()->getFullName();}
124
125 virtual void forEachChild(cVisitor *visitor) override {
126 if constexpr (std::is_base_of_v<cObject, T>)
127 forEachChildOf(const_cast<T*>(&r), visitor);
128 }
129
130 virtual any_ptr getValuePointer() const override {
131 if constexpr (std::is_base_of_v<cObject, T>)
132 return toAnyPtr(&r);
133 else
134 return any_ptr(&r);
135 }
136
137 virtual cClassDescriptor *getDescriptor() const override {
138 if (proxyDesc == nullptr) {
139 cClassDescriptor *targetDesc;
140 if constexpr (std::is_base_of_v<cObject, T>)
141 targetDesc = r.getDescriptor();
142 else
143 targetDesc = omnetpp::ensureDescriptor<T>();
144 auto *nonconst_this = const_cast<cWatch*>(this);
145 proxyDesc = new cWatchProxyDescriptor(nonconst_this, targetDesc);
146 nonconst_this->take(proxyDesc);
147 }
148 return proxyDesc;
149 }
150};
151
157template<typename T>
158class cPointerWatch : public cWatchBase
159{
160 private:
161 T *& p;
162 std::string declTypeName;
163
164 public:
165 cPointerWatch(const char *name, T *& x) : cWatchBase(name), p(x),
166 declTypeName(std::string(opp_typename(typeid(T))) + " *") {}
167
168 virtual const char *getClassName() const override {return declTypeName.c_str();}
169
170 virtual void forEachChild(cVisitor *visitor) override {
171 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
172 if (p) forEachChildOf(const_cast<cObject*>(static_cast<const cObject*>(p)), visitor);
173 }
174
175 virtual any_ptr getValuePointer() const override {
176 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
177 return toAnyPtr(static_cast<const cObject*>(p));
178 else
179 return any_ptr(p);
180 }
181
182 virtual cClassDescriptor *getDescriptor() const override {
183 if (proxyDesc == nullptr) {
184 auto *nonconst_this = const_cast<cPointerWatch*>(this);
185 proxyDesc = new cWatchProxyDescriptor(nonconst_this, getTargetDescriptor());
186 nonconst_this->take(proxyDesc);
187 }
188 else {
189 // watched pointer may have changed (e.g. to/from nullptr, or to an object of another class)
190 proxyDesc->setTargetDescriptor(getTargetDescriptor());
191 }
192 return proxyDesc;
193 }
194
195 private:
196 cClassDescriptor *getTargetDescriptor() const {
197 if (!p)
198 return nullptr;
199 if constexpr (std::is_base_of_v<cObject, std::remove_const_t<T>>)
200 return p->getDescriptor();
201 else
202 return omnetpp::ensureDescriptor<std::remove_const_t<T>>();
203 }
204};
205
206
207template<typename T>
208inline cWatchBase *createWatch(const char *varname, T& d) {
209 return new cWatch<std::remove_cv_t<T>>(varname, d);
210}
211
212template<typename T>
213inline cWatchBase *createWatch(const char *varname, T *& p) {
214 return new cPointerWatch<T>(varname, p);
215}
216
222template<typename T>
223class cComputedWatch : public cWatchBase
224{
225 private:
226 std::function<T()> fn;
227 mutable T cachedValue;
228
229 public:
230 cComputedWatch(const char *name, std::function<T()> f)
231 : cWatchBase(name), fn(f), cachedValue(f()) {}
232
233 virtual const char *getClassName() const override {
234 return getDescriptor()->getFullName();
235 }
236
237 virtual any_ptr getValuePointer() const override {
238 cachedValue = fn();
239 return any_ptr(&cachedValue);
240 }
241
242 virtual cClassDescriptor *getDescriptor() const override {
243 if (proxyDesc == nullptr) {
244 cClassDescriptor *targetDesc = omnetpp::ensureDescriptor<T>();
245 auto *nonconst_this = const_cast<cComputedWatch*>(this);
246 proxyDesc = new cWatchProxyDescriptor(nonconst_this, targetDesc);
247 nonconst_this->take(proxyDesc);
248 }
249 return proxyDesc;
250 }
251};
252
253template<typename F>
254inline cWatchBase *createLambdaWatch(const char *name, F&& fn) {
255 using T = std::invoke_result_t<F>;
256 return new cComputedWatch<T>(name, std::function<T()>(std::forward<F>(fn)));
257}
258
263
272#define WATCH(variable) omnetpp::createWatch(#variable,(variable))
273
274// Obsolete aliases to WATCH()
275#define WATCH_RW(variable) WATCH(variable)
276#define WATCH_OBJ(variable) WATCH(variable)
277#define WATCH_PTR(variable) WATCH(variable)
278#define WATCH_VECTOR(variable) WATCH(variable)
279#define WATCH_PTRVECTOR(variable) WATCH(variable)
280#define WATCH_LIST(variable) WATCH(variable)
281#define WATCH_PTRLIST(variable) WATCH(variable)
282#define WATCH_SET(variable) WATCH(variable)
283#define WATCH_PTRSET(variable) WATCH(variable)
284#define WATCH_MAP(variable) WATCH(variable)
285#define WATCH_PTRMAP(variable) WATCH(variable)
286
304#define WATCH_EXPR(name, expression) omnetpp::createLambdaWatch(name, [this]() { return (expression); })
305
320#define WATCH_LAMBDA(name, lambdaFunction) omnetpp::createLambdaWatch(name, lambdaFunction)
321
323
324} // namespace omnetpp
325
326
327#endif
328
329
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:233
virtual any_ptr getValuePointer() const override
Definition cwatch.h:237
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:242
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:159
virtual const char * getClassName() const override
Definition cwatch.h:168
virtual any_ptr getValuePointer() const override
Definition cwatch.h:175
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:182
virtual void forEachChild(cVisitor *visitor) override
Definition cwatch.h:170
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:81
virtual any_ptr getValuePointer() const =0
cWatchBase(const char *name)
Definition cwatch.h:94
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
Template Watch class that delegates to the type's cClassDescriptor for string conversion and inspecti...
Definition cwatch.h:117
virtual const char * getClassName() const override
Definition cwatch.h:123
virtual any_ptr getValuePointer() const override
Definition cwatch.h:130
virtual cClassDescriptor * getDescriptor() const override
Definition cwatch.h:137
virtual void forEachChild(cVisitor *visitor) override
Definition cwatch.h:125
SIM_API const char * opp_typename(const std::type_info &t)
Returns the name of a C++ type, correcting the quirks of various compilers.