123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- #include <limits.h>
- #include <limits>
- #include "logvar.h"
- #include "debug.h"
- #define GET_BOOL_VAL(p, m) (!!(*p & m))
- #define SET_BIT(p, m) (*p |= m)
- #define CLR_BIT(p, m) (*p &= ~m)
- #define STORE_BIT(p, m, b) (b) ? SET_BIT(p, m) : CLR_BIT(p, m)
- /////////////////////////////////////////////////////////////////////////////
- CLogVariable::CLogVariable(LogTypes lt, void *pData, bool *pbLogCond, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, CLoggable *pParent)
- : m_lt(lt), m_pbLogCond(pbLogCond), m_bOldLogCond(false), m_name(pszName), m_pszPath(NULL), m_nIndex(nIndex), m_vt(VT_Invalid), m_data({NULL}),
- m_fLastSample(0), m_fSamples(0), m_pParent(pParent), m_nUpdates(0), m_nTagID(0), m_nSampleCount(0), m_pnCvByte(NULL), m_nCvMask(0), m_bCvIsBit(false), m_bIsDbPersistant(_IS_DB_PERSISTENT_LOGTYPE(lt))
- {
- if(!pData || !hShm)
- {
- ASSERT(false);
- }
- m_bIsCondLog = _IS_CONDITIONAL_LOGTYPE(m_lt);
- m_bIsIntervalLog = _IS_INTERVAL_LOGTYPE(m_lt);
- if(m_bIsCondLog && !m_pbLogCond)
- {
- ASSERT(false);
- }
- m_data.pVoid = pData;
- m_hShm = hShm;
- m_fMin = std::numeric_limits<double>::infinity();
- m_fMax = -std::numeric_limits<double>::infinity();
- if(rti == typeid(bool))
- {
- m_vt = VT_bool;
- m_cache.boolVal = *m_data.pBool;
- }
- else if(rti == typeid(char))
- {
- #ifdef __CHAR_UNSIGNED__
- m_vt = VT_UI1;
- m_cache.UI1Val = *m_data.pUI1;
- #else
- m_vt = VT_I1;
- m_cache.I1Val = *m_data.pI1;
- #endif
- }
- else if(rti == typeid(signed char))
- {
- m_vt = VT_I1;
- m_cache.I1Val = *m_data.pI1;
- }
- else if(rti == typeid(unsigned char))
- {
- m_vt = VT_UI1;
- m_cache.UI1Val = *m_data.pUI1;
- }
- else if(rti == typeid(short))
- {
- m_vt = VT_I2;
- m_cache.I2Val = *m_data.pI2;
- }
- else if(rti == typeid(unsigned short))
- {
- m_vt = VT_UI2;
- m_cache.UI2Val = *m_data.pUI2;
- }
- else if(rti == typeid(int))
- {
- m_vt = VT_I4;
- m_cache.I4Val = *m_data.pI4;
- }
- else if(rti == typeid(unsigned int))
- {
- m_vt = VT_UI4;
- m_cache.UI4Val = *m_data.pUI4;
- }
- else if(rti == typeid(long))
- {
- if(sizeof(long) == sizeof(long long))
- {
- m_vt = VT_I8;
- m_cache.I8Val = *m_data.pI8;
- }
- else
- {
- m_vt = VT_I4;
- m_cache.I4Val = *m_data.pI4;
- }
- }
- else if(rti == typeid(unsigned long))
- {
- if(sizeof(unsigned long) == sizeof(unsigned long long))
- {
- m_vt = VT_UI8;
- m_cache.UI8Val = *m_data.pUI8;
- }
- else
- {
- m_vt = VT_UI4;
- m_cache.UI4Val = *m_data.pUI4;
- }
- }
- else if(rti == typeid(long long))
- {
- m_vt = VT_I8;
- m_cache.I8Val = *m_data.pI8;
- }
- else if(rti == typeid(unsigned long long))
- {
- m_vt = VT_UI8;
- m_cache.UI8Val = *m_data.pUI8;
- }
- else if(rti == typeid(float))
- {
- m_vt = VT_float;
- m_cache.FloatVal = *m_data.pFloat;
- }
- else if(rti == typeid(double))
- {
- m_vt = VT_double;
- m_cache.DoubleVal = *m_data.pDouble;
- }
- else
- {
- ASSERT(false);
- }
- }
- CLogVariable::CLogVariable(LogTypes lt, void *pData, void *pBase, size_t nCvOffset, unsigned int nCvBitNr, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, CLoggable *pParent) :
- m_lt(lt), m_bOldLogCond(false), m_name(pszName), m_pszPath(NULL), m_nIndex(nIndex), m_fLastSample(0), m_fSamples(0), m_pParent(pParent), m_nUpdates(0), m_nTagID(0), m_nSampleCount(0), m_bCvIsBit(true), m_bIsDbPersistant(_IS_DB_PERSISTENT_LOGTYPE(lt))
- {
- if(!pData || !hShm || nCvBitNr > 7)
- {
- ASSERT(false);
- }
- m_bIsCondLog = _IS_CONDITIONAL_LOGTYPE(m_lt);
- m_bIsIntervalLog = _IS_INTERVAL_LOGTYPE(m_lt);
- m_data.pVoid = pData;
- m_hShm = hShm;
- m_fMin = std::numeric_limits<double>::infinity();
- m_fMax = -std::numeric_limits<double>::infinity();
- m_pnCvByte = (uint8_t*)pBase + nCvOffset;
- m_nCvMask = 0x01 << nCvBitNr;
- if(rti == typeid(bool))
- {
- m_vt = VT_bool;
- m_cache.boolVal = *m_data.pBool;
- }
- else if(rti == typeid(char))
- {
- #ifdef __CHAR_UNSIGNED__
- m_vt = VT_UI1;
- m_cache.UI1Val = *m_data.pUI1;
- #else
- m_vt = VT_I1;
- m_cache.I1Val = *m_data.pI1;
- #endif
- }
- else if(rti == typeid(signed char))
- {
- m_vt = VT_I1;
- m_cache.I1Val = *m_data.pI1;
- }
- else if(rti == typeid(unsigned char))
- {
- m_vt = VT_UI1;
- m_cache.UI1Val = *m_data.pUI1;
- }
- else if(rti == typeid(short))
- {
- m_vt = VT_I2;
- m_cache.I2Val = *m_data.pI2;
- }
- else if(rti == typeid(unsigned short))
- {
- m_vt = VT_UI2;
- m_cache.UI2Val = *m_data.pUI2;
- }
- else if(rti == typeid(int))
- {
- m_vt = VT_I4;
- m_cache.I4Val = *m_data.pI4;
- }
- else if(rti == typeid(unsigned int))
- {
- m_vt = VT_UI4;
- m_cache.UI4Val = *m_data.pUI4;
- }
- else if(rti == typeid(long))
- {
- if(sizeof(long) == sizeof(long long))
- {
- m_vt = VT_I8;
- m_cache.I8Val = *m_data.pI8;
- }
- else
- {
- m_vt = VT_I4;
- m_cache.I4Val = *m_data.pI4;
- }
- }
- else if(rti == typeid(unsigned long))
- {
- if(sizeof(unsigned long) == sizeof(unsigned long long))
- {
- m_vt = VT_UI8;
- m_cache.UI8Val = *m_data.pUI8;
- }
- else
- {
- m_vt = VT_UI4;
- m_cache.UI4Val = *m_data.pUI4;
- }
- }
- else if(rti == typeid(long long))
- {
- m_vt = VT_I8;
- m_cache.I8Val = *m_data.pI8;
- }
- else if(rti == typeid(unsigned long long))
- {
- m_vt = VT_UI8;
- m_cache.UI8Val = *m_data.pUI8;
- }
- else if(rti == typeid(float))
- {
- m_vt = VT_float;
- m_cache.FloatVal = *m_data.pFloat;
- }
- else if(rti == typeid(double))
- {
- m_vt = VT_double;
- m_cache.DoubleVal = *m_data.pDouble;
- }
- else
- {
- ASSERT(false);
- }
- }
- CLogVariable::~CLogVariable(void)
- {
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::InitPath(CLoggable *pParent, const char *pszMemberName)
- {
- if(!pszMemberName)
- pszMemberName = "";
- if(pParent)
- {
- m_path = pParent->GetPath();
- m_path += "/";
- m_path += pszMemberName;
- if(m_nIndex >= 0)
- {
- char szIndex[32];
- sprintf(szIndex, "[%d]", m_nIndex);
- m_path += szIndex;
- }
- }
- else
- {
- m_path = pszMemberName;
- }
- m_pszPath = m_path.c_str();
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::InitTagID(CDataLogger &rdl)
- {
- if((m_nTagID = rdl.GetTagID(m_pszPath, (int)m_vt, (int)m_lt)) == ULONG_MAX)
- {
- ASSERT(false);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- bool CLogVariable::CanLog(bool fLock)
- {
- if(!m_bIsCondLog)
- return true;
- bool bRet;
- if(fLock)
- Lock();
- if(m_bCvIsBit)
- bRet = GET_BOOL_VAL(m_pnCvByte, m_nCvMask);
- else
- bRet = *m_pbLogCond;
- if(fLock)
- Unlock();
- return bRet;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::Sample(void)
- {
- if(!m_bIsIntervalLog)
- return;
- if(!CanLog(true))
- return;
- Lock();
- switch(m_vt)
- {
- case VT_bool:
- m_fLastSample = (*m_data.pBool) ? 1.0 : 0.0;
- break;
- case VT_I1:
- m_fLastSample = (double)*m_data.pI1;
- break;
- case VT_UI1:
- m_fLastSample = (double)*m_data.pUI1;
- break;
- case VT_I2:
- m_fLastSample = (double)*m_data.pI2;
- break;
- case VT_UI2:
- m_fLastSample = (double)*m_data.pUI2;
- break;
- case VT_I4:
- m_fLastSample = (double)*m_data.pI4;
- break;
- case VT_UI4:
- m_fLastSample = (double)*m_data.pUI4;
- break;
- case VT_I8:
- m_fLastSample = (double)*m_data.pI8;
- break;
- case VT_UI8:
- m_fLastSample = (double)*m_data.pUI8;
- break;
- case VT_float:
- m_fLastSample = (double)*m_data.pFloat;
- break;
- case VT_double:
- m_fLastSample = *m_data.pDouble;
- break;
- default:
- Unlock();
- ASSERT(false);
- return;
- }
- if(m_fMin > m_fLastSample)
- m_fMin = m_fLastSample;
- if(m_fMax < m_fLastSample)
- m_fMax = m_fLastSample;
- m_fSamples += m_fLastSample;
- m_nSampleCount++;
- Unlock();
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::LogInterval(time_t nTimestamp, CDataLogger &rdl)
- {
- if(!m_bIsIntervalLog)
- {
- m_fSamples = 0;
- m_nSampleCount = 0;
- return;
- }
- if(!CanLog(true))
- {
- m_fSamples = 0;
- m_nSampleCount = 0;
- return;
- }
- if(m_nSampleCount > 0)
- {
- if(!m_bIsDbPersistant)
- {
- if(m_nSampleCount > 1)
- m_fSamples /= (double)m_nSampleCount;
- rdl.Log(m_nTagID, m_fSamples, m_fMin, m_fMax, nTimestamp, m_nIndex, m_lt);
- }
- else
- {
- rdl.Log(m_nTagID, m_fLastSample, m_fMin, m_fMax, nTimestamp, m_nIndex, m_lt);
- }
- }
- m_fSamples = 0;
- m_fMin = std::numeric_limits<double>::infinity();
- m_fMax = -std::numeric_limits<double>::infinity();
- m_nSampleCount = 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::LogValueChanged(time_t nTimestamp, CDataLogger &rdl, bool bStartup, bool bWriteNull)
- {
- if(m_bIsIntervalLog)
- return;
-
- if(bWriteNull) // force write of a NULL value and exit
- {
- rdl.Log(m_nTagID, 0.0, 0.0, 0.0, nTimestamp, m_nIndex, m_lt, true, bStartup);
- return;
- }
- double val;
- bool bCondition, bConditionChanged, bDoLog = false;
- bCondition = CanLog(true);
- bConditionChanged = (m_bOldLogCond != bCondition) || bStartup;
- m_bOldLogCond = bCondition;
- if(!bCondition && !bConditionChanged)
- return;
- Lock();
- switch(m_vt)
- {
- case VT_bool:
- if(bCondition && ((m_cache.boolVal != *m_data.pBool) || bConditionChanged)) // log, if either the value has changed or a condition transition from 0 to 1 has occured
- {
- m_cache.boolVal = *m_data.pBool;
- val = m_cache.boolVal ? 1.0 : 0.0;
- bDoLog = true;
- }
- break;
- case VT_I1:
- if(bCondition && ((m_cache.I1Val != *m_data.pI1) || bConditionChanged))
- {
- m_cache.I1Val = *m_data.pI1;
- val = (double)m_cache.I1Val;
- bDoLog = true;
- }
- break;
- case VT_UI1:
- if(bCondition && ((m_cache.UI1Val != *m_data.pUI1) || bConditionChanged))
- {
- m_cache.UI1Val = *m_data.pUI1;
- val = (double)m_cache.UI1Val;
- bDoLog = true;
- }
- break;
- case VT_I2:
- if(bCondition && ((m_cache.I2Val != *m_data.pI2) || bConditionChanged))
- {
- m_cache.I2Val = *m_data.pI2;
- val = (double)m_cache.I2Val;
- bDoLog = true;
- }
- break;
- case VT_UI2:
- if(bCondition && ((m_cache.UI2Val != *m_data.pUI2) || bConditionChanged))
- {
- m_cache.UI2Val = *m_data.pUI2;
- val = (double)m_cache.UI2Val;
- bDoLog = true;
- }
- break;
- case VT_I4:
- if(bCondition && ((m_cache.I4Val != *m_data.pI4) || bConditionChanged))
- {
- m_cache.I4Val = *m_data.pI4;
- val = (double)m_cache.I4Val;
- bDoLog = true;
- }
- break;
- case VT_UI4:
- if(bCondition && ((m_cache.UI4Val != *m_data.pUI4) || bConditionChanged))
- {
- m_cache.UI4Val = *m_data.pUI4;
- val = (double)m_cache.UI4Val;
- bDoLog = true;
- }
- break;
- case VT_I8:
- if(bCondition && ((m_cache.I8Val != *m_data.pI8) || bConditionChanged))
- {
- m_cache.I8Val = *m_data.pI8;
- val = (double)m_cache.I8Val;
- bDoLog = true;
- }
- break;
- case VT_UI8:
- if(bCondition && ((m_cache.UI8Val != *m_data.pUI8) || bConditionChanged))
- {
- m_cache.UI8Val = *m_data.pUI8;
- val = (double)m_cache.UI8Val;
- bDoLog = true;
- }
- break;
- case VT_float:
- if(bCondition && ((m_cache.FloatVal != *m_data.pFloat) || bConditionChanged))
- {
- m_cache.FloatVal = *m_data.pFloat;
- val = (double)m_cache.FloatVal;
- bDoLog = true;
- }
- break;
- case VT_double:
- if(bCondition && ((m_cache.DoubleVal != *m_data.pDouble) || bConditionChanged))
- {
- m_cache.DoubleVal = *m_data.pDouble;
- val = m_cache.DoubleVal;
- bDoLog = true;
- }
- break;
- default:
- ASSERT(false);
- break;
- }
- Unlock();
- if(bDoLog) // log value, if either the value has changed or a condition transition from 0 to 1 has occured
- {
- rdl.Log(m_nTagID, val, 0.0, 0.0, nTimestamp, m_nIndex, m_lt);
- }
- else if(!bCondition && bConditionChanged) // log a NULL value , if a condition transition from 1 to 0 has occured
- {
- rdl.Log(m_nTagID, 0.0, 0.0, 0.0, nTimestamp, m_nIndex, m_lt, true);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::Lock(void)
- {
- ::GfaIpcLockSHM(m_hShm);
- }
- /////////////////////////////////////////////////////////////////////////////
- void CLogVariable::Unlock(void)
- {
- ::GfaIpcUnlockSHM(m_hShm);
- }
|