Param.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. void Param::zero()
  6. {
  7. type=PARAM_TYPE(0);
  8. enum_type=null;
  9. name .clear();
  10. value.s.clear();
  11. value.b=0;
  12. value.i=0;
  13. value.f=0;
  14. value.v2.zero();
  15. value.v .zero();
  16. value.v4.zero();
  17. value.c .zero();
  18. value.id.zero();
  19. }
  20. Param::Param() {zero();}
  21. /******************************************************************************/
  22. Bool Param::asBool()C
  23. {
  24. switch(type)
  25. {
  26. case PARAM_BOOL : return value.b;
  27. case PARAM_INT : return value.i!=0;
  28. case PARAM_FLT : return value.f!=0;
  29. case PARAM_VEC2 : return value.v2.any();
  30. case PARAM_VEC : return value.v .any();
  31. case PARAM_VEC4 : return value.v4.any();
  32. case PARAM_COLOR : return value.c .any();
  33. case PARAM_STR : return TextBool(value.s);
  34. case PARAM_ENUM : return value.id.valid() || value.s.is();
  35. case PARAM_ID : return value.id.valid();
  36. case PARAM_ID_ARRAY: return arrayIDs()>0;
  37. default : return false;
  38. }
  39. }
  40. Int Param::asInt()C
  41. {
  42. switch(type)
  43. {
  44. case PARAM_BOOL : return value.b;
  45. case PARAM_INT : return value.i;
  46. case PARAM_FLT : return Round(value.f );
  47. case PARAM_VEC2 : return Round(value.v2.x);
  48. case PARAM_VEC : return Round(value.v .x);
  49. case PARAM_VEC4 : return Round(value.v4.x);
  50. case PARAM_COLOR : return value.c.r;
  51. case PARAM_STR : return TextInt(value.s);
  52. case PARAM_ENUM : return asEnum();
  53. //case PARAM_ID : return
  54. //case PARAM_ID_ARRAY: return
  55. default : return 0;
  56. }
  57. }
  58. Flt Param::asFlt()C
  59. {
  60. switch(type)
  61. {
  62. case PARAM_BOOL : return value.b;
  63. case PARAM_INT : return value.i;
  64. case PARAM_FLT : return value.f;
  65. case PARAM_VEC2 : return value.v2.x;
  66. case PARAM_VEC : return value.v .x;
  67. case PARAM_VEC4 : return value.v4.x;
  68. case PARAM_COLOR : return value.c .r/255.0f;
  69. case PARAM_STR : return TextFlt(value.s);
  70. case PARAM_ENUM : return asEnum();
  71. //case PARAM_ID : return
  72. //case PARAM_ID_ARRAY: return
  73. default : return 0;
  74. }
  75. }
  76. Vec2 Param::asVec2()C
  77. {
  78. switch(type)
  79. {
  80. case PARAM_BOOL : return value.b ;
  81. case PARAM_INT : return value.i ;
  82. case PARAM_FLT : return value.f ;
  83. case PARAM_VEC2 : return value.v2 ;
  84. case PARAM_VEC : return value.v .xy;
  85. case PARAM_VEC4 : return value.v4.xy;
  86. case PARAM_COLOR : return Vec2(value.c.r, value.c.g)/255.0f;
  87. case PARAM_STR : return TextVec2(value.s);
  88. //case PARAM_ENUM : return asEnum();
  89. //case PARAM_ID : return
  90. //case PARAM_ID_ARRAY: return
  91. default : return 0;
  92. }
  93. }
  94. Vec Param::asVec()C
  95. {
  96. switch(type)
  97. {
  98. case PARAM_BOOL : return value.b ;
  99. case PARAM_INT : return value.i ;
  100. case PARAM_FLT : return value.f ;
  101. case PARAM_VEC2 : return Vec(value.v2, 0 );
  102. case PARAM_VEC : return value.v ;
  103. case PARAM_VEC4 : return value.v4.xyz ;
  104. case PARAM_COLOR : return value.c .asVec();
  105. case PARAM_STR : return TextVec(value.s );
  106. //case PARAM_ENUM : return asEnum();
  107. //case PARAM_ID : return
  108. //case PARAM_ID_ARRAY: return
  109. default : return 0;
  110. }
  111. }
  112. Vec4 Param::asVec4()C
  113. {
  114. switch(type)
  115. {
  116. case PARAM_BOOL : return value.b ;
  117. case PARAM_INT : return value.i ;
  118. case PARAM_FLT : return value.f ;
  119. case PARAM_VEC2 : return Vec4(value.v2, 0, 0);
  120. case PARAM_VEC : return Vec4(value.v , 0);
  121. case PARAM_VEC4 : return value.v4 ;
  122. case PARAM_COLOR : return value.c .asVec4();
  123. case PARAM_STR : return TextVec4(value.s);
  124. //case PARAM_ENUM : return asEnum();
  125. //case PARAM_ID : return
  126. //case PARAM_ID_ARRAY: return
  127. default : return 0;
  128. }
  129. }
  130. Color Param::asColor()C
  131. {
  132. switch(type)
  133. {
  134. case PARAM_BOOL : return value.b ? WHITE : TRANSPARENT;
  135. case PARAM_INT : return Color(value.i, value.i, value.i, 255);
  136. case PARAM_FLT : return Color(FltToByte(value.f ), FltToByte(value.f ), FltToByte(value.f));
  137. case PARAM_VEC2 : return Color(FltToByte(value.v2.x), FltToByte(value.v2.y), 0);
  138. case PARAM_VEC : return value.v;
  139. case PARAM_VEC4 : return value.v4;
  140. case PARAM_COLOR : return value.c;
  141. case PARAM_STR : return TextColor(value.s);
  142. //case PARAM_ID :
  143. //case PARAM_ID_ARRAY:
  144. default : return TRANSPARENT;
  145. }
  146. }
  147. UID Param::asID()C
  148. {
  149. switch(type)
  150. {
  151. //case PARAM_BOOL : return UID(value.b, 0, 0, 0);
  152. //case PARAM_INT : return UID(value.i, 0, 0, 0);
  153. case PARAM_ID : return value.id;
  154. case PARAM_ID_ARRAY: if(arrayIDs()>=1)return *(UID*)value.s(); break;
  155. case PARAM_STR : {UID id; id.fromText(value.s); return id;}
  156. case PARAM_ENUM : return value.id;
  157. }
  158. return UIDZero;
  159. }
  160. UID Param::asID(Int id_index)C
  161. {
  162. switch(type)
  163. {
  164. case PARAM_ID : if( id_index==0 )return value.id ; break;
  165. case PARAM_ID_ARRAY: if(InRange(id_index, arrayIDs()))return ((UID*)value.s())[id_index]; break;
  166. }
  167. return UIDZero;
  168. }
  169. UID Param::asIDMod(Int id_index)C
  170. {
  171. switch(type)
  172. {
  173. case PARAM_ID : return value.id;
  174. case PARAM_ID_ARRAY: if(Int ids=arrayIDs())return ((UID*)value.s())[Mod(id_index, ids)]; break;
  175. }
  176. return UIDZero;
  177. }
  178. Str Param::asText(Int precision)C
  179. {
  180. switch(type)
  181. {
  182. default : return S;
  183. case PARAM_BOOL : return TextInt (value.b);
  184. case PARAM_INT : return TextInt (value.i);
  185. case PARAM_FLT : return TextReal(value.f, precision);
  186. case PARAM_VEC2 : return value.v2.asText(precision);
  187. case PARAM_VEC : return value.v .asText(precision);
  188. case PARAM_VEC4 : return value.v4.asText(precision);
  189. case PARAM_COLOR : return value.c .asText();
  190. case PARAM_STR : return value.s;
  191. case PARAM_ENUM : return value.s;
  192. case PARAM_ID : return value.id.asHex();
  193. case PARAM_ID_ARRAY:
  194. {
  195. Str s; if(Int ids=arrayIDs())
  196. {
  197. s.reserve(ids*32 + (ids-1)); // 32=characters for one ID, (ids-1)=number of '\n' between ID's
  198. UID *id=(UID*)value.s();
  199. FREP(ids)s.line()+=id[i].asHex(); // list in order
  200. }
  201. return s;
  202. }
  203. }
  204. }
  205. Int Param::asEnum()C
  206. {
  207. switch(type)
  208. {
  209. case PARAM_INT : return value.i;
  210. case PARAM_ENUM: if(enum_type){Int i=enum_type->find(value.id); if(i>=0)return i; i=enum_type->find(value.s); if(i>=0)return i;} break; // try ID first, then try Name
  211. }
  212. return -1;
  213. }
  214. /******************************************************************************/
  215. Int Param::arrayIDs()C {return value.s.length()/(SIZE(UID)/SIZE(Char));} // !! only for PARAM_ID_ARRAY !!
  216. Int Param:: IDs()C
  217. {
  218. switch(type)
  219. {
  220. case PARAM_ID : return 1;
  221. case PARAM_ID_ARRAY: return arrayIDs();
  222. default : return 0;
  223. }
  224. }
  225. UInt Param::memUsage()C
  226. {
  227. return value.s.memUsage();
  228. }
  229. Bool Param::hasID(C UID &id)C
  230. {
  231. switch(type)
  232. {
  233. case PARAM_ID : return value.id==id;
  234. case PARAM_ID_ARRAY:
  235. {
  236. UID *ids=(UID*)value.s();
  237. REP(arrayIDs())if(ids[i]==id)return true;
  238. }break;
  239. }
  240. return false;
  241. }
  242. /******************************************************************************/
  243. Param& Param::clearValue()
  244. {
  245. switch(type)
  246. {
  247. case PARAM_BOOL : value.b=0; break;
  248. case PARAM_INT : value.i=0; break;
  249. case PARAM_FLT : value.f=0; break;
  250. case PARAM_VEC2 : value.v2.zero (); break;
  251. case PARAM_VEC : value.v .zero (); break;
  252. case PARAM_VEC4 : value.v4.zero (); break;
  253. case PARAM_COLOR : value.c .zero (); break;
  254. case PARAM_ID : value.id.zero (); break;
  255. case PARAM_ID_ARRAY: value.s .clear(); break;
  256. case PARAM_STR : value.s .clear(); break;
  257. case PARAM_ENUM : value.s .clear(); value.id.zero(); break;
  258. }
  259. return T;
  260. }
  261. Param& Param::setValue(Int i)
  262. {
  263. switch(type)
  264. {
  265. case PARAM_BOOL : value.b =(i!=0); break;
  266. case PARAM_INT : value.i =i; break;
  267. case PARAM_FLT : value.f =i; break;
  268. case PARAM_VEC2 : value.v2=i; break;
  269. case PARAM_VEC : value.v =i; break;
  270. case PARAM_VEC4 : value.v4=i; break;
  271. case PARAM_STR : value.s =i; break;
  272. case PARAM_COLOR : value.c .set(i, i, i, 255); break;
  273. //case PARAM_ID : value.id.set(i, 0, 0, 0); break; don't change
  274. //case PARAM_ID_ARRAY: break; don't change
  275. case PARAM_ENUM :
  276. {
  277. if(enum_type && InRange(i, *enum_type))
  278. {
  279. value.s =(*enum_type)[i].name;
  280. value.id=(*enum_type)[i].id ;
  281. }else
  282. {
  283. value.s .clear();
  284. value.id.zero();
  285. }
  286. }break;
  287. }
  288. return T;
  289. }
  290. Param& Param::setValue(C Str &s)
  291. {
  292. switch(type)
  293. {
  294. case PARAM_BOOL : value.b =TextBool (s); break;
  295. case PARAM_INT : value.i =TextInt (s); break;
  296. case PARAM_FLT : value.f =TextFlt (s); break;
  297. case PARAM_VEC2 : value.v2=TextVec2 (s); break;
  298. case PARAM_VEC : value.v =TextVec (s); break;
  299. case PARAM_VEC4 : value.v4=TextVec4 (s); break;
  300. case PARAM_STR : value.s = s ; break;
  301. case PARAM_COLOR : value.c =TextColor(s); break;
  302. case PARAM_ID : value.id.fromText (s); break;
  303. case PARAM_ID_ARRAY:
  304. { // this should handle the case when 's' is 'this.s'
  305. Memt<Str> lines; Split(lines, s, '\n');
  306. Memt<UID> ids ; FREPA(lines){UID temp; if(temp.fromText(lines[i]))Swap(ids.New(), temp);}
  307. setAsIDArray(ids, false); // disallow changing type because we're in 'setValue' which can change only the value
  308. }break;
  309. case PARAM_ENUM:
  310. {
  311. value.s .clear();
  312. value.id.zero ();
  313. if(enum_type)
  314. {
  315. Int e=enum_type->find(s); if(InRange(e, *enum_type))
  316. {
  317. value.s =(*enum_type)[e].name;
  318. value.id=(*enum_type)[e].id ;
  319. }
  320. }
  321. }break;
  322. }
  323. return T;
  324. }
  325. Param& Param::setValue(C Param &src)
  326. {
  327. if(type==src.type)value=src.value;else switch(type)
  328. {
  329. case PARAM_BOOL : value.b =src.asBool (); break;
  330. case PARAM_INT : value.i =src.asInt (); break;
  331. case PARAM_FLT : value.f =src.asFlt (); break;
  332. case PARAM_VEC2 : value.v2=src.asVec2 (); break;
  333. case PARAM_VEC : value.v =src.asVec (); break;
  334. case PARAM_VEC4 : value.v4=src.asVec4 (); break;
  335. case PARAM_COLOR: value.c =src.asColor(); break;
  336. case PARAM_ID : value.id=src.asID (); break;
  337. case PARAM_ID_ARRAY: switch(src.type)
  338. {
  339. case PARAM_ID : setAsIDArray(ConstCast(src.value.id), false); break; // disallow changing type because we're in 'setValue' which can change only the value
  340. //case PARAM_ID_ARRAY: this case is already handled in "type==src.type"
  341. case PARAM_STR : setValue(src.value.s); break;
  342. default : value.s.clear(); break;
  343. }break;
  344. case PARAM_STR: switch(src.type)
  345. {
  346. case PARAM_BOOL : if(!src.value.b )value.s.clear();else value.s=src.asText(); break;
  347. case PARAM_INT : if(!src.value.i )value.s.clear();else value.s=src.asText(); break;
  348. case PARAM_FLT : if(!src.value.f )value.s.clear();else value.s=src.asText(); break;
  349. case PARAM_VEC2 : if(!src.value.v2.any ())value.s.clear();else value.s=src.asText(); break;
  350. case PARAM_VEC : if(!src.value.v .any ())value.s.clear();else value.s=src.asText(); break;
  351. case PARAM_VEC4 : if(!src.value.v4.any ())value.s.clear();else value.s=src.asText(); break;
  352. case PARAM_COLOR : if(!src.value.c .any ())value.s.clear();else value.s=src.asText(); break;
  353. case PARAM_ID : if(!src.value.id.valid())value.s.clear();else value.s=src.asText(); break;
  354. case PARAM_ID_ARRAY: value.s=src.asText(); break; // 'asText' will already return an empty string if there are no ID's
  355. case PARAM_ENUM : value.s=src.value.s; break;
  356. //case PARAM_STR : value.s=src.value.s; break; this case is already handled in "type==src.type"
  357. default : value.s.clear(); break;
  358. }break;
  359. case PARAM_ENUM: switch(src.type)
  360. {
  361. case PARAM_ENUM: value.s =src.value.s ; value.id=src.value.id; if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s =(*enum_type)[i].name;else{i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  362. case PARAM_STR : value.s =src.value.s ; value.id.zero (); if(enum_type){Int i=enum_type->find(value.s ); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id ;} break;
  363. case PARAM_ID : value.id=src.value.id; value.s .clear(); if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s =(*enum_type)[i].name;} break;
  364. default : value.s.clear(); value.id.zero (); break;
  365. }break;
  366. }
  367. return T;
  368. }
  369. Param& Param::setType(PARAM_TYPE type, Enum *enum_type)
  370. {
  371. if(InRange(type, PARAM_NUM))
  372. if(T.type!=type || (type==PARAM_ENUM && T.enum_type!=enum_type))
  373. {
  374. switch(type)
  375. {
  376. case PARAM_BOOL : value.b =asBool (); value.s.clear(); break;
  377. case PARAM_INT : value.i =asInt (); value.s.clear(); break;
  378. case PARAM_FLT : value.f =asFlt (); value.s.clear(); break;
  379. case PARAM_VEC2 : value.v2=asVec2 (); value.s.clear(); break;
  380. case PARAM_VEC : value.v =asVec (); value.s.clear(); break;
  381. case PARAM_VEC4 : value.v4=asVec4 (); value.s.clear(); break;
  382. case PARAM_COLOR: value.c =asColor(); value.s.clear(); break;
  383. case PARAM_ID : value.id=asID (); value.s.clear(); break;
  384. case PARAM_ID_ARRAY: switch(T.type)
  385. {
  386. case PARAM_ID : setAsIDArray(value.id, false); break; // disallow changing type because we're in 'setType' which assumes that 'type' will be set precisely
  387. case PARAM_STR: T.type=type; setValue(value.s); break; // change the type before calling 'setValue'
  388. default : value.s.clear(); break;
  389. }break;
  390. case PARAM_STR: switch(T.type)
  391. {
  392. case PARAM_BOOL : if(!value.b )value.s.clear();else value.s=asText(); break;
  393. case PARAM_INT : if(!value.i )value.s.clear();else value.s=asText(); break;
  394. case PARAM_FLT : if(!value.f )value.s.clear();else value.s=asText(); break;
  395. case PARAM_VEC2 : if(!value.v2.any ())value.s.clear();else value.s=asText(); break;
  396. case PARAM_VEC : if(!value.v .any ())value.s.clear();else value.s=asText(); break;
  397. case PARAM_VEC4 : if(!value.v4.any ())value.s.clear();else value.s=asText(); break;
  398. case PARAM_COLOR : if(!value.c .any ())value.s.clear();else value.s=asText(); break;
  399. case PARAM_ID : if(!value.id.valid())value.s.clear();else value.s=asText(); break;
  400. case PARAM_ID_ARRAY: value.s=asText(); break; // 'asText' will already return an empty string if there are no ID's
  401. case PARAM_ENUM : break; // keep 'value.s'
  402. default : value.s.clear(); break;
  403. }break;
  404. case PARAM_ENUM:
  405. {
  406. T.enum_type=enum_type;
  407. switch(T.type)
  408. {
  409. case PARAM_ENUM: if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s =(*enum_type)[i].name;else{i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break; // keep 'value.s', 'value.id'
  410. case PARAM_STR : value.id.zero (); if(enum_type){Int i=enum_type->find(value.s ); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id ;} break; // keep 'value.s'
  411. case PARAM_ID : value.s .clear(); if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s =(*enum_type)[i].name;} break; // keep 'value.id'
  412. default : value.s .clear(); value.id.zero(); break;
  413. }
  414. }break;
  415. }
  416. T.type=type; // change type at the end
  417. if(T.type!=PARAM_ENUM)T.enum_type=null;
  418. }
  419. return T;
  420. }
  421. /******************************************************************************/
  422. Param& Param::setTypeValue(C Param &src)
  423. {
  424. T. type=src. type;
  425. T.enum_type=src.enum_type;
  426. T. value=src. value;
  427. return T;
  428. }
  429. /******************************************************************************/
  430. Param& Param::setAsIDArray(C MemPtr<UID> &ids, Bool allow_PARAM_ID_type)
  431. {
  432. enum_type=null;
  433. value.s.clear(); // always 'clear' even for 'reserve' to avoid copying old data in 'setNum'
  434. if(allow_PARAM_ID_type && ids.elms()==1)
  435. {
  436. type=PARAM_ID;
  437. value.id=ids[0];
  438. }else
  439. {
  440. type=PARAM_ID_ARRAY;
  441. if(ids.elms())
  442. {
  443. Int chars=ids.elms()*(SIZE(UID)/SIZE(Char));
  444. value.s.reserve(chars); ids.copyTo((UID*)value.s());
  445. value.s._d[value.s._length=chars]='\0'; // this is a string so it needs to have a nul terminate char
  446. }
  447. }
  448. return T;
  449. }
  450. Param& Param::includeAsIDArray(C MemPtr<UID> &ids, Bool allow_PARAM_ID_type)
  451. {
  452. if(Int id_num=IDs()) // if have any existing ID's
  453. {
  454. Memt<UID> temp; temp.setNum(id_num);
  455. if(type==PARAM_ID)temp[0]=value.id;else temp.copyFrom((UID*)value.s());
  456. FREPA(ids)temp.include(ids[i]); // include in order
  457. return setAsIDArray(temp, allow_PARAM_ID_type);
  458. }
  459. return setAsIDArray(ids, allow_PARAM_ID_type);
  460. }
  461. /******************************************************************************/
  462. Bool Param::save(File &f, CChar *path)C
  463. {
  464. f.putMulti(Byte(5), type); // version
  465. if(type==PARAM_ENUM)f.putAsset(Enums.id(enum_type));
  466. f.putStr(name);
  467. switch(type)
  468. {
  469. case PARAM_BOOL : f<<value.b ; break;
  470. case PARAM_INT : f<<value.i ; break;
  471. case PARAM_FLT : f<<value.f ; break;
  472. case PARAM_VEC2 : f<<value.v2; break;
  473. case PARAM_VEC : f<<value.v ; break;
  474. case PARAM_VEC4 : f<<value.v4; break;
  475. case PARAM_COLOR : f<<value.c ; break;
  476. case PARAM_ID : f<<value.id; break;
  477. case PARAM_ENUM : f<<value.id<<value.s; break;
  478. case PARAM_STR : f<<value.s ; break;
  479. case PARAM_ID_ARRAY: {Int ids=arrayIDs(); f.cmpUIntV(ids); f.putN((UID*)value.s(), ids);} break;
  480. }
  481. return f.ok();
  482. }
  483. Bool Param::load(File &f, CChar *path)
  484. {
  485. value.s.clear();
  486. switch(f.decUIntV()) // version
  487. {
  488. case 5:
  489. {
  490. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f.getAssetID(), path);else enum_type=null;
  491. f.getStr(name);
  492. switch(type)
  493. {
  494. default : goto error;
  495. case PARAM_BOOL : f>>value.b ; break;
  496. case PARAM_INT : f>>value.i ; break;
  497. case PARAM_FLT : f>>value.f ; break;
  498. case PARAM_VEC2 : f>>value.v2; break;
  499. case PARAM_VEC : f>>value.v ; break;
  500. case PARAM_VEC4 : f>>value.v4; break;
  501. case PARAM_COLOR : f>>value.c ; break;
  502. case PARAM_ID : f>>value.id; break;
  503. case PARAM_ENUM : f>>value.id>>value.s; if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s=(*enum_type)[i].name;else{i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  504. case PARAM_STR : f>>value.s ; break;
  505. case PARAM_ID_ARRAY: if(UInt ids=f.decUIntV())
  506. {
  507. Int chars=ids*(SIZE(UID)/SIZE(Char));
  508. value.s.reserve(chars); f.getN((UID*)value.s(), ids);
  509. value.s._d[value.s._length=chars]='\0'; // this is a string so it needs to have a nul terminate char
  510. }break;
  511. }
  512. if(f.ok())return true;
  513. }break;
  514. case 4:
  515. {
  516. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f.getAssetID(), path);else enum_type=null;
  517. f._getStr2(name);
  518. switch(type)
  519. {
  520. default : goto error;
  521. case PARAM_BOOL : f>>value.b ; break;
  522. case PARAM_INT : f>>value.i ; break;
  523. case PARAM_FLT : f>>value.f ; break;
  524. case PARAM_VEC2 : f>>value.v2; break;
  525. case PARAM_VEC : f>>value.v ; break;
  526. case PARAM_VEC4 : f>>value.v4; break;
  527. case PARAM_COLOR : f>>value.c ; break;
  528. case PARAM_ID : f>>value.id; break;
  529. case PARAM_ENUM : f>>value.id; f._getStr2(value.s); if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s=(*enum_type)[i].name;else{i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  530. case PARAM_STR : f._getStr2(value.s); break;
  531. case PARAM_ID_ARRAY: if(UInt ids=f.decUIntV())
  532. {
  533. Int chars=ids*(SIZE(UID)/SIZE(Char));
  534. value.s.reserve(chars); f.getN((UID*)value.s(), ids);
  535. value.s._d[value.s._length=chars]='\0'; // this is a string so it needs to have a nul terminate char
  536. }break;
  537. }
  538. if(f.ok())return true;
  539. }break;
  540. case 3:
  541. {
  542. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f._getStr(), path);else enum_type=null;
  543. f._getStr(name);
  544. switch(type)
  545. {
  546. case PARAM_BOOL : f>>value.b ; break;
  547. case PARAM_INT : f>>value.i ; break;
  548. case PARAM_FLT : f>>value.f ; break;
  549. case PARAM_VEC2 : f>>value.v2; break;
  550. case PARAM_VEC : f>>value.v ; break;
  551. case PARAM_VEC4 : f>>value.v4; break;
  552. case PARAM_COLOR: f>>value.c ; break;
  553. case PARAM_ID : f>>value.id; if(!value.id.valid())type=PARAM_ID_ARRAY; break; // upgrade old file format's empty ID to PARAM_ID_ARRAY with no elements
  554. case PARAM_ENUM : f>>value.id; f._getStr(value.s); if(enum_type){Int i=enum_type->find(value.id); if(InRange(i, *enum_type))value.s=(*enum_type)[i].name;else{i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  555. case PARAM_STR : f._getStr(value.s); break;
  556. default : goto error;
  557. }
  558. if(f.ok())return true;
  559. }break;
  560. case 2:
  561. {
  562. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f._getStr(), path);else enum_type=null;
  563. f._getStr(name);
  564. switch(type)
  565. {
  566. case PARAM_BOOL : f >> value.b ; break;
  567. case PARAM_INT : f >> value.i ; break;
  568. case PARAM_FLT : f >> value.f ; break;
  569. case PARAM_VEC2 : f >> value.v2; break;
  570. case PARAM_VEC : f >> value.v ; break;
  571. case PARAM_VEC4 : f >> value.v4; break;
  572. case PARAM_COLOR: f >> value.c ; break;
  573. case PARAM_STR : f._getStr(value.s); break;
  574. case PARAM_ENUM : f._getStr(value.s); value.id.zero(); if(enum_type){Int i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;} break;
  575. default : goto error;
  576. }
  577. if(f.ok())return true;
  578. }break;
  579. case 1:
  580. {
  581. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f._getStr16(), path);else enum_type=null;
  582. name=f._getStr16();
  583. switch(type)
  584. {
  585. case PARAM_BOOL: f>>value.b ; break;
  586. case PARAM_INT : f>>value.i ; break;
  587. case PARAM_FLT : f>>value.f ; break;
  588. case PARAM_STR : value.s=f._getStr16(); break;
  589. case PARAM_ENUM: value.s=f._getStr16(); value.id.zero(); if(enum_type){Int i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;} break;
  590. default : goto error;
  591. }
  592. if(f.ok())return true;
  593. }break;
  594. case 0:
  595. {
  596. f>>type; if(type==PARAM_ENUM)enum_type=Enums(f._getStr8(), path);else enum_type=null;
  597. name=f._getStr8();
  598. switch(type)
  599. {
  600. case PARAM_BOOL: f>>value.b; break;
  601. case PARAM_INT : f>>value.i; break;
  602. case PARAM_FLT : f>>value.f; break;
  603. case PARAM_STR : {Char8 str[256]; f>>str; value.s=str;} break;
  604. case PARAM_ENUM: {Char8 str[256]; f>>str; value.s=str; value.id.zero(); if(enum_type){Int i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  605. default : goto error;
  606. }
  607. if(f.ok())return true;
  608. }break;
  609. }
  610. error:
  611. zero(); return false;
  612. }
  613. void Param::loadOld(File &f)
  614. {
  615. value.s.clear();
  616. f>>type;
  617. Char8 name[40]; f>>name; T.name=name;
  618. if(type==PARAM_ENUM){Char8 name[256]; f>>name; enum_type=Enums(name);}else enum_type=null;
  619. switch(type)
  620. {
  621. case PARAM_BOOL: f>>value.b; break;
  622. case PARAM_INT : f>>value.i; break;
  623. case PARAM_FLT : f>>value.f; break;
  624. case PARAM_STR : {Char8 str[256]; f>>str; value.s=str;} break;
  625. case PARAM_ENUM: {Char8 str[256]; f>>str; value.s=str; value.id.zero(); if(enum_type){Int i=enum_type->find(value.s); if(InRange(i, *enum_type))value.id=(*enum_type)[i].id;}} break;
  626. }
  627. if(f.ok())return;
  628. zero();
  629. }
  630. /******************************************************************************/
  631. Int CompareValue(C Param &p0, C Param &p1)
  632. {
  633. if(Int i=Compare(p0.type, p1.type))return i; // type
  634. switch(p0.type) // value
  635. {
  636. case PARAM_BOOL : return Compare(p0.value.b , p1.value.b );
  637. case PARAM_INT : return Compare(p0.value.i , p1.value.i );
  638. case PARAM_FLT : return Compare(p0.value.f , p1.value.f );
  639. case PARAM_VEC2 : return Compare(p0.value.v2, p1.value.v2);
  640. case PARAM_VEC : return Compare(p0.value.v , p1.value.v );
  641. case PARAM_VEC4 : return Compare(p0.value.v4, p1.value.v4);
  642. case PARAM_COLOR : return Compare(p0.value.c , p1.value.c );
  643. case PARAM_STR : return Compare(p0.value.s , p1.value.s );
  644. case PARAM_ID : return Compare(p0.value.id, p1.value.id);
  645. case PARAM_ID_ARRAY:
  646. {
  647. Int ids0=p0.arrayIDs(), ids1=p1.arrayIDs(), ids=Min(ids0, ids1);
  648. FREP(ids)if(Int c=Compare(p0.asID(i), p1.asID(i)))return c;
  649. return Compare(ids0, ids1);
  650. }break;
  651. case PARAM_ENUM:
  652. {
  653. if(p0.enum_type && p1.enum_type)
  654. {
  655. if(p0.enum_type!=p1.enum_type)return Compare(p0.enum_type->name, p1.enum_type->name);
  656. }else
  657. if(p0.enum_type)return +1;else
  658. if(p1.enum_type)return -1;
  659. }return Compare(p0.value.s, p1.value.s);
  660. }
  661. return 0;
  662. }
  663. Int Compare(C Param &p0, C Param &p1)
  664. {
  665. if(Int i=Compare(p0.name, p1.name))return i; // name
  666. return CompareValue(p0, p1);
  667. }
  668. /******************************************************************************/
  669. }
  670. /******************************************************************************/