ReAntTweakBar.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. #include "ReAntTweakBar.h"
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <sstream>
  5. #include <iomanip>
  6. #include <map>
  7. #define MAX_CB_VAR_SIZE 10
  8. // Max line size for reading files
  9. #define MAX_LINE 1000
  10. #define MAX_WORD 100
  11. // GLOBAL WRAPPERS
  12. namespace igl
  13. {
  14. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > > ReTw_custom_types;
  15. }
  16. TwType igl::ReTwDefineEnum(
  17. const char *name,
  18. const TwEnumVal *enumValues,
  19. unsigned int nbValues)
  20. {
  21. // copy enum valus into vector
  22. std::vector<TwEnumVal> enum_vals;
  23. enum_vals.resize(nbValues);
  24. for(unsigned int j = 0; j<nbValues;j++)
  25. {
  26. enum_vals[j] = enumValues[j];
  27. }
  28. TwType type = TwDefineEnum(name,enumValues,nbValues);
  29. ReTw_custom_types[type] =
  30. std::pair<const char *,std::vector<TwEnumVal> >(name,enum_vals);
  31. return type;
  32. }
  33. namespace igl
  34. {
  35. struct ReTwTypeString
  36. {
  37. TwType type;
  38. const char * type_str;
  39. };
  40. #define RETW_NUM_DEFAULT_TYPE_STRINGS 23
  41. ReTwTypeString ReTwDefaultTypeStrings[RETW_NUM_DEFAULT_TYPE_STRINGS] =
  42. {
  43. {TW_TYPE_UNDEF,"TW_TYPE_UNDEF"},
  44. {TW_TYPE_BOOLCPP,"TW_TYPE_BOOLCPP"},
  45. {TW_TYPE_BOOL8,"TW_TYPE_BOOL8"},
  46. {TW_TYPE_BOOL16,"TW_TYPE_BOOL16"},
  47. {TW_TYPE_BOOL32,"TW_TYPE_BOOL32"},
  48. {TW_TYPE_CHAR,"TW_TYPE_CHAR"},
  49. {TW_TYPE_INT8,"TW_TYPE_INT8"},
  50. {TW_TYPE_UINT8,"TW_TYPE_UINT8"},
  51. {TW_TYPE_INT16,"TW_TYPE_INT16"},
  52. {TW_TYPE_UINT16,"TW_TYPE_UINT16"},
  53. {TW_TYPE_INT32,"TW_TYPE_INT32"},
  54. {TW_TYPE_UINT32,"TW_TYPE_UINT32"},
  55. {TW_TYPE_FLOAT,"TW_TYPE_FLOAT"},
  56. {TW_TYPE_DOUBLE,"TW_TYPE_DOUBLE"},
  57. {TW_TYPE_COLOR32,"TW_TYPE_COLOR32"},
  58. {TW_TYPE_COLOR3F,"TW_TYPE_COLOR3F"},
  59. {TW_TYPE_COLOR4F,"TW_TYPE_COLOR4F"},
  60. {TW_TYPE_CDSTRING,"TW_TYPE_CDSTRING"},
  61. {TW_TYPE_STDSTRING,"TW_TYPE_STDSTRING"},
  62. {TW_TYPE_QUAT4F,"TW_TYPE_QUAT4F"},
  63. {TW_TYPE_QUAT4D,"TW_TYPE_QUAT4D"},
  64. {TW_TYPE_DIR3F,"TW_TYPE_DIR3F"},
  65. {TW_TYPE_DIR3D,"TW_TYPE_DIR3D"}
  66. };
  67. }
  68. igl::ReTwBar::ReTwBar():
  69. bar(NULL),rw_items(),cb_items()
  70. {
  71. }
  72. igl::ReTwBar::ReTwBar(const igl::ReTwBar & that):
  73. bar(that.bar),
  74. rw_items(that.rw_items),
  75. cb_items(that.cb_items)
  76. {
  77. }
  78. igl::ReTwBar & igl::ReTwBar::operator=(const igl::ReTwBar & that)
  79. {
  80. // check for self assignment
  81. if(this != &that)
  82. {
  83. bar = that.bar;
  84. rw_items = that.rw_items;
  85. cb_items = that.cb_items;
  86. }
  87. return *this;
  88. }
  89. // BAR WRAPPERS
  90. void igl::ReTwBar::TwNewBar(const char *barName)
  91. {
  92. // double colon without anything in front of it means look for this in the
  93. // global namespace... I hope...
  94. this->bar = ::TwNewBar(barName);
  95. }
  96. int igl::ReTwBar::TwAddVarRW(
  97. const char *name,
  98. TwType type,
  99. void *var,
  100. const char *def,
  101. const bool record)
  102. {
  103. int ret = ::TwAddVarRW(this->bar,name,type,var,def);
  104. if(ret && record)
  105. {
  106. rw_items.push_back(ReTwRWItem(name,type,var));
  107. }
  108. return ret;
  109. }
  110. int igl::ReTwBar::TwAddVarCB(
  111. const char *name,
  112. TwType type,
  113. TwSetVarCallback setCallback,
  114. TwGetVarCallback getCallback,
  115. void *clientData,
  116. const char *def,
  117. const bool record)
  118. {
  119. int ret =
  120. ::TwAddVarCB(this->bar,name,type,setCallback,getCallback,clientData,def);
  121. if(ret && record)
  122. {
  123. cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
  124. }
  125. return ret;
  126. }
  127. int igl::ReTwBar::TwAddVarRO(
  128. const char *name,
  129. TwType type,
  130. void *var,
  131. const char *def)
  132. {
  133. int ret = ::TwAddVarRO(this->bar,name,type,var,def);
  134. // Read only variables are not recorded
  135. //if(ret)
  136. //{
  137. // rw_items.push_back(ReTwRWItem(name,type,var));
  138. //}
  139. return ret;
  140. }
  141. int igl::ReTwBar::TwAddButton(
  142. const char *name,
  143. TwButtonCallback buttonCallback,
  144. void *clientData,
  145. const char *def)
  146. {
  147. int ret =
  148. ::TwAddButton(this->bar,name,buttonCallback,clientData,def);
  149. // buttons are not recorded
  150. //if(ret)
  151. //{
  152. // cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
  153. //}
  154. return ret;
  155. }
  156. int igl::ReTwBar::TwSetParam(
  157. const char *varName,
  158. const char *paramName,
  159. TwParamValueType paramValueType,
  160. unsigned int inValueCount,
  161. const void *inValues)
  162. {
  163. // For now just pass these along
  164. return
  165. ::TwSetParam(
  166. this->bar,
  167. varName,
  168. paramName,
  169. paramValueType,
  170. inValueCount,
  171. inValues);
  172. }
  173. int igl::ReTwBar::TwGetParam(
  174. const char *varName,
  175. const char *paramName,
  176. TwParamValueType paramValueType,
  177. unsigned int outValueMaxCount,
  178. void *outValues)
  179. {
  180. return
  181. ::TwGetParam(
  182. this->bar,
  183. varName,
  184. paramName,
  185. paramValueType,
  186. outValueMaxCount,
  187. outValues);
  188. }
  189. int igl::ReTwBar::TwRefreshBar()
  190. {
  191. return ::TwRefreshBar(this->bar);
  192. }
  193. int igl::ReTwBar::TwTerminate()
  194. {
  195. return ::TwTerminate();
  196. }
  197. bool igl::ReTwBar::save(const char *file_name)
  198. {
  199. FILE * fp;
  200. if(file_name == NULL)
  201. {
  202. fp = stdout;
  203. }else
  204. {
  205. fp = fopen(file_name,"w");
  206. }
  207. if(fp == NULL)
  208. {
  209. printf("ERROR: not able to open %s for writing...\n",file_name);
  210. return false;
  211. }
  212. // Print all RW variables
  213. for(
  214. std::vector<ReTwRWItem>::iterator it = rw_items.begin();
  215. it != rw_items.end();
  216. it++)
  217. {
  218. std::string s = (*it).name;
  219. const char * name = s.c_str();
  220. TwType type = (*it).type;
  221. void * var = (*it).var;
  222. fprintf(fp,"%s: %s\n",
  223. name,
  224. get_value_as_string(var,type).c_str());
  225. }
  226. char var[MAX_CB_VAR_SIZE];
  227. // Print all CB variables
  228. for(
  229. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  230. it != cb_items.end();
  231. it++)
  232. {
  233. const char * name = it->name.c_str();
  234. TwType type = it->type;
  235. //TwSetVarCallback setCallback = it->setCallback;
  236. TwGetVarCallback getCallback = it->getCallback;
  237. void * clientData = it->clientData;
  238. // I'm not sure how to do what I want to do. getCallback needs to be sure
  239. // that it can write to var. So var needs to point to a valid and big
  240. // enough chunk of memory
  241. getCallback(var,clientData);
  242. fprintf(fp,"%s: %s\n",
  243. name,
  244. get_value_as_string(var,type).c_str());
  245. }
  246. fprintf(fp,"\n");
  247. if(file_name != NULL)
  248. {
  249. fclose(fp);
  250. }
  251. // everything succeeded
  252. return true;
  253. }
  254. std::string igl::ReTwBar::get_value_as_string(
  255. void * var,
  256. TwType type)
  257. {
  258. std::stringstream sstr;
  259. switch(type)
  260. {
  261. case TW_TYPE_BOOLCPP:
  262. {
  263. sstr << "TW_TYPE_BOOLCPP" << " ";
  264. sstr << *(static_cast<bool*>(var));
  265. break;
  266. }
  267. case TW_TYPE_QUAT4D:
  268. {
  269. sstr << "TW_TYPE_QUAT4D" << " ";
  270. // Q: Why does casting to double* work? shouldn't I have to cast to
  271. // double**?
  272. double * q = static_cast<double*>(var);
  273. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  274. break;
  275. }
  276. case TW_TYPE_QUAT4F:
  277. {
  278. sstr << "TW_TYPE_QUAT4F" << " ";
  279. // Q: Why does casting to float* work? shouldn't I have to cast to
  280. // float**?
  281. float * q = static_cast<float*>(var);
  282. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  283. break;
  284. }
  285. case TW_TYPE_COLOR4F:
  286. {
  287. sstr << "TW_TYPE_COLOR4F" << " ";
  288. float * c = static_cast<float*>(var);
  289. sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
  290. break;
  291. }
  292. case TW_TYPE_COLOR3F:
  293. {
  294. sstr << "TW_TYPE_COLOR3F" << " ";
  295. float * c = static_cast<float*>(var);
  296. sstr << c[0] << " " << c[1] << " " << c[2];
  297. break;
  298. }
  299. case TW_TYPE_DIR3D:
  300. {
  301. sstr << "TW_TYPE_DIR3D" << " ";
  302. double * d = static_cast<double*>(var);
  303. sstr << d[0] << " " << d[1] << " " << d[2];
  304. break;
  305. }
  306. case TW_TYPE_DIR3F:
  307. {
  308. sstr << "TW_TYPE_DIR3F" << " ";
  309. float * d = static_cast<float*>(var);
  310. sstr << d[0] << " " << d[1] << " " << d[2];
  311. break;
  312. }
  313. case TW_TYPE_BOOL32:
  314. {
  315. sstr << "TW_TYPE_BOOL32" << " ";
  316. sstr << *(static_cast<int*>(var));
  317. break;
  318. }
  319. case TW_TYPE_INT32:
  320. {
  321. sstr << "TW_TYPE_INT32" << " ";
  322. sstr << *(static_cast<int*>(var));
  323. break;
  324. }
  325. case TW_TYPE_FLOAT:
  326. {
  327. sstr << "TW_TYPE_FLOAT" << " ";
  328. sstr << *(static_cast<float*>(var));
  329. break;
  330. }
  331. case TW_TYPE_DOUBLE:
  332. {
  333. sstr << "TW_TYPE_DOUBLE" << " ";
  334. sstr << std::setprecision(15) << *(static_cast<double*>(var));
  335. break;
  336. }
  337. default:
  338. {
  339. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  340. ReTw_custom_types.find(type);
  341. if(iter != ReTw_custom_types.end())
  342. {
  343. sstr << (*iter).second.first << " ";
  344. int enum_val = *(static_cast<int*>(var));
  345. // try find display name for enum value
  346. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  347. bool found = false;
  348. for(;eit<(*iter).second.second.end();eit++)
  349. {
  350. if(enum_val == eit->Value)
  351. {
  352. sstr << eit->Label;
  353. found = true;
  354. break;
  355. }
  356. }
  357. if(!found)
  358. {
  359. sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
  360. }
  361. }else
  362. {
  363. sstr << "ERROR_TYPE_NOT_SUPPORTED";
  364. }
  365. break;
  366. }
  367. }
  368. return sstr.str();
  369. }
  370. bool igl::ReTwBar::load(const char *file_name)
  371. {
  372. FILE * fp;
  373. fp = fopen(file_name,"r");
  374. if(fp == NULL)
  375. {
  376. printf("ERROR: not able to open %s for reading...\n",file_name);
  377. return false;
  378. }
  379. // go through file line by line
  380. char line[MAX_LINE];
  381. bool still_comments;
  382. char name[MAX_WORD];
  383. char type_str[MAX_WORD];
  384. char value_str[MAX_WORD];
  385. // line number
  386. int j = 0;
  387. bool finished = false;
  388. while(true)
  389. {
  390. // Eat comments
  391. still_comments = true;
  392. while(still_comments)
  393. {
  394. if(fgets(line,MAX_LINE,fp) == NULL)
  395. {
  396. finished = true;
  397. break;
  398. }
  399. // Blank lines and lines that begin with # are comments
  400. still_comments = (line[0] == '#' || line[0] == '\n');
  401. j++;
  402. }
  403. if(finished)
  404. {
  405. break;
  406. }
  407. sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
  408. //printf("%s: %s %s\n",name, type_str,value_str);
  409. TwType type;
  410. if(!type_from_string(type_str,type))
  411. {
  412. printf("ERROR: %s type not found... Skipping...\n",type_str);
  413. continue;
  414. }
  415. set_value_from_string(name,type,value_str);
  416. }
  417. fclose(fp);
  418. // everything succeeded
  419. return true;
  420. }
  421. bool igl::ReTwBar::type_from_string(const char *type_str, TwType & type)
  422. {
  423. // first check default types
  424. for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
  425. {
  426. if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
  427. {
  428. type = ReTwDefaultTypeStrings[j].type;
  429. return true;
  430. break;
  431. }
  432. }
  433. // then check custom types
  434. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  435. ReTw_custom_types.begin();
  436. for(;iter != ReTw_custom_types.end(); iter++)
  437. {
  438. if(strcmp((*iter).second.first,type_str)==0)
  439. {
  440. type = (*iter).first;
  441. return true;
  442. }
  443. }
  444. return false;
  445. }
  446. bool igl::ReTwBar::set_value_from_string(
  447. const char * name,
  448. TwType type,
  449. const char * value_str)
  450. {
  451. void * value = NULL;
  452. // possible value slots
  453. int i;
  454. float v;
  455. double dv;
  456. float f[4];
  457. double d[4];
  458. bool b;
  459. // First try to get value from default types
  460. switch(type)
  461. {
  462. case TW_TYPE_BOOLCPP:
  463. {
  464. int ib;
  465. if(sscanf(value_str," %d",&ib) == 1)
  466. {
  467. b = ib!=0;
  468. value = &b;
  469. }else
  470. {
  471. printf("ERROR: Bad value format...\n");
  472. return false;
  473. }
  474. break;
  475. }
  476. case TW_TYPE_QUAT4D:
  477. //case TW_TYPE_COLOR4D:
  478. {
  479. if(sscanf(value_str," %lf %lf %lf %lf",&d[0],&d[1],&d[2],&d[3]) == 4)
  480. {
  481. value = &d;
  482. }else
  483. {
  484. printf("ERROR: Bad value format...\n");
  485. return false;
  486. }
  487. break;
  488. }
  489. case TW_TYPE_QUAT4F:
  490. case TW_TYPE_COLOR4F:
  491. {
  492. if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
  493. {
  494. value = &f;
  495. }else
  496. {
  497. printf("ERROR: Bad value format...\n");
  498. return false;
  499. }
  500. break;
  501. }
  502. //case TW_TYPE_COLOR3D:
  503. case TW_TYPE_DIR3D:
  504. {
  505. if(sscanf(value_str," %lf %lf %lf",&d[0],&d[1],&d[2]) == 3)
  506. {
  507. value = &d;
  508. }else
  509. {
  510. printf("ERROR: Bad value format...\n");
  511. return false;
  512. }
  513. break;
  514. }
  515. case TW_TYPE_COLOR3F:
  516. case TW_TYPE_DIR3F:
  517. {
  518. if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
  519. {
  520. value = &f;
  521. }else
  522. {
  523. printf("ERROR: Bad value format...\n");
  524. return false;
  525. }
  526. break;
  527. }
  528. case TW_TYPE_BOOL32:
  529. case TW_TYPE_INT32:
  530. {
  531. if(sscanf(value_str," %d",&i) == 1)
  532. {
  533. value = &i;
  534. }else
  535. {
  536. printf("ERROR: Bad value format...\n");
  537. return false;
  538. }
  539. break;
  540. }
  541. case TW_TYPE_FLOAT:
  542. {
  543. if(sscanf(value_str," %f",&v) == 1)
  544. {
  545. value = &v;
  546. }else
  547. {
  548. printf("ERROR: Bad value format...\n");
  549. return false;
  550. }
  551. break;
  552. }
  553. case TW_TYPE_DOUBLE:
  554. {
  555. if(sscanf(value_str," %lf",&dv) == 1)
  556. {
  557. value = &dv;
  558. }else
  559. {
  560. printf("ERROR: Bad value format...\n");
  561. return false;
  562. }
  563. break;
  564. }
  565. default:
  566. // Try to find type in custom enum types
  567. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  568. ReTw_custom_types.find(type);
  569. if(iter != ReTw_custom_types.end())
  570. {
  571. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  572. bool found = false;
  573. for(;eit<(*iter).second.second.end();eit++)
  574. {
  575. if(strcmp(value_str,eit->Label) == 0)
  576. {
  577. i = eit->Value;
  578. value = &i;
  579. found = true;
  580. break;
  581. }
  582. }
  583. if(!found)
  584. {
  585. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  586. }
  587. }else
  588. {
  589. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  590. }
  591. break;
  592. }
  593. // Find variable based on name
  594. // First look in RW items
  595. bool item_found = false;
  596. for(
  597. std::vector<ReTwRWItem>::iterator it = rw_items.begin();
  598. it != rw_items.end();
  599. it++)
  600. {
  601. if(it->name == name)
  602. {
  603. void * var = it->var;
  604. switch(type)
  605. {
  606. case TW_TYPE_BOOLCPP:
  607. {
  608. bool * bvar = static_cast<bool*>(var);
  609. bool * bvalue = static_cast<bool*>(value);
  610. *bvar = *bvalue;
  611. break;
  612. }
  613. case TW_TYPE_QUAT4D:
  614. //case TW_TYPE_COLOR4D:
  615. {
  616. double * dvar = static_cast<double*>(var);
  617. double * dvalue = static_cast<double*>(value);
  618. dvar[0] = dvalue[0];
  619. dvar[1] = dvalue[1];
  620. dvar[2] = dvalue[2];
  621. dvar[3] = dvalue[3];
  622. break;
  623. }
  624. case TW_TYPE_QUAT4F:
  625. case TW_TYPE_COLOR4F:
  626. {
  627. float * fvar = static_cast<float*>(var);
  628. float * fvalue = static_cast<float*>(value);
  629. fvar[0] = fvalue[0];
  630. fvar[1] = fvalue[1];
  631. fvar[2] = fvalue[2];
  632. fvar[3] = fvalue[3];
  633. break;
  634. }
  635. //case TW_TYPE_COLOR3D:
  636. case TW_TYPE_DIR3D:
  637. {
  638. double * dvar = static_cast<double*>(var);
  639. double * dvalue = static_cast<double*>(value);
  640. dvar[0] = dvalue[0];
  641. dvar[1] = dvalue[1];
  642. dvar[2] = dvalue[2];
  643. break;
  644. }
  645. case TW_TYPE_COLOR3F:
  646. case TW_TYPE_DIR3F:
  647. {
  648. float * fvar = static_cast<float*>(var);
  649. float * fvalue = static_cast<float*>(value);
  650. fvar[0] = fvalue[0];
  651. fvar[1] = fvalue[1];
  652. fvar[2] = fvalue[2];
  653. break;
  654. }
  655. case TW_TYPE_BOOL32:
  656. case TW_TYPE_INT32:
  657. {
  658. int * ivar = static_cast<int*>(var);
  659. int * ivalue = static_cast<int*>(value);
  660. *ivar = *ivalue;
  661. break;
  662. }
  663. case TW_TYPE_FLOAT:
  664. {
  665. float * fvar = static_cast<float*>(var);
  666. float * fvalue = static_cast<float*>(value);
  667. *fvar = *fvalue;
  668. break;
  669. }
  670. case TW_TYPE_DOUBLE:
  671. {
  672. double * dvar = static_cast<double*>(var);
  673. double * fvalue = static_cast<double*>(value);
  674. *dvar = *fvalue;
  675. break;
  676. }
  677. default:
  678. // Try to find type in custom enum types
  679. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  680. ReTw_custom_types.find(type);
  681. if(iter != ReTw_custom_types.end())
  682. {
  683. int * ivar = static_cast<int*>(var);
  684. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  685. bool found = false;
  686. for(;eit<(*iter).second.second.end();eit++)
  687. {
  688. if(strcmp(value_str,eit->Label) == 0)
  689. {
  690. *ivar = eit->Value;
  691. found = true;
  692. break;
  693. }
  694. }
  695. if(!found)
  696. {
  697. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  698. }
  699. }else
  700. {
  701. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  702. }
  703. break;
  704. }
  705. item_found = true;
  706. break;
  707. }
  708. }
  709. // Try looking in CB items
  710. if(!item_found)
  711. {
  712. for(
  713. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  714. it != cb_items.end();
  715. it++)
  716. {
  717. if(it->name==name)
  718. {
  719. it->setCallback(value,it->clientData);
  720. item_found = true;
  721. break;
  722. }
  723. }
  724. }
  725. if(!item_found)
  726. {
  727. printf("ERROR: item not found\n");
  728. }
  729. return true;
  730. }