WARNING: USE THIS SOFTWARE AT YOUR OWN RISK! THIS IS EXPERIMENTAL SOFTWARE NOT INTENDED FOR PRODUCTION USE! Zuble is currently an early stage prototype. As such Zuble is minimally tested and inherently unstable. It is provided for experimental, development, and demonstration purposes only. Zuble QML Types   |  Zuble C++ Classes   |  Zuble Overview
Zuble  0.1
Zuble Framework C++/QML extension API
ZAndGate.cpp
Go to the documentation of this file.
1 #include "ZAndGate.h"
2 #include <QVariant>
3 #include <QtQml>
4 #include "zglobal.h"
5 
6 namespace Zbl {
7 
8 ZAndGate::ZAndGate(QObject *parent)
9  : QObject(parent), m_value(false)
10 {
11 
12 }
13 
15 {
16  //ZBL_REGISTER_LOGGED_OBJECT
17 
18  qmlRegisterType<ZAndGate>("org.zuble.qml", 1, 0, "ZAndGate");
19 }
20 
21 
23 {
24  return m_value;
25 }
26 
27 bool ZAndGate::addInputProperty(QObject* targetObject,
28  const QString& propertyName,
29  const QString& signalName)
30 {
31  // TBD: check if input object is in same thread as this object
32 
33  // TBD: check if input already exists and if so ignore request, return error
34 
35  // TBD: check for errors in following code and abort accordingly
36 
37  QString message = ptrStr(targetObject);
38 
39  //qDebug("ZAndGate:: target object = %s",message.toUtf8().constData());
40 
41  QString sigName;
42 
43  if(signalName.isEmpty())
44  sigName = QString("%1Changed()").arg(propertyName);
45  else
46  {
47  //sigName = QString("on%1()").arg(signalName);
48  sigName = signalName;
49  }
50  //qDebug("ZAndGate:: signal name = %s", sigName.toUtf8().constData());
51 
52  QByteArray normalSig = QMetaObject::normalizedSignature(sigName.toUtf8().constData());
53  //qDebug("ZAndGate:: normalized signal name = %s", normalSig.constData());
54 
55 
56  // find meta data for object/property changed connection
57 
58  const QMetaObject *mo = targetObject->metaObject();
59 
60  int sigIndex = mo->indexOfSignal(QMetaObject::normalizedSignature(sigName.toUtf8().constData()));
61 
62  //qDebug("ZAndGate:: addInputProperty signal = %d", sigIndex);
63 
64  QMetaMethod metaSignal = mo->method(sigIndex);
65 
66  int slotIndex = metaObject()->indexOfSlot("onPropChanged()");
67 
68  //qDebug("ZAndGate:: addInputProperty slot = %d", slotIndex);
69 
70  QMetaMethod metaSlot = metaObject()->method(slotIndex);
71 
72  // add prop to map
73 
74  m_props.insertMulti(targetObject, proxy(propertyName,targetObject->property(propertyName.toUtf8().constData()).toBool()));
75 
76  // connect to property change signal on target object
77 
78  connect(targetObject, metaSignal, this, metaSlot);
79 
80  evaluate(); // TBD: this is overkill! we need only evaluate the added property!
81 
82  return true;
83 }
84 
85 bool ZAndGate::removeInputProperty(QObject* targetObject, const QString& propertyName)
86 {
87  qDebug("ZAndGate ==> Oops! removeInputProperty not implemented! Sorry.");
88  return false;
89 }
90 
92 {
93  m_props.clear();
94 
95  bool previous = m_value;
96 
97  m_value = false;
98 
99  if(previous != m_value)
100  emit outputChanged();
101 }
102 
104 {
105 
106  // iterate first to last for sender object
107  // if any prop of sender becomes false and output == true then output = false
108  // else if all props of sender become true and output == false check local copy of all props
109  // of all objects and set output accordingly
110 
111  QObject* targetObj = sender();
112 
113  QString message = ptrStr(targetObj);
114  QString strThis = ptrStr(this);
115 
116  //qDebug("ZAndGate:%s ==> sender =%s", cStr(strThis), cStr(message) );
117 
118  bool allTrue = true;
119  bool valueChanged = false;
120  bool foundObject = false;
121 
123 
124  while(i.hasNext())
125  {
126  i.next();
127 
128  proxy next = i.value();
129 
130  if(i.key() != targetObj)
131  {
132  if(foundObject)
133  break;
134  else
135  continue;
136  }
137 
138  foundObject = true;
139 
140  bool nextValue = waitGetProperty(targetObj, next.first).toBool();
141 
142  if(next.second != nextValue)
143  {
144  valueChanged = true;
145 
146  if(!nextValue)
147  allTrue = false;
148 
149  i.setValue(proxy(next.first,nextValue));
150  }
151  else
152  {
153  if(!next.second)
154  allTrue = false;
155  }
156 
157  }
158 
159  if(valueChanged)
160  {
161  if(!allTrue && m_value)
162  {
163  m_value = false;
164 
165  emit outputChanged();
166  }
167  else if(allTrue && !m_value)
168  evaluate();
169  }
170 
171 
172 }
173 
174 QVariant ZAndGate::waitGetProperty(QObject* targetObj, const QString& name)
175 {
176  QVariant retValue;
177 
179 
180  if(inObjectThread(this))
181  {
182  retValue = targetObj->property(cStr(name));
183  }
184  else
185  {
186  QMetaObject::invokeMethod(targetObj,"property",
187  Qt::BlockingQueuedConnection,
188  Q_RETURN_ARG(QVariant, retValue),
189  Q_ARG(const QString&,name));
190  }
191 
192  ZBL_SLOT_END_RETURN(retValue, QVariant(),
194 }
195 
197 {
198  bool allTrue = true;
199 
201 
202  while(i.hasNext())
203  {
204  i.next();
205 
206  proxy next = i.value();
207 
208  if(!next.second)
209  {
210  if(m_value)
211  {
212  m_value = false;
213  emit outputChanged();
214  }
215  allTrue = false;
216  break;
217  }
218  }
219 
220  if(allTrue && !m_value)
221  {
222  m_value = true;
223 
224  emit outputChanged();
225  }
226 
227 }
228 
229 
230 } // Zbl
propMap m_props
A map of object property proxies, by object pointer. Each proxy identifies one property. Multiple proxies may exist per input object.
Definition: ZAndGate.h:139
QMutableMapIterator< QObject *, proxy > propIterator
iterator for object/propertyName/value triplet maps
Definition: ZAndGate.h:73
static void registerType()
Registers ZAndGate as a QML type.
Definition: ZAndGate.cpp:14
#define Z_FAC_JS
Definition: zglobal.h:123
void evaluate()
Definition: ZAndGate.cpp:196
Q_INVOKABLE void removeAllProperties()
Removes all properties from the watched properties list.
Definition: ZAndGate.cpp:91
Q_INVOKABLE bool removeInputProperty(QObject *targetObject, const QString &propertyName)
Removes a property from the watched properties list.
Definition: ZAndGate.cpp:85
bool m_value
Current output value of the AND gate. True if all input properties are true, false otherwise...
Definition: ZAndGate.h:146
void outputChanged()
Definition: ZAndGate.cpp:6
bool getValue()
Definition: ZAndGate.cpp:22
#define ZBL_SLOT_BEGIN_TRY
Definition: zglobal.h:128
ZAndGate(QObject *parent=nullptr)
Definition: ZAndGate.cpp:8
QPair< QString, bool > proxy
propertyName/value
Definition: ZAndGate.h:58
void onPropChanged()
Definition: ZAndGate.cpp:103
#define cStr(qStr)
Definition: zglobal.h:49
bool inObjectThread(const QObject &object)
Definition: zglobal.h:173
#define ptrStr(ptr)
Definition: zglobal.h:54
QVariant waitGetProperty(QObject *targetObj, const QString &name)
Definition: ZAndGate.cpp:174
#define ZBL_SLOT_END_RETURN(return_success, return_failed, facility, code, error_message)
Definition: zglobal.h:141
Q_INVOKABLE bool addInputProperty(QObject *targetObject, const QString &propertyName, const QString &signalName=QString())
Adds a property to the watched properties list.
Definition: ZAndGate.cpp:27