PDA

View Full Version : knowing when the value of an integer changes.



emp1953
1st December 2018, 23:37
I have a long unsigned int "error_word" where each bit represents an operation in my application. If the bit is set, that operation has had an error or failed and needs to be looked at.

I realize that primatives do not have signals or events associated with them.

Is there some other data type or object I can use that will send an event/signal that I can monitor. I currently have the code set up with a timer that calls a slot that compares the value of the current error_word to its previous value 2 seconds ago. I'm hoping someone in this forum has a suggestion

Thanks

-emp1953

d_stranz
2nd December 2018, 16:58
As you know, only QObject-based classes can have signals or slots. My initial idea was to make a QObject class to hold the value of the variable you want to monitor, and override some of the basic functions, something like this (untested code!):



class MonitoredValue : public QObject
{
Q_OBJECT;

public:
MonitoredValue( const uint32_t & initialVal, QObject * parent = 0 ) : QObject( parent ), monitoredVal( initialVal ) {}
virtual ~MonitoredVal() {}

// read-only access
const uint32_t & operator() const { return monitoredVal; }
uint32_t & operator() const { return monitoredVal; }

// assignment
const MonitoredValue & operator=( const uint32_t & newVal )
{ emit valueChanging( monitoredVal ); monitoredVal = newVal; emit valueChanged( monitoredVal ); return *this; }

const MonitoredValue & operator=( const MonitoredValue & rhs )
{ emit valueChanging( monitoredVal ); monitoredVal = rhs.monitoredVal; emit valueChanged( monitoredVal ); return *this; }

// cast operators
operator uint32_t & () { return monitoredVal; }
operator const uint32_t & () const { return monitoredVal; }

signals:
void valueChanging( const uint32_t & val );
void valueChanged( const uint32_t & val );

private:
uint32_t monitoredVal;
};

Example:




using ErrorWord = MonitoredValue;

ErrorWord errorWord( 0 );
connect( &errorWord, &ErrorWord::valueChanging, this, &MyClass::errorChanging );
connect( &errorWord, &ErrorWord::valueChanged, this, &MyClass::errorChanged );

uint32_t currentError = errorWord;

errorWord = 42; // assigns new error, emits signals;


It would be nice if you could create this as a template, so that the monitored value could be any type, but Qt doesn't permit that for QObject classes. It would also be nice if you could connect any member function of a class to a slot, but as far as I can tell, the signal / slot mechanism requires that the class emitting the signal be derived from QObject.

And because Qt also doesn't support copy constructors or assignment operators for QObject classes, this method may not work without some modification.

You can also use other signal / slot mechanisms, like Boost Signals2 (https://www.boost.org/doc/libs/1_63_0/doc/html/signals2.html). This might work better for your purpose than Qt's version.

emp1953
2nd December 2018, 22:24
As you know, only QObject-based classes can have signals or slots. My initial idea was to make a QObject class to hold the value of the variable you want to monitor, and override some of the basic functions, something like this (untested code!):

Thank you for that, I'll give it a go.

emp1953

d_stranz
3rd December 2018, 00:44
Please report back and tell us how it goes.

emp1953
15th January 2019, 18:58
I haven't had the opportunity to work on this project again, but will shortly. I will provide my results.