1616
1717namespace inet {
1818
19+ namespace internal {
20+ void refreshDisplayString (cModule *thisModule, const StringFormat::IResolver *thisModuleAsResolver);
21+ std::string doResolveExpression (cModule *targetModule, const char *expression);
22+ }
23+
1924/* *
2025 * A base functionality for all INET modules that implements behavior common to all modules.
2126 *
@@ -30,36 +35,14 @@ class INET_API ModuleMixin : public T, public StringFormat::IResolver
3035 static_assert (std::is_base_of<cModule, T>::value, " Type parameter of ModuleMixin must be a subclass of cModule" );
3136
3237 protected:
33- class cCollectObjectsVisitor : public cVisitor
34- {
35- public:
36- const char *name;
37- std::vector<cObject*> objects;
38-
39- public:
40- cCollectObjectsVisitor (const char *name): name(name) { }
41-
42- protected:
43- virtual bool visit (cObject *object) override {
44- if (object->isName (name))
45- objects.push_back (object);
46- return true ;
47- }
48- };
4938
5039 protected:
5140 virtual void initialize () override { T::initialize (); }
5241 virtual void initialize (int stage) override { T::initialize (stage); }
5342
5443 virtual void refreshDisplay () const override
5544 {
56- if (T::hasPar (" displayStringTextFormat" )) {
57- auto displayStringTextFormat = T::par (" displayStringTextFormat" ).stringValue ();
58- if (!opp_isempty (displayStringTextFormat)) {
59- auto text = StringFormat::formatString (displayStringTextFormat, this );
60- T::getDisplayString ().setTagArg (" t" , 0 , text.c_str ());
61- }
62- }
45+ internal::refreshDisplayString (const_cast <ModuleMixin<T>*>(this ), this );
6346 T::refreshDisplay ();
6447 }
6548
@@ -72,45 +55,7 @@ class INET_API ModuleMixin : public T, public StringFormat::IResolver
7255
7356 virtual std::string resolveExpression (const char *expression) const override
7457 {
75- const char *lastDot = strrchr (expression, ' .' );
76-
77- cModule *targetModule = const_cast <ModuleMixin<T>*>(this );
78- const char *fieldName = expression;
79-
80- if (lastDot != nullptr ) {
81- // Extract submodule path (everything before the last dot)
82- std::string submodulePath (expression, lastDot - expression);
83-
84- targetModule = const_cast <ModuleMixin<T>*>(this )->getModuleByPath (submodulePath.c_str ());
85-
86-
87- fieldName = lastDot + 1 ;
88- }
89-
90- cCollectObjectsVisitor visitor (fieldName);
91- visitor.processChildrenOf (targetModule);
92-
93- if (visitor.objects .empty ())
94- throw cRuntimeError (" Unknown expression: %s" , expression);
95-
96- if (visitor.objects .size () > 1 ) {
97- std::stable_sort (visitor.objects .begin (), visitor.objects .end (), [] (const cObject *o1, const cObject *o2) {
98- return dynamic_cast <const cWatchBase *>(o1) != nullptr && dynamic_cast <const cWatchBase *>(o2) == nullptr ;
99- });
100- }
101-
102- // special case so that strings are displayed without quotes
103- if (auto *par = dynamic_cast <cPar *>(visitor.objects [0 ])) {
104- if (par->getType () == cPar::STRING )
105- return par->stdstringValue ();
106- }
107- if (auto *watchBase = dynamic_cast <cWatchBase *>(visitor.objects [0 ])) {
108- any_ptr ptr = watchBase->getValuePointer ();
109- if (ptr.contains <std::string>())
110- return *ptr.get <std::string>();
111- }
112-
113- return visitor.objects [0 ]->str ();
58+ return internal::doResolveExpression (const_cast <ModuleMixin<T>*>(this ), expression);
11459 }
11560};
11661
0 commit comments