#include "shmvar.h" #include CShmVariable::CShmVariable(void *pData, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, QObject *pParent) : QObject(pParent), m_vt(VT_Invalid), m_data({NULL}), m_varName(pszName) { if(!pData || !hShm) { Q_ASSERT_X(false, "CShmVariable::CShmVariable", "Invalid parameter!"); return; } m_data.pVoid = pData; m_hShm = hShm; setObjectName(QStringLiteral("CShmVariable")); if((m_nIndex = nIndex) >= 0) { m_varName += QString("%1%2%3").arg('[').arg(nIndex).arg(']'); } if(rti == typeid(bool)) { m_vt = VT_bool; m_cache.boolVal = *m_data.pBool; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_bool"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(char)) { #ifdef __CHAR_UNSIGNED__ m_vt = VT_UI1; m_cache.UI1Val = *m_data.pUI1; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI1"; #endif // _TRACK_TYPES_AT_LOAD #else m_vt = VT_I1; m_cache.I1Val = *m_data.pI1; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I1"; #endif // _TRACK_TYPES_AT_LOAD #endif } else if(rti == typeid(signed char)) { m_vt = VT_I1; m_cache.I1Val = *m_data.pI1; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I1"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(unsigned char)) { m_vt = VT_UI1; m_cache.UI1Val = *m_data.pUI1; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI1"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(short)) { m_vt = VT_I2; m_cache.I2Val = *m_data.pI2; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I2"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(unsigned short)) { m_vt = VT_UI2; m_cache.UI2Val = *m_data.pUI2; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI2"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(int)) { m_vt = VT_I4; m_cache.I4Val = *m_data.pI4; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I4"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(unsigned int)) { m_vt = VT_UI4; m_cache.UI4Val = *m_data.pUI4; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI4"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(long)) { if(sizeof(long) == sizeof(long long)) { m_vt = VT_I8; m_cache.I8Val = *m_data.pI8; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I8"; #endif // _TRACK_TYPES_AT_LOAD } else { m_vt = VT_I4; m_cache.I4Val = *m_data.pI4; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I4"; #endif // _TRACK_TYPES_AT_LOAD } } else if(rti == typeid(unsigned long)) { if(sizeof(unsigned long) == sizeof(unsigned long long)) { m_vt = VT_UI8; m_cache.UI8Val = *m_data.pUI8; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI8"; #endif // _TRACK_TYPES_AT_LOAD } else { m_vt = VT_UI4; m_cache.UI4Val = *m_data.pUI4; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI4"; #endif // _TRACK_TYPES_AT_LOAD } } else if(rti == typeid(long long)) { m_vt = VT_I8; m_cache.I8Val = *m_data.pI8; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_I8"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(unsigned long long)) { m_vt = VT_UI8; m_cache.UI8Val = *m_data.pUI8; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_UI8"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(float)) { m_vt = VT_float; m_cache.FloatVal = *m_data.pFloat; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_float"; #endif // _TRACK_TYPES_AT_LOAD } else if(rti == typeid(double)) { m_vt = VT_double; m_cache.DoubleVal = *m_data.pDouble; #if _TRACK_TYPES_AT_LOAD qDebug() << "VT_double"; #endif // _TRACK_TYPES_AT_LOAD } else { Q_ASSERT_X(false, "CShmVariable::CShmVariable", "Unknown data type!"); } } CShmVariable::~CShmVariable(void) { } void CShmVariable::valRaw(QVariant &v) { switch(m_vt) { case VT_bool: v.setValue(*m_data.pBool); break; case VT_I1: v.setValue((signed int)*m_data.pI1); break; case VT_UI1: v.setValue((unsigned int)*m_data.pUI1); break; case VT_I2: v.setValue((signed int)*m_data.pI2); break; case VT_UI2: v.setValue((unsigned int)*m_data.pUI2); break; case VT_I4: v.setValue(*m_data.pI4); break; case VT_UI4: v.setValue(*m_data.pUI4); break; case VT_I8: v.setValue(*m_data.pI8); break; case VT_UI8: v.setValue(*m_data.pUI8); break; case VT_float: v.setValue(*m_data.pFloat); break; case VT_double: v.setValue(*m_data.pDouble); break; default: break; } } QVariant CShmVariable::val(void) { QVariant v; Lock(); valRaw(v); Unlock(); return v; } void CShmVariable::setVal(const QVariant &val) { if(val.isValid() && !val.isNull()) { #if _TRACK_QT_WRITES char szDebugOut[256]; #endif // _TRACK_QT_WRITES Lock(); switch(m_vt) { case VT_bool: if(val.canConvert()) { m_cache.boolVal = val.toBool(); if(*m_data.pBool != m_cache.boolVal) { *m_data.pBool = m_cache.boolVal; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: bool %s@(%p) - %s", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.boolVal ? "true" : "false"); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_I1: if(val.canConvert()) { m_cache.I1Val = (signed char)val.toInt(); if(*m_data.pI1 != m_cache.I1Val) { *m_data.pI1 = m_cache.I1Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: signed char %s@(%p) - %hhd", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I1Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_UI1: if(val.canConvert()) { m_cache.UI1Val = (unsigned char)val.toInt(); if(*m_data.pUI1 != m_cache.UI1Val) { *m_data.pUI1 = m_cache.UI1Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: unsigned char %s@(%p) - %hhu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI1Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_I2: if(val.canConvert()) { m_cache.I2Val = (signed short)val.toInt(); if(*m_data.pI2 != m_cache.I2Val) { *m_data.pI2 = m_cache.I2Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: signed short %s@(%p) - %hd", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I2Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_UI2: if(val.canConvert()) { m_cache.UI2Val = (unsigned short)val.toInt(); if(*m_data.pUI2 != m_cache.UI2Val) { *m_data.pUI2 = m_cache.UI2Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: unsigned short %s@(%p) - %hu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI2Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_I4: if(val.canConvert()) { m_cache.I4Val = (signed int)val.toInt(); if(*m_data.pI4 != m_cache.I4Val) { *m_data.pI4 = m_cache.I4Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: signed int %s@(%p) - %d", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I4Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_UI4: if(val.canConvert()) { m_cache.UI4Val = (unsigned int)val.toInt(); if(*m_data.pUI4 != m_cache.UI4Val) { *m_data.pUI4 = m_cache.UI4Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: unsigned int %s@(%p) - %u", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI4Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_I8: if(val.canConvert()) { m_cache.I8Val = (signed long long)val.toLongLong(); if(*m_data.pI8 != m_cache.I8Val) { *m_data.pI8 = m_cache.I8Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: signed long long %s@(%p) - %lld", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I8Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_UI8: if(val.canConvert()) { m_cache.UI8Val = (unsigned long long)val.toLongLong(); if(*m_data.pUI8 != m_cache.UI8Val) { *m_data.pUI8 = m_cache.UI8Val; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: unsigned long long %s@(%p) - %llu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI8Val); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_float: if(val.canConvert()) { m_cache.FloatVal = (float)val.toFloat(); if(*m_data.pFloat != m_cache.FloatVal) { *m_data.pFloat = m_cache.FloatVal; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: float %s@(%p) - %f", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.FloatVal); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; case VT_double: if(val.canConvert()) { m_cache.DoubleVal = (double)val.toDouble(); if(*m_data.pDouble != m_cache.DoubleVal) { *m_data.pDouble = m_cache.DoubleVal; emitChanged(false); #if _TRACK_QT_WRITES sprintf(szDebugOut, "CShmVariable::setVal: double %s@(%p) - %f", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.DoubleVal); qDebug() << szDebugOut; #endif // _TRACK_QT_WRITES } } break; default: qDebug() << "CShmVariable::setVal: invalid vartype!"; break; } Unlock(); } } unsigned int CShmVariable::vt(void) const { return m_vt; } unsigned long long CShmVariable::CheckUpdateShm(bool fLock) { CHECK_UPDATE_SHM_RETVAL rv = {1, 0}; if(fLock) Lock(); switch(m_vt) { case VT_bool: if(m_cache.boolVal != *m_data.pBool) { m_cache.boolVal = *m_data.pBool; emitChanged(false); rv.nUpdated = 1; } break; case VT_I1: if(m_cache.I1Val != *m_data.pI1) { m_cache.I1Val = *m_data.pI1; emitChanged(false); rv.nUpdated = 1; } break; case VT_UI1: if(m_cache.UI1Val != *m_data.pUI1) { m_cache.UI1Val = *m_data.pUI1; emitChanged(false); rv.nUpdated = 1; } break; case VT_I2: if(m_cache.I2Val != *m_data.pI2) { m_cache.I2Val = *m_data.pI2; emitChanged(false); rv.nUpdated = 1; } break; case VT_UI2: if(m_cache.UI2Val != *m_data.pUI2) { m_cache.UI2Val = *m_data.pUI2; emitChanged(false); rv.nUpdated = 1; } break; case VT_I4: if(m_cache.I4Val != *m_data.pI4) { m_cache.I4Val = *m_data.pI4; emitChanged(false); rv.nUpdated = 1; } break; case VT_UI4: if(m_cache.UI4Val != *m_data.pUI4) { m_cache.UI4Val = *m_data.pUI4; emitChanged(false); rv.nUpdated = 1; } break; case VT_I8: if(m_cache.I8Val != *m_data.pI8) { m_cache.I8Val = *m_data.pI8; emitChanged(false); rv.nUpdated = 1; } break; case VT_UI8: if(m_cache.UI8Val != *m_data.pUI8) { m_cache.UI8Val = *m_data.pUI8; emitChanged(false); rv.nUpdated = 1; } break; case VT_float: if(m_cache.FloatVal != *m_data.pFloat) { m_cache.FloatVal = *m_data.pFloat; emitChanged(false); rv.nUpdated = 1; } break; case VT_double: if(m_cache.DoubleVal != *m_data.pDouble) { m_cache.DoubleVal = *m_data.pDouble; emitChanged(false); rv.nUpdated = 1; } break; default: break; } if(fLock) Unlock(); return rv.nRetval; } void CShmVariable::Lock(void) { ::GfaIpcLockSHM(m_hShm); // qDebug() << "CShmVariable::Lock"; } void CShmVariable::Unlock(void) { // qDebug() << "CShmVariable::Unlock"; ::GfaIpcUnlockSHM(m_hShm); } void CShmVariable::emitChanged(bool fLock) { // qDebug() << "val changed!"; if(fLock) emit valChanged(val()); else { QVariant v; valRaw(v); emit valChanged(v); } }