ArnLib  4.0.x
Active Registry Network
ArnItem.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2022 Michael Wiklund.
2 // All rights reserved.
3 // Contact: arnlib@wiklunden.se
4 //
5 // This file is part of the ArnLib - Active Registry Network.
6 // Parts of ArnLib depend on Qt and/or other libraries that have their own
7 // licenses. Usage of these other libraries is subject to their respective
8 // license agreements.
9 //
10 // GNU Lesser General Public License Usage
11 // This file may be used under the terms of the GNU Lesser General Public
12 // License version 2.1 as published by the Free Software Foundation and
13 // appearing in the file LICENSE_LGPL.txt included in the packaging of this
14 // file. In addition, as a special exception, you may use the rights described
15 // in the Nokia Qt LGPL Exception version 1.1, included in the file
16 // LGPL_EXCEPTION.txt in this package.
17 //
18 // GNU General Public License Usage
19 // Alternatively, this file may be used under the terms of the GNU General Public
20 // License version 3.0 as published by the Free Software Foundation and appearing
21 // in the file LICENSE_GPL.txt included in the packaging of this file.
22 //
23 // Other Usage
24 // Alternatively, this file may be used in accordance with the terms and conditions
25 // contained in a signed written agreement between you and Michael Wiklund.
26 //
27 // This program is distributed in the hope that it will be useful, but WITHOUT ANY
28 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
29 // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
30 //
31 
32 #include "ArnInc/ArnItem.hpp"
33 #include "private/ArnItem_p.hpp"
34 #include "ArnInc/ArnM.hpp"
35 #include "ArnLink.hpp"
36 #include <QTimerEvent>
37 #include <QBasicTimer>
38 #include <QMetaObject>
39 #include <QDebug>
40 
41 
42 #if QT_VERSION >= 0x050000
43 QMetaMethod ArnItem::_metaSignalChanged(
45  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)()>(&ArnItem::changed)));
46 QMetaMethod ArnItem::_metaSignalChangedInt(
47  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(int)>(&ArnItem::changed)));
48 QMetaMethod ArnItem::_metaSignalChangedReal(
49  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(ARNREAL)>(&ArnItem::changed)));
50 QMetaMethod ArnItem::_metaSignalChangedBool(
51  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(bool)>(&ArnItem::changed)));
52 QMetaMethod ArnItem::_metaSignalChangedString(
53  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(const QString&)>(&ArnItem::changed)));
54 QMetaMethod ArnItem::_metaSignalChangedByteArray(
55  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(const QByteArray&)>(&ArnItem::changed)));
56 QMetaMethod ArnItem::_metaSignalChangedVariant(
57  QMetaMethod::fromSignal( static_cast<void (ArnItem::*)(const QVariant&)>(&ArnItem::changed)));
58 #endif
59 
60 
61 class MQBasicTimer : public QBasicTimer
62 {
63 public:
65  {
66  _interval = 0;
67  }
68 
69  int interval() const {return _interval;}
70  void setInterval( int interval) {_interval = interval;}
71  void start(QObject* obj) {QBasicTimer::start( _interval, obj);}
72  void start( int msec, QObject* obj)
73  {
74  _interval = msec;
75  QBasicTimer::start( _interval, obj);
76  }
77 
78 private:
79  int _interval;
80 };
81 
82 
83 ArnItemPrivate::ArnItemPrivate()
84 {
85  _delayTimer = arnNullptr;
86  _isTemplate = false;
87 
88  _emitChanged = 0;
89  _emitChangedInt = 0;
90  _emitChangedReal = 0;
91  _emitChangedBool = 0;
92  _emitChangedString = 0;
93  _emitChangedByteArray = 0;
94 }
95 
96 
97 ArnItemPrivate::~ArnItemPrivate()
98 {
99  if (_delayTimer)
100  delete _delayTimer;
101 }
102 
103 
104 void ArnItem::init()
105 {
106 }
107 
108 
109 ArnItem::ArnItem( QObject *parent)
110  : ArnItemB( *new ArnItemPrivate, parent)
111 {
112  init();
113 }
114 
115 
116 ArnItem::ArnItem( const QString& path, QObject *parent)
117  : ArnItemB( *new ArnItemPrivate, parent)
118 {
119  init();
120  this->open( path);
121 }
122 
123 
124 ArnItem::ArnItem( const ArnItem& itemTemplate, const QString& path, QObject *parent)
125  : ArnItemB( *new ArnItemPrivate, parent)
126 {
127  init();
128  if (itemTemplate.isTemplate()) { // Template mode: Copy syncMode & Mode from template to this Item
129  this->addSyncMode( itemTemplate.syncMode(), true);
130  this->addMode( itemTemplate.getMode());
131  this->open( path);
132  }
133  else {
134  ArnM::errorLog( QString(tr("Should be template path=")) + path,
136  }
137 }
138 
139 
140 ArnItem::ArnItem( ArnItemPrivate& dd, QObject* parent)
141  : ArnItemB( dd, parent)
142 {
143  init();
144 }
145 
146 
147 void ArnItem::itemCreatedBelow( const QString& path)
148 {
149  emit arnItemCreated( path);
150 }
151 
152 
153 void ArnItem::itemModeChangedBelow( const QString& path, uint linkId, Arn::ObjectMode mode)
154 {
155  emit arnModeChanged( path, linkId, mode);
156 }
157 
158 
159 void ArnItem::timerEvent( QTimerEvent* ev)
160 {
161  Q_D(ArnItem);
162 
163  if (d->_delayTimer && (ev->timerId() == d->_delayTimer->timerId())) {
164  // qDebug() << "ArnItem delay doUpdate: path=" << path();
165  doItemUpdate( ArnLinkHandle::null());
166  }
167 
168  return ArnItemB::timerEvent( ev);
169 }
170 
171 
172 int ArnItem::delayTimerId() const
173 {
174  Q_D(const ArnItem);
175 
176  if (!d->_delayTimer) return 0;
177 
178  return d->_delayTimer->timerId();
179 }
180 
181 
182 ArnItem& ArnItem::setTemplate( bool isTemplate)
183 {
184  Q_D(ArnItem);
185 
186  d->_isTemplate = isTemplate;
187  return *this;
188 }
189 
190 
192 {
193  Q_D(const ArnItem);
194 
195  return d->_isTemplate;
196 }
197 
198 
199 void ArnItem::setDelay( int delay)
200 {
201  Q_D(ArnItem);
202 
203  if (!d->_delayTimer) {
204  d->_delayTimer = new MQBasicTimer;
205  }
206  d->_delayTimer->setInterval( delay);
207 }
208 
209 
210 int ArnItem::delay() const
211 {
212  Q_D(const ArnItem);
213 
214  if (!d->_delayTimer) return 0;
215 
216  return d->_delayTimer->interval();
217 }
218 
219 
221 {
222  Q_D(const ArnItem);
223 
224  return d->_delayTimer && d->_delayTimer->isActive();
225 }
226 
227 
229 {
230  if (isDelayPending()) {
231  doItemUpdate( ArnLinkHandle::null());
232  }
233 }
234 
235 
237 {
238  this->setValue( other);
239  return *this;
240 }
241 
242 
244 {
245  this->setValue( val);
246  return *this;
247 }
248 
249 
251 {
252  this->setValue( val);
253  return *this;
254 }
255 
256 
257 ArnItem& ArnItem::operator=( const QString& val)
258 {
259  this->setValue( val);
260  return *this;
261 }
262 
263 
264 ArnItem& ArnItem::operator=( const QByteArray& val)
265 {
266  this->setValue( val);
267  return *this;
268 }
269 
270 
271 ArnItem& ArnItem::operator=( const char* val)
272 {
273  this->setValue( val);
274  return *this;
275 }
276 
277 
279 {
280  this->setValue( val);
281  return *this;
282 }
283 
284 
286 {
287  this->setValue( val);
288  return *this;
289 }
290 
291 
293 {
294  this->setValue( val);
295  return *this;
296 }
297 
298 
299 ArnItem& ArnItem::operator=( const QVariant& val)
300 {
301  this->setValue( val);
302  return *this;
303 }
304 
305 
307 {
308  this->addValue( val);
309  return *this;
310 }
311 
312 
314 {
315  this->addValue( val);
316  return *this;
317 }
318 
319 
321 {
322  bool value = toBool();
323 
324  setValue( !value);
325 }
326 
327 
328 #if QT_VERSION >= 0x050000
329 
330 void ArnItem::connectNotify( const QMetaMethod &signal)
331 {
332  Q_D(ArnItem);
333 
334  if (signal == _metaSignalChanged) {
335  d->_emitChanged++;
336  }
337  else if (signal == _metaSignalChangedInt) {
338  d->_emitChangedInt++;
339  }
340  else if (signal == _metaSignalChangedReal) {
341  d->_emitChangedReal++;
342  }
343  else if (signal == _metaSignalChangedBool) {
344  d->_emitChangedBool++;
345  }
346  else if (signal == _metaSignalChangedString) {
347  d->_emitChangedString++;
348  }
349  else if (signal == _metaSignalChangedByteArray) {
350  d->_emitChangedByteArray++;
351  }
352  else if (signal == _metaSignalChangedVariant) {
353  d->_emitChangedVariant++;
354  }
355 }
356 
357 
358 void ArnItem::disconnectNotify( const QMetaMethod &signal)
359 {
360  Q_D(ArnItem);
361 
362  if (signal == _metaSignalChanged) {
363  d->_emitChanged--;
364  }
365  else if (signal == _metaSignalChangedInt) {
366  d->_emitChangedInt--;
367  }
368  else if (signal == _metaSignalChangedReal) {
369  d->_emitChangedReal--;
370  }
371  else if (signal == _metaSignalChangedBool) {
372  d->_emitChangedBool--;
373  }
374  else if (signal == _metaSignalChangedString) {
375  d->_emitChangedString--;
376  }
377  else if (signal == _metaSignalChangedByteArray) {
378  d->_emitChangedByteArray--;
379  }
380  else if (signal == _metaSignalChangedVariant) {
381  d->_emitChangedVariant--;
382  }
383 }
384 
385 
386 #else
387 
388 void ArnItem::connectNotify( const char *signal)
389 {
390  Q_D(ArnItem);
391 
392  if (QLatin1String( signal) == SIGNAL(changed())) {
393  d->_emitChanged++;
394  }
395  else if (QLatin1String( signal) == SIGNAL(changed(int))) {
396  d->_emitChangedInt++;
397  }
398 #ifdef ARNREAL_FLOAT
399  else if (QLatin1String( signal) == SIGNAL(changed(float))) {
400 #else
401  else if (QLatin1String( signal) == SIGNAL(changed(double))) {
402 #endif
403  d->_emitChangedReal++;
404  }
405  else if (QLatin1String( signal) == SIGNAL(changed(bool))) {
406  d->_emitChangedBool++;
407  }
408  else if (QLatin1String( signal) == SIGNAL(changed(QString))) {
409  d->_emitChangedString++;
410  }
411  else if (QLatin1String( signal) == SIGNAL(changed(QByteArray))) {
412  d->_emitChangedByteArray++;
413  }
414  else if (QLatin1String( signal) == SIGNAL(changed(QVariant))) {
415  d->_emitChangedVariant++;
416  }
417 }
418 
419 
420 void ArnItem::disconnectNotify( const char *signal)
421 {
422  Q_D(ArnItem);
423 
424  if (QLatin1String( signal) == SIGNAL(changed())) {
425  d->_emitChanged--;
426  }
427  else if (QLatin1String( signal) == SIGNAL(changed(int))) {
428  d->_emitChangedInt--;
429  }
430 #ifdef ARNREAL_FLOAT
431  else if (QLatin1String( signal) == SIGNAL(changed(float))) {
432 #else
433  else if (QLatin1String( signal) == SIGNAL(changed(double))) {
434 #endif
435  d->_emitChangedReal--;
436  }
437  else if (QLatin1String( signal) == SIGNAL(changed(bool))) {
438  d->_emitChangedBool--;
439  }
440  else if (QLatin1String( signal) == SIGNAL(changed(QString))) {
441  d->_emitChangedString--;
442  }
443  else if (QLatin1String( signal) == SIGNAL(changed(QByteArray))) {
444  d->_emitChangedByteArray--;
445  }
446  else if (QLatin1String( signal) == SIGNAL(changed(QVariant))) {
447  d->_emitChangedVariant--;
448  }
449 }
450 
451 #endif
452 
453 
454 void ArnItem::itemUpdated( const ArnLinkHandle& handleData, const QByteArray* value)
455 {
456  Q_D(ArnItem);
457 
458  if (!value) { // Update of item with no data supplied
459  if (d->_delayTimer) {
460  if (!d->_delayTimer->isActive()) {
461  d->_delayTimer->start( this);
462  // qDebug() << "ArnItem delay start: path=" << path();
463  }
464  }
465  else {
466  doItemUpdate( handleData);
467  }
468  }
469  else { // Update of item with data supplied (pipe in multi-thread)
470  if (d->_emitChanged) {
471  emit changed();
472  }
473  if (d->_emitChangedInt) {
474  emit changed( int( value->toInt()));
475  }
476  if (d->_emitChangedReal) {
477 #if defined( ARNREAL_FLOAT)
478  emit changed( float( value->toFloat()));
479 #else
480  emit changed( double( value->toDouble()));
481 #endif
482  }
483  if (d->_emitChangedBool) {
484  emit changed( bool( value->toInt() != 0));
485  }
486  if (d->_emitChangedString) {
487  emit changed( QString::fromUtf8( value->constData(), value->size()));
488  }
489  if (d->_emitChangedByteArray) {
490  emit changed( *value);
491  }
492  if (d->_emitChangedVariant) {
493  // Can only handle printable value ...
494  emit changed( QVariant( QString::fromUtf8( value->constData(), value->size())));
495  }
496  resetOnlyEcho(); // Nothing else yet ...
497  }
498 }
499 
500 
501 void ArnItem::doItemUpdate( const ArnLinkHandle& handleData)
502 {
503  Q_UNUSED(handleData);
504  Q_D(ArnItem);
505 
506 
507  if (d->_delayTimer ) {
508  d->_delayTimer->stop();
509  }
510 
511  if (d->_emitChanged) {
512  emit changed();
513  }
514  if (d->_emitChangedInt) {
515  emit changed( toInt());
516  }
517  if (d->_emitChangedReal) {
518  emit changed( toReal());
519  }
520  if (d->_emitChangedBool) {
521  emit changed( toBool());
522  }
523  if (d->_emitChangedString) {
524  emit changed( toString());
525  }
526  if (d->_emitChangedByteArray) {
527  emit changed( toByteArray());
528  }
529  if (d->_emitChangedByteArray) {
530  emit changed( toVariant());
531  }
532  resetOnlyEcho(); // Nothing else yet ...
533 }
534 
535 
536 void ArnItem::modeUpdate( Arn::ObjectMode mode, bool isSetup)
537 {
538  ArnItemB::modeUpdate( mode, isSetup); // must be called for base-class update
539  if (isSetup) return;
540 
541  emit modeChanged( mode);
542 }
543 
544 
546 {
547 }
548 
549 
550 QTextStream &operator<<( QTextStream& out, const ArnItem& item)
551 {
552  out << item.toString();
553  return out;
554 }
555 
556 
557 
558 
void setValue(const ArnItem &other, int ignoreSame=Arn::SameValue::DefaultAction)
Assign the value of an other ArnItem to an Arn Data Object
Definition: ArnItem.hpp:440
void setDelay(int delay)
Set delay of data changed signal.
Definition: ArnItem.cpp:199
ArnItem(QObject *parent=arnNullptr)
Standard constructor of a closed handle.
Definition: ArnItem.cpp:109
ArnItem & operator+=(int val)
Definition: ArnItem.cpp:306
QTextStream & operator<<(QTextStream &out, const ArnItem &item)
Definition: ArnItem.cpp:550
void start(int msec, QObject *obj)
Definition: ArnItem.cpp:72
Arn::ObjectSyncMode syncMode() const
Definition: ArnItem.hpp:172
Arn::ObjectMode getMode() const
Definition: ArnItem.hpp:166
bool isDelayPending() const
Definition: ArnItem.cpp:220
void addMode(Arn::ObjectMode mode)
Add general mode settings for this Arn Data Object
Definition: ArnItem.hpp:159
void toggleBool()
Toggle the bool at the Arn Data Object
Definition: ArnItem.cpp:320
ArnItem & operator=(const ArnItem &other)
Definition: ArnItem.cpp:236
int delay() const
Get delay of data changed signal.
Definition: ArnItem.cpp:210
QByteArray toByteArray(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:387
void changed()
Signals emitted when data in Arn Data Object is changed.
bool open(const QString &path)
Open a handle to an Arn Data Object
Definition: ArnItemB.cpp:91
ArnItem & setTemplate(bool isTemplate=true)
Mark this ArnItem as a template.
Definition: ArnItem.cpp:182
QVariant toVariant(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:394
void modeChanged(Arn::ObjectMode mode)
Signal emitted when mode in Arn Data Object is changed.
bool isTemplate() const
Definition: ArnItem.cpp:191
QString toString(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:380
bool toBool(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:373
QString path(Arn::NameF nameF=Arn::NameF::EmptyOk) const
Path of the Arn Data Object
void bypassDelayPending()
Definition: ArnItem.cpp:228
void start(QObject *obj)
Definition: ArnItem.cpp:71
#define ARNREAL
Definition: Arn.hpp:44
void arnItemCreated(const QString &path)
Signal emitted when an Arn Data Object is created in the tree below.
ARNREAL toReal(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:366
Base class handle for an Arn Data Object.
Definition: ArnItemB.hpp:59
uint linkId() const
Get the id for this Arn Data Object
void setInterval(int interval)
Definition: ArnItem.cpp:70
static void errorLog(QString errText, ArnError err=ArnError::Undef, void *reference=arnNullptr)
Definition: ArnM.cpp:1025
int toInt(bool *isOk=arnNullptr) const
Definition: ArnItem.hpp:352
void arnModeChanged(const QString &path, uint linkId, Arn::ObjectMode mode)
Signal emitted when an Arn Data Object in the tree below has a general mode change.
Handle for an Arn Data Object.
Definition: ArnItem.hpp:72
void addValue(int value)
AtomicOp adds an integer to an Arn Data Object
Definition: ArnItem.hpp:548
virtual ~ArnItem()
Definition: ArnItem.cpp:545
int interval() const
Definition: ArnItem.cpp:69