ReAntTweakBar.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  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. const char * name = (*it).name.c_str();
  219. TwType type = (*it).type;
  220. void * var = (*it).var;
  221. fprintf(fp,"%s: %s\n",
  222. name,
  223. get_value_as_string(var,type).c_str());
  224. }
  225. char var[MAX_CB_VAR_SIZE];
  226. // Print all CB variables
  227. for(
  228. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  229. it != cb_items.end();
  230. it++)
  231. {
  232. const char * name = it->name.c_str();
  233. TwType type = it->type;
  234. //TwSetVarCallback setCallback = it->setCallback;
  235. TwGetVarCallback getCallback = it->getCallback;
  236. void * clientData = it->clientData;
  237. // I'm not sure how to do what I want to do. getCallback needs to be sure
  238. // that it can write to var. So var needs to point to a valid and big
  239. // enough chunk of memory
  240. getCallback(var,clientData);
  241. fprintf(fp,"%s: %s\n",
  242. name,
  243. get_value_as_string(var,type).c_str());
  244. }
  245. fprintf(fp,"\n");
  246. if(file_name != NULL)
  247. {
  248. fclose(fp);
  249. }
  250. // everything succeeded
  251. return true;
  252. }
  253. std::string igl::ReTwBar::get_value_as_string(
  254. void * var,
  255. TwType type)
  256. {
  257. std::stringstream sstr;
  258. switch(type)
  259. {
  260. case TW_TYPE_BOOLCPP:
  261. {
  262. sstr << "TW_TYPE_BOOLCPP" << " ";
  263. sstr << *(static_cast<bool*>(var));
  264. break;
  265. }
  266. case TW_TYPE_QUAT4D:
  267. {
  268. sstr << "TW_TYPE_QUAT4D" << " ";
  269. // Q: Why does casting to double* work? shouldn't I have to cast to
  270. // double**?
  271. double * q = static_cast<double*>(var);
  272. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  273. break;
  274. }
  275. case TW_TYPE_QUAT4F:
  276. {
  277. sstr << "TW_TYPE_QUAT4F" << " ";
  278. // Q: Why does casting to float* work? shouldn't I have to cast to
  279. // float**?
  280. float * q = static_cast<float*>(var);
  281. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  282. break;
  283. }
  284. case TW_TYPE_COLOR4F:
  285. {
  286. sstr << "TW_TYPE_COLOR4F" << " ";
  287. float * c = static_cast<float*>(var);
  288. sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
  289. break;
  290. }
  291. case TW_TYPE_COLOR3F:
  292. {
  293. sstr << "TW_TYPE_COLOR3F" << " ";
  294. float * c = static_cast<float*>(var);
  295. sstr << c[0] << " " << c[1] << " " << c[2];
  296. break;
  297. }
  298. case TW_TYPE_DIR3D:
  299. {
  300. sstr << "TW_TYPE_DIR3D" << " ";
  301. double * d = static_cast<double*>(var);
  302. sstr << d[0] << " " << d[1] << " " << d[2];
  303. break;
  304. }
  305. case TW_TYPE_DIR3F:
  306. {
  307. sstr << "TW_TYPE_DIR3F" << " ";
  308. float * d = static_cast<float*>(var);
  309. sstr << d[0] << " " << d[1] << " " << d[2];
  310. break;
  311. }
  312. case TW_TYPE_BOOL32:
  313. {
  314. sstr << "TW_TYPE_BOOL32" << " ";
  315. sstr << *(static_cast<int*>(var));
  316. break;
  317. }
  318. case TW_TYPE_INT32:
  319. {
  320. sstr << "TW_TYPE_INT32" << " ";
  321. sstr << *(static_cast<int*>(var));
  322. break;
  323. }
  324. case TW_TYPE_FLOAT:
  325. {
  326. sstr << "TW_TYPE_FLOAT" << " ";
  327. sstr << *(static_cast<float*>(var));
  328. break;
  329. }
  330. case TW_TYPE_DOUBLE:
  331. {
  332. sstr << "TW_TYPE_DOUBLE" << " ";
  333. sstr << std::setprecision(15) << *(static_cast<double*>(var));
  334. break;
  335. }
  336. default:
  337. {
  338. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  339. ReTw_custom_types.find(type);
  340. if(iter != ReTw_custom_types.end())
  341. {
  342. sstr << (*iter).second.first << " ";
  343. int enum_val = *(static_cast<int*>(var));
  344. // try find display name for enum value
  345. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  346. bool found = false;
  347. for(;eit<(*iter).second.second.end();eit++)
  348. {
  349. if(enum_val == eit->Value)
  350. {
  351. sstr << eit->Label;
  352. found = true;
  353. break;
  354. }
  355. }
  356. if(!found)
  357. {
  358. sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
  359. }
  360. }else
  361. {
  362. sstr << "ERROR_TYPE_NOT_SUPPORTED";
  363. }
  364. break;
  365. }
  366. }
  367. return sstr.str();
  368. }
  369. bool igl::ReTwBar::load(const char *file_name)
  370. {
  371. FILE * fp;
  372. fp = fopen(file_name,"r");
  373. if(fp == NULL)
  374. {
  375. printf("ERROR: not able to open %s for reading...\n",file_name);
  376. return false;
  377. }
  378. // go through file line by line
  379. char line[MAX_LINE];
  380. bool still_comments;
  381. char name[MAX_WORD];
  382. char type_str[MAX_WORD];
  383. char value_str[MAX_WORD];
  384. // line number
  385. int j = 0;
  386. bool finished = false;
  387. while(true)
  388. {
  389. // Eat comments
  390. still_comments = true;
  391. while(still_comments)
  392. {
  393. if(fgets(line,MAX_LINE,fp) == NULL)
  394. {
  395. finished = true;
  396. break;
  397. }
  398. // Blank lines and lines that begin with # are comments
  399. still_comments = (line[0] == '#' || line[0] == '\n');
  400. j++;
  401. }
  402. if(finished)
  403. {
  404. break;
  405. }
  406. sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
  407. //printf("%s: %s %s\n",name, type_str,value_str);
  408. TwType type;
  409. if(!type_from_string(type_str,type))
  410. {
  411. printf("ERROR: %s type not found... Skipping...\n",type_str);
  412. continue;
  413. }
  414. set_value_from_string(name,type,value_str);
  415. }
  416. fclose(fp);
  417. // everything succeeded
  418. return true;
  419. }
  420. bool igl::ReTwBar::type_from_string(const char *type_str, TwType & type)
  421. {
  422. // first check default types
  423. for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
  424. {
  425. if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
  426. {
  427. type = ReTwDefaultTypeStrings[j].type;
  428. return true;
  429. break;
  430. }
  431. }
  432. // then check custom types
  433. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  434. ReTw_custom_types.begin();
  435. for(;iter != ReTw_custom_types.end(); iter++)
  436. {
  437. if(strcmp((*iter).second.first,type_str)==0)
  438. {
  439. type = (*iter).first;
  440. return true;
  441. }
  442. }
  443. return false;
  444. }
  445. bool igl::ReTwBar::set_value_from_string(
  446. const char * name,
  447. TwType type,
  448. const char * value_str)
  449. {
  450. void * value = NULL;
  451. // possible value slots
  452. int i;
  453. float v;
  454. double dv;
  455. float f[4];
  456. double d[4];
  457. bool b;
  458. // First try to get value from default types
  459. switch(type)
  460. {
  461. case TW_TYPE_BOOLCPP:
  462. {
  463. int ib;
  464. if(sscanf(value_str," %d",&ib) == 1)
  465. {
  466. b = ib!=0;
  467. value = &b;
  468. }else
  469. {
  470. printf("ERROR: Bad value format...\n");
  471. return false;
  472. }
  473. break;
  474. }
  475. case TW_TYPE_QUAT4D:
  476. //case TW_TYPE_COLOR4D:
  477. {
  478. if(sscanf(value_str," %lf %lf %lf %lf",&d[0],&d[1],&d[2],&d[3]) == 4)
  479. {
  480. value = &d;
  481. }else
  482. {
  483. printf("ERROR: Bad value format...\n");
  484. return false;
  485. }
  486. break;
  487. }
  488. case TW_TYPE_QUAT4F:
  489. case TW_TYPE_COLOR4F:
  490. {
  491. if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
  492. {
  493. value = &f;
  494. }else
  495. {
  496. printf("ERROR: Bad value format...\n");
  497. return false;
  498. }
  499. break;
  500. }
  501. //case TW_TYPE_COLOR3D:
  502. case TW_TYPE_DIR3D:
  503. {
  504. if(sscanf(value_str," %lf %lf %lf",&d[0],&d[1],&d[2]) == 3)
  505. {
  506. value = &d;
  507. }else
  508. {
  509. printf("ERROR: Bad value format...\n");
  510. return false;
  511. }
  512. break;
  513. }
  514. case TW_TYPE_COLOR3F:
  515. case TW_TYPE_DIR3F:
  516. {
  517. if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
  518. {
  519. value = &f;
  520. }else
  521. {
  522. printf("ERROR: Bad value format...\n");
  523. return false;
  524. }
  525. break;
  526. }
  527. case TW_TYPE_BOOL32:
  528. case TW_TYPE_INT32:
  529. {
  530. if(sscanf(value_str," %d",&i) == 1)
  531. {
  532. value = &i;
  533. }else
  534. {
  535. printf("ERROR: Bad value format...\n");
  536. return false;
  537. }
  538. break;
  539. }
  540. case TW_TYPE_FLOAT:
  541. {
  542. if(sscanf(value_str," %f",&v) == 1)
  543. {
  544. value = &v;
  545. }else
  546. {
  547. printf("ERROR: Bad value format...\n");
  548. return false;
  549. }
  550. break;
  551. }
  552. case TW_TYPE_DOUBLE:
  553. {
  554. if(sscanf(value_str," %lf",&dv) == 1)
  555. {
  556. value = &dv;
  557. }else
  558. {
  559. printf("ERROR: Bad value format...\n");
  560. return false;
  561. }
  562. break;
  563. }
  564. default:
  565. // Try to find type in custom enum types
  566. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  567. ReTw_custom_types.find(type);
  568. if(iter != ReTw_custom_types.end())
  569. {
  570. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  571. bool found = false;
  572. for(;eit<(*iter).second.second.end();eit++)
  573. {
  574. if(strcmp(value_str,eit->Label) == 0)
  575. {
  576. i = eit->Value;
  577. value = &i;
  578. found = true;
  579. break;
  580. }
  581. }
  582. if(!found)
  583. {
  584. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  585. }
  586. }else
  587. {
  588. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  589. }
  590. break;
  591. }
  592. // Find variable based on name
  593. // First look in RW items
  594. bool item_found = false;
  595. for(
  596. std::vector<ReTwRWItem>::iterator it = rw_items.begin();
  597. it != rw_items.end();
  598. it++)
  599. {
  600. if(it->name == name)
  601. {
  602. void * var = it->var;
  603. switch(type)
  604. {
  605. case TW_TYPE_BOOLCPP:
  606. {
  607. bool * bvar = static_cast<bool*>(var);
  608. bool * bvalue = static_cast<bool*>(value);
  609. *bvar = *bvalue;
  610. break;
  611. }
  612. case TW_TYPE_QUAT4D:
  613. //case TW_TYPE_COLOR4D:
  614. {
  615. double * dvar = static_cast<double*>(var);
  616. double * dvalue = static_cast<double*>(value);
  617. dvar[0] = dvalue[0];
  618. dvar[1] = dvalue[1];
  619. dvar[2] = dvalue[2];
  620. dvar[3] = dvalue[3];
  621. break;
  622. }
  623. case TW_TYPE_QUAT4F:
  624. case TW_TYPE_COLOR4F:
  625. {
  626. float * fvar = static_cast<float*>(var);
  627. float * fvalue = static_cast<float*>(value);
  628. fvar[0] = fvalue[0];
  629. fvar[1] = fvalue[1];
  630. fvar[2] = fvalue[2];
  631. fvar[3] = fvalue[3];
  632. break;
  633. }
  634. //case TW_TYPE_COLOR3D:
  635. case TW_TYPE_DIR3D:
  636. {
  637. double * dvar = static_cast<double*>(var);
  638. double * dvalue = static_cast<double*>(value);
  639. dvar[0] = dvalue[0];
  640. dvar[1] = dvalue[1];
  641. dvar[2] = dvalue[2];
  642. break;
  643. }
  644. case TW_TYPE_COLOR3F:
  645. case TW_TYPE_DIR3F:
  646. {
  647. float * fvar = static_cast<float*>(var);
  648. float * fvalue = static_cast<float*>(value);
  649. fvar[0] = fvalue[0];
  650. fvar[1] = fvalue[1];
  651. fvar[2] = fvalue[2];
  652. break;
  653. }
  654. case TW_TYPE_BOOL32:
  655. case TW_TYPE_INT32:
  656. {
  657. int * ivar = static_cast<int*>(var);
  658. int * ivalue = static_cast<int*>(value);
  659. *ivar = *ivalue;
  660. break;
  661. }
  662. case TW_TYPE_FLOAT:
  663. {
  664. float * fvar = static_cast<float*>(var);
  665. float * fvalue = static_cast<float*>(value);
  666. *fvar = *fvalue;
  667. break;
  668. }
  669. case TW_TYPE_DOUBLE:
  670. {
  671. double * dvar = static_cast<double*>(var);
  672. double * fvalue = static_cast<double*>(value);
  673. *dvar = *fvalue;
  674. break;
  675. }
  676. default:
  677. // Try to find type in custom enum types
  678. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  679. ReTw_custom_types.find(type);
  680. if(iter != ReTw_custom_types.end())
  681. {
  682. int * ivar = static_cast<int*>(var);
  683. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  684. bool found = false;
  685. for(;eit<(*iter).second.second.end();eit++)
  686. {
  687. if(strcmp(value_str,eit->Label) == 0)
  688. {
  689. *ivar = eit->Value;
  690. found = true;
  691. break;
  692. }
  693. }
  694. if(!found)
  695. {
  696. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  697. }
  698. }else
  699. {
  700. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  701. }
  702. break;
  703. }
  704. item_found = true;
  705. break;
  706. }
  707. }
  708. // Try looking in CB items
  709. if(!item_found)
  710. {
  711. for(
  712. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  713. it != cb_items.end();
  714. it++)
  715. {
  716. if(it->name==name)
  717. {
  718. it->setCallback(value,it->clientData);
  719. item_found = true;
  720. break;
  721. }
  722. }
  723. }
  724. if(!item_found)
  725. {
  726. printf("ERROR: item not found\n");
  727. }
  728. return true;
  729. }