allow elam to delve into QObject properties
authorKonrad Rosenbaum <konrad@silmor.de>
Tue, 12 Jul 2016 17:00:24 +0000 (19:00 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Tue, 12 Jul 2016 17:00:24 +0000 (19:00 +0200)
elam/include/elamengine.h
elam/src/elamengine.cpp
elam/tests/eval/eval.cpp
elam/tests/eval/eval.h

index 6c4a545..e2d1f5b 100644 (file)
@@ -266,6 +266,10 @@ class ELAM_EXPORT Engine:public QObject
        private:
                ///parse a literal
                QPair<QString,QVariant>parseLiteral(QString,int);
+               ///helper: find whether a variable/constant exists
+               bool valueExists(QMap<QString,QVariant>list,QString name)const;
+               ///helper: find a specific value for a variable/constant
+               QVariant findValue(QMap<QString,QVariant>list,QString name)const;
 };
 
 //end of namespace
index f4f8738..1cc3e56 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <QDebug>
 #include <DPtr>
+#include <QStringList>
 
 namespace ELAM {
 
@@ -156,16 +157,61 @@ CharacterClassSettings Engine::characterClasses()
        return d->cclass;
 }
 
+bool Engine::valueExists ( QMap< QString, QVariant > list, QString name )const
+{
+       //simple:
+       if(list.contains(name))return true;
+       //parse for dots
+       QChar dot=d->cclass.dotChar();
+       if(dot.isNull())return false;
+       QStringList nlist=name.split(dot);
+       //split and explore
+       QString n1=nlist.takeFirst();
+       if(!list.contains(n1))return false;
+       QVariant cur=list[n1];
+       while(nlist.size()>0){
+               if(!cur.canConvert<QObject*>())return false;
+               QByteArray n=nlist.takeFirst().toLatin1();
+               QObject*o=cur.value<QObject*>();
+               if(!o)return false;
+               if(!o->dynamicPropertyNames().contains(n)&&o->metaObject()->indexOfProperty(n.data())<0)
+                       return false;
+               cur=o->property(n.constData());
+       }
+       return cur.isValid();
+}
+
+QVariant Engine::findValue ( QMap< QString, QVariant > list, QString name )const
+{
+       if(list.contains(name))return list[name];
+       //parse for dots
+       QChar dot=d->cclass.dotChar();
+       if(dot.isNull())return QVariant();
+       QStringList nlist=name.split(dot);
+       //split and explore
+       QString n1=nlist.takeFirst();
+       if(!list.contains(n1))return QVariant();
+       QVariant cur=list[n1];
+       while(nlist.size()>0){
+               if(!cur.canConvert<QObject*>())return QVariant();
+               QByteArray n=nlist.takeFirst().toLatin1();
+               QObject*o=cur.value<QObject*>();
+               if(!o)return QVariant();
+               if(!o->dynamicPropertyNames().contains(n)&&o->metaObject()->indexOfProperty(n.data())<0)
+                       return QVariant();
+               cur=o->property(n.constData());
+       }
+       return cur;
+}
+
 QVariant Engine::getConstant(QString n) const
 {
-       if(d->consts.contains(n))return d->consts[n];
-       return QVariant();
+       return findValue(d->consts,n);
 }
 
 QVariant Engine::getVariable(QString n) const
 {
-       if(d->vars.contains(n))return d->vars[n];
-       return QVariant();
+       return findValue(d->vars,n);
 }
 
 QVariant Engine::getValue(QString n) const
@@ -177,12 +223,12 @@ QVariant Engine::getValue(QString n) const
 
 bool Engine::hasConstant(QString n) const
 {
-       return d->consts.contains(n);
+       return valueExists(d->consts,n);
 }
 
 bool Engine::hasVariable(QString n) const
 {
-       return d->vars.contains(n);
+       return valueExists(d->vars,n);
 }
 
 bool Engine::hasValue(QString n) const
index afdf8df..17e3b6d 100644 (file)
@@ -38,6 +38,26 @@ void ElamTest::evaltest()
        
 }
 
+void ElamTest::dottest()
+{
+       StringEngine ie;
+       ie.characterClasses().setDotChar('.');
+       QObject obj;
+       obj.setObjectName("hello");
+       obj.setProperty("dynamic","juhoo");
+       ie.setVariable("b",QVariant::fromValue(&obj));
+       QVERIFY(ie.hasVariable("b.objectName"));
+       QCOMPARE(ie.getVariable("b.objectName"),QVariant("hello"));
+       QVERIFY(ie.hasVariable("b.dynamic"));
+       QCOMPARE(ie.getVariable("b.dynamic"),QVariant("juhoo"));
+       QString exs="a=b.objectName+' world '+b.dynamic";
+       Expression ex=ie.expression(exs);
+//     qDebug()<<"expression:\n"<<ex;
+       QVariant v=ie.evaluate(ex);
+       QCOMPARE(v,QVariant("hello world juhoo"));
+       QCOMPARE(ie.getVariable("a"),QVariant("hello world juhoo"));
+}
+
 static QVariant mycount(const QList<QVariant>&args,Engine&)
 {
        return (qlonglong)args.size();
@@ -80,4 +100,4 @@ void ElamTest::functest()
 }
 
 
-QTEST_MAIN(ElamTest)
\ No newline at end of file
+QTEST_MAIN(ElamTest)
index ef4409c..7eb7237 100644 (file)
@@ -9,4 +9,5 @@ class ElamTest:public QObject
                void excepttest();
                void counttest();
                void functest();
+               void dottest();
 };