shmvar.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. #include "shmvar.h"
  2. #include <QDebug>
  3. CShmVariable::CShmVariable(void *pData, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, QObject *pParent)
  4. : QObject(pParent), m_vt(VT_Invalid), m_data({NULL}), m_varName(pszName)
  5. {
  6. if(!pData || !hShm)
  7. {
  8. Q_ASSERT_X(false, "CShmVariable::CShmVariable", "Invalid parameter!");
  9. return;
  10. }
  11. m_data.pVoid = pData;
  12. m_hShm = hShm;
  13. setObjectName(QStringLiteral("CShmVariable"));
  14. if((m_nIndex = nIndex) >= 0)
  15. {
  16. m_varName += QString("%1%2%3").arg('[').arg(nIndex).arg(']');
  17. }
  18. if(rti == typeid(bool))
  19. {
  20. m_vt = VT_bool;
  21. m_cache.boolVal = *m_data.pBool;
  22. #if _TRACK_TYPES_AT_LOAD
  23. qDebug() << "VT_bool";
  24. #endif // _TRACK_TYPES_AT_LOAD
  25. }
  26. else if(rti == typeid(char))
  27. {
  28. #ifdef __CHAR_UNSIGNED__
  29. m_vt = VT_UI1;
  30. m_cache.UI1Val = *m_data.pUI1;
  31. #if _TRACK_TYPES_AT_LOAD
  32. qDebug() << "VT_UI1";
  33. #endif // _TRACK_TYPES_AT_LOAD
  34. #else
  35. m_vt = VT_I1;
  36. m_cache.I1Val = *m_data.pI1;
  37. #if _TRACK_TYPES_AT_LOAD
  38. qDebug() << "VT_I1";
  39. #endif // _TRACK_TYPES_AT_LOAD
  40. #endif
  41. }
  42. else if(rti == typeid(signed char))
  43. {
  44. m_vt = VT_I1;
  45. m_cache.I1Val = *m_data.pI1;
  46. #if _TRACK_TYPES_AT_LOAD
  47. qDebug() << "VT_I1";
  48. #endif // _TRACK_TYPES_AT_LOAD
  49. }
  50. else if(rti == typeid(unsigned char))
  51. {
  52. m_vt = VT_UI1;
  53. m_cache.UI1Val = *m_data.pUI1;
  54. #if _TRACK_TYPES_AT_LOAD
  55. qDebug() << "VT_UI1";
  56. #endif // _TRACK_TYPES_AT_LOAD
  57. }
  58. else if(rti == typeid(short))
  59. {
  60. m_vt = VT_I2;
  61. m_cache.I2Val = *m_data.pI2;
  62. #if _TRACK_TYPES_AT_LOAD
  63. qDebug() << "VT_I2";
  64. #endif // _TRACK_TYPES_AT_LOAD
  65. }
  66. else if(rti == typeid(unsigned short))
  67. {
  68. m_vt = VT_UI2;
  69. m_cache.UI2Val = *m_data.pUI2;
  70. #if _TRACK_TYPES_AT_LOAD
  71. qDebug() << "VT_UI2";
  72. #endif // _TRACK_TYPES_AT_LOAD
  73. }
  74. else if(rti == typeid(int))
  75. {
  76. m_vt = VT_I4;
  77. m_cache.I4Val = *m_data.pI4;
  78. #if _TRACK_TYPES_AT_LOAD
  79. qDebug() << "VT_I4";
  80. #endif // _TRACK_TYPES_AT_LOAD
  81. }
  82. else if(rti == typeid(unsigned int))
  83. {
  84. m_vt = VT_UI4;
  85. m_cache.UI4Val = *m_data.pUI4;
  86. #if _TRACK_TYPES_AT_LOAD
  87. qDebug() << "VT_UI4";
  88. #endif // _TRACK_TYPES_AT_LOAD
  89. }
  90. else if(rti == typeid(long))
  91. {
  92. if(sizeof(long) == sizeof(long long))
  93. {
  94. m_vt = VT_I8;
  95. m_cache.I8Val = *m_data.pI8;
  96. #if _TRACK_TYPES_AT_LOAD
  97. qDebug() << "VT_I8";
  98. #endif // _TRACK_TYPES_AT_LOAD
  99. }
  100. else
  101. {
  102. m_vt = VT_I4;
  103. m_cache.I4Val = *m_data.pI4;
  104. #if _TRACK_TYPES_AT_LOAD
  105. qDebug() << "VT_I4";
  106. #endif // _TRACK_TYPES_AT_LOAD
  107. }
  108. }
  109. else if(rti == typeid(unsigned long))
  110. {
  111. if(sizeof(unsigned long) == sizeof(unsigned long long))
  112. {
  113. m_vt = VT_UI8;
  114. m_cache.UI8Val = *m_data.pUI8;
  115. #if _TRACK_TYPES_AT_LOAD
  116. qDebug() << "VT_UI8";
  117. #endif // _TRACK_TYPES_AT_LOAD
  118. }
  119. else
  120. {
  121. m_vt = VT_UI4;
  122. m_cache.UI4Val = *m_data.pUI4;
  123. #if _TRACK_TYPES_AT_LOAD
  124. qDebug() << "VT_UI4";
  125. #endif // _TRACK_TYPES_AT_LOAD
  126. }
  127. }
  128. else if(rti == typeid(long long))
  129. {
  130. m_vt = VT_I8;
  131. m_cache.I8Val = *m_data.pI8;
  132. #if _TRACK_TYPES_AT_LOAD
  133. qDebug() << "VT_I8";
  134. #endif // _TRACK_TYPES_AT_LOAD
  135. }
  136. else if(rti == typeid(unsigned long long))
  137. {
  138. m_vt = VT_UI8;
  139. m_cache.UI8Val = *m_data.pUI8;
  140. #if _TRACK_TYPES_AT_LOAD
  141. qDebug() << "VT_UI8";
  142. #endif // _TRACK_TYPES_AT_LOAD
  143. }
  144. else if(rti == typeid(float))
  145. {
  146. m_vt = VT_float;
  147. m_cache.FloatVal = *m_data.pFloat;
  148. #if _TRACK_TYPES_AT_LOAD
  149. qDebug() << "VT_float";
  150. #endif // _TRACK_TYPES_AT_LOAD
  151. }
  152. else if(rti == typeid(double))
  153. {
  154. m_vt = VT_double;
  155. m_cache.DoubleVal = *m_data.pDouble;
  156. #if _TRACK_TYPES_AT_LOAD
  157. qDebug() << "VT_double";
  158. #endif // _TRACK_TYPES_AT_LOAD
  159. }
  160. else
  161. {
  162. Q_ASSERT_X(false, "CShmVariable::CShmVariable", "Unknown data type!");
  163. }
  164. }
  165. CShmVariable::~CShmVariable(void)
  166. {
  167. }
  168. void CShmVariable::valRaw(QVariant &v)
  169. {
  170. switch(m_vt)
  171. {
  172. case VT_bool:
  173. v.setValue(*m_data.pBool);
  174. break;
  175. case VT_I1:
  176. v.setValue((signed int)*m_data.pI1);
  177. break;
  178. case VT_UI1:
  179. v.setValue((unsigned int)*m_data.pUI1);
  180. break;
  181. case VT_I2:
  182. v.setValue((signed int)*m_data.pI2);
  183. break;
  184. case VT_UI2:
  185. v.setValue((unsigned int)*m_data.pUI2);
  186. break;
  187. case VT_I4:
  188. v.setValue(*m_data.pI4);
  189. break;
  190. case VT_UI4:
  191. v.setValue(*m_data.pUI4);
  192. break;
  193. case VT_I8:
  194. v.setValue(*m_data.pI8);
  195. break;
  196. case VT_UI8:
  197. v.setValue(*m_data.pUI8);
  198. break;
  199. case VT_float:
  200. v.setValue(*m_data.pFloat);
  201. break;
  202. case VT_double:
  203. v.setValue(*m_data.pDouble);
  204. break;
  205. default:
  206. break;
  207. }
  208. }
  209. QVariant CShmVariable::val(void)
  210. {
  211. QVariant v;
  212. Lock();
  213. valRaw(v);
  214. Unlock();
  215. return v;
  216. }
  217. void CShmVariable::setVal(const QVariant &val)
  218. {
  219. if(val.isValid() && !val.isNull())
  220. {
  221. #if _TRACK_QT_WRITES
  222. char szDebugOut[256];
  223. #endif // _TRACK_QT_WRITES
  224. Lock();
  225. switch(m_vt)
  226. {
  227. case VT_bool:
  228. if(val.canConvert<bool>())
  229. {
  230. m_cache.boolVal = val.toBool();
  231. if(*m_data.pBool != m_cache.boolVal)
  232. {
  233. *m_data.pBool = m_cache.boolVal;
  234. emitChanged(false);
  235. #if _TRACK_QT_WRITES
  236. sprintf(szDebugOut, "CShmVariable::setVal: bool %s@(%p) - %s", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.boolVal ? "true" : "false");
  237. qDebug() << szDebugOut;
  238. #endif // _TRACK_QT_WRITES
  239. }
  240. }
  241. break;
  242. case VT_I1:
  243. if(val.canConvert<int>())
  244. {
  245. m_cache.I1Val = (signed char)val.toInt();
  246. if(*m_data.pI1 != m_cache.I1Val)
  247. {
  248. *m_data.pI1 = m_cache.I1Val;
  249. emitChanged(false);
  250. #if _TRACK_QT_WRITES
  251. sprintf(szDebugOut, "CShmVariable::setVal: signed char %s@(%p) - %hhd", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I1Val);
  252. qDebug() << szDebugOut;
  253. #endif // _TRACK_QT_WRITES
  254. }
  255. }
  256. break;
  257. case VT_UI1:
  258. if(val.canConvert<int>())
  259. {
  260. m_cache.UI1Val = (unsigned char)val.toInt();
  261. if(*m_data.pUI1 != m_cache.UI1Val)
  262. {
  263. *m_data.pUI1 = m_cache.UI1Val;
  264. emitChanged(false);
  265. #if _TRACK_QT_WRITES
  266. sprintf(szDebugOut, "CShmVariable::setVal: unsigned char %s@(%p) - %hhu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI1Val);
  267. qDebug() << szDebugOut;
  268. #endif // _TRACK_QT_WRITES
  269. }
  270. }
  271. break;
  272. case VT_I2:
  273. if(val.canConvert<int>())
  274. {
  275. m_cache.I2Val = (signed short)val.toInt();
  276. if(*m_data.pI2 != m_cache.I2Val)
  277. {
  278. *m_data.pI2 = m_cache.I2Val;
  279. emitChanged(false);
  280. #if _TRACK_QT_WRITES
  281. sprintf(szDebugOut, "CShmVariable::setVal: signed short %s@(%p) - %hd", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I2Val);
  282. qDebug() << szDebugOut;
  283. #endif // _TRACK_QT_WRITES
  284. }
  285. }
  286. break;
  287. case VT_UI2:
  288. if(val.canConvert<int>())
  289. {
  290. m_cache.UI2Val = (unsigned short)val.toInt();
  291. if(*m_data.pUI2 != m_cache.UI2Val)
  292. {
  293. *m_data.pUI2 = m_cache.UI2Val;
  294. emitChanged(false);
  295. #if _TRACK_QT_WRITES
  296. sprintf(szDebugOut, "CShmVariable::setVal: unsigned short %s@(%p) - %hu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI2Val);
  297. qDebug() << szDebugOut;
  298. #endif // _TRACK_QT_WRITES
  299. }
  300. }
  301. break;
  302. case VT_I4:
  303. if(val.canConvert<int>())
  304. {
  305. m_cache.I4Val = (signed int)val.toInt();
  306. if(*m_data.pI4 != m_cache.I4Val)
  307. {
  308. *m_data.pI4 = m_cache.I4Val;
  309. emitChanged(false);
  310. #if _TRACK_QT_WRITES
  311. sprintf(szDebugOut, "CShmVariable::setVal: signed int %s@(%p) - %d", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I4Val);
  312. qDebug() << szDebugOut;
  313. #endif // _TRACK_QT_WRITES
  314. }
  315. }
  316. break;
  317. case VT_UI4:
  318. if(val.canConvert<int>())
  319. {
  320. m_cache.UI4Val = (unsigned int)val.toInt();
  321. if(*m_data.pUI4 != m_cache.UI4Val)
  322. {
  323. *m_data.pUI4 = m_cache.UI4Val;
  324. emitChanged(false);
  325. #if _TRACK_QT_WRITES
  326. sprintf(szDebugOut, "CShmVariable::setVal: unsigned int %s@(%p) - %u", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI4Val);
  327. qDebug() << szDebugOut;
  328. #endif // _TRACK_QT_WRITES
  329. }
  330. }
  331. break;
  332. case VT_I8:
  333. if(val.canConvert<long long>())
  334. {
  335. m_cache.I8Val = (signed long long)val.toLongLong();
  336. if(*m_data.pI8 != m_cache.I8Val)
  337. {
  338. *m_data.pI8 = m_cache.I8Val;
  339. emitChanged(false);
  340. #if _TRACK_QT_WRITES
  341. sprintf(szDebugOut, "CShmVariable::setVal: signed long long %s@(%p) - %lld", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.I8Val);
  342. qDebug() << szDebugOut;
  343. #endif // _TRACK_QT_WRITES
  344. }
  345. }
  346. break;
  347. case VT_UI8:
  348. if(val.canConvert<long long>())
  349. {
  350. m_cache.UI8Val = (unsigned long long)val.toLongLong();
  351. if(*m_data.pUI8 != m_cache.UI8Val)
  352. {
  353. *m_data.pUI8 = m_cache.UI8Val;
  354. emitChanged(false);
  355. #if _TRACK_QT_WRITES
  356. sprintf(szDebugOut, "CShmVariable::setVal: unsigned long long %s@(%p) - %llu", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.UI8Val);
  357. qDebug() << szDebugOut;
  358. #endif // _TRACK_QT_WRITES
  359. }
  360. }
  361. break;
  362. case VT_float:
  363. if(val.canConvert<float>())
  364. {
  365. m_cache.FloatVal = (float)val.toFloat();
  366. if(*m_data.pFloat != m_cache.FloatVal)
  367. {
  368. *m_data.pFloat = m_cache.FloatVal;
  369. emitChanged(false);
  370. #if _TRACK_QT_WRITES
  371. sprintf(szDebugOut, "CShmVariable::setVal: float %s@(%p) - %f", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.FloatVal);
  372. qDebug() << szDebugOut;
  373. #endif // _TRACK_QT_WRITES
  374. }
  375. }
  376. break;
  377. case VT_double:
  378. if(val.canConvert<double>())
  379. {
  380. m_cache.DoubleVal = (double)val.toDouble();
  381. if(*m_data.pDouble != m_cache.DoubleVal)
  382. {
  383. *m_data.pDouble = m_cache.DoubleVal;
  384. emitChanged(false);
  385. #if _TRACK_QT_WRITES
  386. sprintf(szDebugOut, "CShmVariable::setVal: double %s@(%p) - %f", m_varName.toStdString().c_str(), m_data.pVoid, m_cache.DoubleVal);
  387. qDebug() << szDebugOut;
  388. #endif // _TRACK_QT_WRITES
  389. }
  390. }
  391. break;
  392. default:
  393. qDebug() << "CShmVariable::setVal: invalid vartype!";
  394. break;
  395. }
  396. Unlock();
  397. }
  398. }
  399. unsigned int CShmVariable::vt(void) const
  400. {
  401. return m_vt;
  402. }
  403. unsigned long long CShmVariable::CheckUpdateShm(bool fLock)
  404. {
  405. CHECK_UPDATE_SHM_RETVAL rv = {1, 0};
  406. if(fLock)
  407. Lock();
  408. switch(m_vt)
  409. {
  410. case VT_bool:
  411. if(m_cache.boolVal != *m_data.pBool)
  412. {
  413. m_cache.boolVal = *m_data.pBool;
  414. emitChanged(false);
  415. rv.nUpdated = 1;
  416. }
  417. break;
  418. case VT_I1:
  419. if(m_cache.I1Val != *m_data.pI1)
  420. {
  421. m_cache.I1Val = *m_data.pI1;
  422. emitChanged(false);
  423. rv.nUpdated = 1;
  424. }
  425. break;
  426. case VT_UI1:
  427. if(m_cache.UI1Val != *m_data.pUI1)
  428. {
  429. m_cache.UI1Val = *m_data.pUI1;
  430. emitChanged(false);
  431. rv.nUpdated = 1;
  432. }
  433. break;
  434. case VT_I2:
  435. if(m_cache.I2Val != *m_data.pI2)
  436. {
  437. m_cache.I2Val = *m_data.pI2;
  438. emitChanged(false);
  439. rv.nUpdated = 1;
  440. }
  441. break;
  442. case VT_UI2:
  443. if(m_cache.UI2Val != *m_data.pUI2)
  444. {
  445. m_cache.UI2Val = *m_data.pUI2;
  446. emitChanged(false);
  447. rv.nUpdated = 1;
  448. }
  449. break;
  450. case VT_I4:
  451. if(m_cache.I4Val != *m_data.pI4)
  452. {
  453. m_cache.I4Val = *m_data.pI4;
  454. emitChanged(false);
  455. rv.nUpdated = 1;
  456. }
  457. break;
  458. case VT_UI4:
  459. if(m_cache.UI4Val != *m_data.pUI4)
  460. {
  461. m_cache.UI4Val = *m_data.pUI4;
  462. emitChanged(false);
  463. rv.nUpdated = 1;
  464. }
  465. break;
  466. case VT_I8:
  467. if(m_cache.I8Val != *m_data.pI8)
  468. {
  469. m_cache.I8Val = *m_data.pI8;
  470. emitChanged(false);
  471. rv.nUpdated = 1;
  472. }
  473. break;
  474. case VT_UI8:
  475. if(m_cache.UI8Val != *m_data.pUI8)
  476. {
  477. m_cache.UI8Val = *m_data.pUI8;
  478. emitChanged(false);
  479. rv.nUpdated = 1;
  480. }
  481. break;
  482. case VT_float:
  483. if(m_cache.FloatVal != *m_data.pFloat)
  484. {
  485. m_cache.FloatVal = *m_data.pFloat;
  486. emitChanged(false);
  487. rv.nUpdated = 1;
  488. }
  489. break;
  490. case VT_double:
  491. if(m_cache.DoubleVal != *m_data.pDouble)
  492. {
  493. m_cache.DoubleVal = *m_data.pDouble;
  494. emitChanged(false);
  495. rv.nUpdated = 1;
  496. }
  497. break;
  498. default:
  499. break;
  500. }
  501. if(fLock)
  502. Unlock();
  503. return rv.nRetval;
  504. }
  505. void CShmVariable::Lock(void)
  506. {
  507. ::GfaIpcLockSHM(m_hShm);
  508. // qDebug() << "CShmVariable::Lock";
  509. }
  510. void CShmVariable::Unlock(void)
  511. {
  512. // qDebug() << "CShmVariable::Unlock";
  513. ::GfaIpcUnlockSHM(m_hShm);
  514. }
  515. void CShmVariable::emitChanged(bool fLock)
  516. {
  517. // qDebug() << "val changed!";
  518. if(fLock)
  519. emit valChanged(val());
  520. else
  521. {
  522. QVariant v;
  523. valRaw(v);
  524. emit valChanged(v);
  525. }
  526. }