propertyParsing.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "core/strings/stringFunctions.h"
  23. #include "core/strings/stringUnit.h"
  24. #include "console/consoleInternal.h"
  25. #include "core/color.h"
  26. #include "console/consoleTypes.h"
  27. #include "math/mPoint2.h"
  28. #include "math/mPoint3.h"
  29. #include "math/mPoint4.h"
  30. #include "math/mRect.h"
  31. #include "math/mBox.h"
  32. #include "math/mQuat.h"
  33. #include "math/mAngAxis.h"
  34. #include "math/mMatrix.h"
  35. // Property system includes:
  36. #include "console/propertyParsing.h"
  37. namespace PropertyInfo
  38. {
  39. //-----------------------------------------------------------------------------
  40. // Bool
  41. //-----------------------------------------------------------------------------
  42. bool default_scan(const String &data, bool & result)
  43. {
  44. result = dAtob(data.c_str());
  45. return true;
  46. }
  47. bool default_print(String & result, bool const & data)
  48. {
  49. if(data)
  50. result = String("1");
  51. else
  52. result = String("0");
  53. return true;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // F32/U32/S32
  57. //-----------------------------------------------------------------------------
  58. bool default_scan(const String &data, F32 & result)
  59. {
  60. result = dAtof(data.c_str());
  61. return true;
  62. }
  63. bool default_print(String & result, F32 const & data)
  64. {
  65. result = String::ToString(data);
  66. return true;
  67. }
  68. bool default_scan(const String &data, U32 & result)
  69. {
  70. result = dAtoi(data.c_str());
  71. return true;
  72. }
  73. bool default_print(String & result, U32 const & data)
  74. {
  75. result = String::ToString(data);
  76. return true;
  77. }
  78. bool default_scan(const String &data, S32 & result)
  79. {
  80. result = dAtoi(data.c_str());
  81. return true;
  82. }
  83. bool default_print(String & result, S32 const & data)
  84. {
  85. result = String::ToString(data);
  86. return true;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Basic Vector Types
  90. //-----------------------------------------------------------------------------
  91. template <typename T>
  92. inline void default_vector_scan(const String &data, Vector<T> & result)
  93. {
  94. result.clear();
  95. for(S32 i = 0; i < StringUnit::getUnitCount(data, " \t\n"); i++)
  96. result.push_back(dAtof(StringUnit::getUnit(data, i, " \t\n")));
  97. }
  98. template <typename T>
  99. inline void default_vector_print(String & result, Vector<T> const & data)
  100. {
  101. result = String("");
  102. S32 items = data.size();
  103. for(S32 i = 0; i < items; i++)
  104. {
  105. result += String::ToString(data[i]);
  106. if(i < items-1)
  107. result += String(" ");
  108. }
  109. }
  110. bool default_scan(const String &data, Vector<F32> & result)
  111. {
  112. default_vector_scan(data,result);
  113. return true;
  114. }
  115. bool default_print(String & result, Vector<F32> const & data)
  116. {
  117. default_vector_print<F32>(result,data);
  118. return true;
  119. }
  120. bool default_scan(const String &data, Vector<U32> & result)
  121. {
  122. default_vector_scan(data,result);
  123. return true;
  124. }
  125. bool default_print(String & result, Vector<U32> const & data)
  126. {
  127. default_vector_print<U32>(result,data);
  128. return true;
  129. }
  130. bool default_scan(const String &data, Vector<S32> & result)
  131. {
  132. default_vector_scan(data,result);
  133. return true;
  134. }
  135. bool default_print(String & result, Vector<S32> const & data)
  136. {
  137. default_vector_print<S32>(result,data);
  138. return true;
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Math - Points
  142. //-----------------------------------------------------------------------------
  143. bool default_scan(const String &data, Point2F & result)
  144. {
  145. dSscanf(data.c_str(),"%g %g",&result.x,&result.y);
  146. return true;
  147. }
  148. bool default_print(String & result, Point2F const & data)
  149. {
  150. result = String::ToString("%g %g",data.x,data.y);
  151. return true;
  152. }
  153. bool default_scan(const String &data, Point2I & result)
  154. {
  155. // Handle passed as floating point from script
  156. if(data.find('.') != String::NPos)
  157. {
  158. Point2F tempResult;
  159. dSscanf(data.c_str(),"%f %f",&tempResult.x,&tempResult.y);
  160. result.x = mFloor(tempResult.x);
  161. result.y = mFloor(tempResult.y);
  162. }
  163. else
  164. dSscanf(data.c_str(),"%d %d",&result.x,&result.y);
  165. return true;
  166. }
  167. bool default_print(String & result, Point2I const & data)
  168. {
  169. result = String::ToString("%d %d",data.x,data.y);
  170. return true;
  171. }
  172. bool default_scan(const String &data, Point3F & result)
  173. {
  174. dSscanf(data.c_str(),"%g %g %g",&result.x,&result.y,&result.z);
  175. return true;
  176. }
  177. bool default_print(String & result, Point3F const & data)
  178. {
  179. result = String::ToString("%g %g %g",data.x,data.y,data.z);
  180. return true;
  181. }
  182. bool default_scan(const String &data, Point3I & result)
  183. {
  184. // Handle passed as floating point from script
  185. if(data.find('.') != String::NPos)
  186. {
  187. Point3F tempResult;
  188. dSscanf(data.c_str(),"%f %f %f",&tempResult.x,&tempResult.y,&tempResult.z);
  189. result.x = mFloor(tempResult.x);
  190. result.y = mFloor(tempResult.y);
  191. result.z = mFloor(tempResult.z);
  192. }
  193. else
  194. dSscanf(data.c_str(),"%d %d %d",&result.x,&result.y,&result.z);
  195. return true;
  196. }
  197. bool default_print(String & result, Point3I const & data)
  198. {
  199. result = String::ToString("%d %d %d",data.x,data.y,data.z);
  200. return true;
  201. }
  202. bool default_scan(const String &data, Point4F & result)
  203. {
  204. dSscanf(data.c_str(),"%g %g %g %g",&result.x,&result.y,&result.z,&result.w);
  205. return true;
  206. }
  207. bool default_print(String & result, Point4F const & data)
  208. {
  209. result = String::ToString("%g %g %g %g",data.x,data.y,data.z,data.w);
  210. return true;
  211. }
  212. bool default_scan(const String &data, Point4I & result)
  213. {
  214. // Handle passed as floating point from script
  215. if(data.find('.') != String::NPos)
  216. {
  217. Point4F tempResult;
  218. dSscanf(data.c_str(),"%f %f %f %f",&tempResult.x,&tempResult.y,&tempResult.z,&tempResult.w);
  219. result.x = mFloor(tempResult.x);
  220. result.y = mFloor(tempResult.y);
  221. result.z = mFloor(tempResult.z);
  222. result.w = mFloor(tempResult.w);
  223. }
  224. else
  225. dSscanf(data.c_str(),"%d %d %d %d",&result.x,&result.y,&result.z,&result.w);
  226. return true;
  227. }
  228. bool default_print(String & result, const Point4I & data)
  229. {
  230. result = String::ToString("%d %d %d %d", data.x, data.y, data.z, data.w);
  231. return true;
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Math - Rectangles and boxes
  235. //-----------------------------------------------------------------------------
  236. bool default_scan( const String &data, RectI & result )
  237. {
  238. // Handle passed as floating point from script
  239. if(data.find('.') != String::NPos)
  240. {
  241. RectF tempResult;
  242. dSscanf(data.c_str(),"%f %f %f %f",&tempResult.point.x,&tempResult.point.y,&tempResult.extent.x,&tempResult.extent.y);
  243. result.point.x = mFloor(tempResult.point.x);
  244. result.point.y = mFloor(tempResult.point.y);
  245. result.extent.x = mFloor(tempResult.extent.x);
  246. result.extent.y = mFloor(tempResult.extent.y);
  247. }
  248. else
  249. dSscanf(data.c_str(),"%d %d %d %d",&result.point.x,&result.point.y,&result.extent.x,&result.extent.y);
  250. return true;
  251. }
  252. bool default_print( String & result, const RectI & data )
  253. {
  254. result = String::ToString("%i %i %i %i",data.point.x,data.point.y,data.extent.x,data.extent.y);
  255. return true;
  256. }
  257. bool default_scan(const String &data, RectF & result)
  258. {
  259. dSscanf(data.c_str(),"%g %g %g %g",&result.point.x,&result.point.y,&result.extent.x,&result.extent.y);
  260. return true;
  261. }
  262. bool default_print(String & result, const RectF & data)
  263. {
  264. result = String::ToString("%g %g %g %g",data.point.x,data.point.y,data.extent.x,data.extent.y);
  265. return true;
  266. }
  267. bool default_scan(const String &data, Box3F & result)
  268. {
  269. dSscanf(data.c_str(),"%g %g %g %g %g %g",
  270. &result.minExtents.x,&result.minExtents.y,&result.minExtents.z,
  271. &result.maxExtents.x,&result.maxExtents.y,&result.maxExtents.z);
  272. return true;
  273. }
  274. bool default_print(String & result, const Box3F & data)
  275. {
  276. result = String::ToString("%g %g %g %g %g %g",
  277. data.minExtents.x,data.minExtents.y,data.minExtents.z,
  278. data.maxExtents.x,data.maxExtents.y,data.maxExtents.z);
  279. return true;
  280. }
  281. //-----------------------------------------------------------------------------
  282. bool default_scan( const String &data, AngAxisF & result )
  283. {
  284. if(StringUnit::getUnitCount(data," ") < 4)
  285. return false;
  286. dSscanf(data.c_str(),"%g %g %g %g", &result.axis.x,&result.axis.y,&result.axis.z,&result.angle);
  287. result.angle = mDegToRad(result.angle);
  288. return true;
  289. }
  290. bool default_print( String & result, const AngAxisF & data )
  291. {
  292. F32 angle = mRadToDeg(data.angle);
  293. angle = mFmod(angle + 360.0f,360.0f);
  294. result = String::ToString("%g %g %g %g", data.axis.x, data.axis.y, data.axis.z, angle);
  295. return true;
  296. }
  297. bool default_scan( const String &data, QuatF & result )
  298. {
  299. if(StringUnit::getUnitCount(data," ") < 4)
  300. return false;
  301. dSscanf(data.c_str(),"%g %g %g %g", &result.x,&result.y,&result.z,&result.w);
  302. return true;
  303. }
  304. bool default_print( String & result, const QuatF & data )
  305. {
  306. result = String::ToString("%g %g %g %g", data.x, data.y, data.z, data.w);
  307. return true;
  308. }
  309. bool default_scan( const String &data, MatrixF & result )
  310. {
  311. if(StringUnit::getUnitCount(data," ") < 16)
  312. return false;
  313. F32* m = result;
  314. dSscanf(data.c_str(),"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
  315. &m[result.idx(0,0)], &m[result.idx(0,1)], &m[result.idx(0,2)], &m[result.idx(0,3)],
  316. &m[result.idx(1,0)], &m[result.idx(1,1)], &m[result.idx(1,2)], &m[result.idx(1,3)],
  317. &m[result.idx(2,0)], &m[result.idx(2,1)], &m[result.idx(2,2)], &m[result.idx(2,3)],
  318. &m[result.idx(3,0)], &m[result.idx(3,1)], &m[result.idx(3,2)], &m[result.idx(3,3)]);
  319. return true;
  320. }
  321. bool default_print( String & result, const MatrixF & data )
  322. {
  323. const F32* m = data;
  324. result = String::ToString("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g",
  325. m[data.idx(0,0)], m[data.idx(0,1)], m[data.idx(0,2)], m[data.idx(0,3)],
  326. m[data.idx(1,0)], m[data.idx(1,1)], m[data.idx(1,2)], m[data.idx(1,3)],
  327. m[data.idx(2,0)], m[data.idx(2,1)], m[data.idx(2,2)], m[data.idx(2,3)],
  328. m[data.idx(3,0)], m[data.idx(3,1)], m[data.idx(3,2)], m[data.idx(3,3)]);
  329. return true;
  330. }
  331. //-----------------------------------------------------------------------------
  332. // Colors
  333. //-----------------------------------------------------------------------------
  334. bool default_scan(const String &data, LinearColorF & result)
  335. {
  336. if(StringUnit::getUnitCount(data," ") == 3)
  337. {
  338. dSscanf(data.c_str(),"%g %g %g",&result.red,&result.green,&result.blue);
  339. result.alpha = 1.0f;
  340. }
  341. else
  342. dSscanf(data.c_str(),"%g %g %g %g",&result.red,&result.green,&result.blue,&result.alpha);
  343. return true;
  344. }
  345. bool default_print(String & result, LinearColorF const & data)
  346. {
  347. if(data.alpha == 1.0f)
  348. result = String::ToString("%g %g %g",data.red,data.green,data.blue);
  349. else
  350. result = String::ToString("%g %g %g %g",data.red,data.green,data.blue,data.alpha);
  351. return true;
  352. }
  353. bool default_scan(const String &data, ColorI & result)
  354. {
  355. if(StringUnit::getUnitCount(data," ") == 3)
  356. {
  357. S32 r,g,b;
  358. dSscanf(data.c_str(),"%i %i %i",&r,&g,&b);
  359. result.set(r,g,b);
  360. }
  361. else
  362. {
  363. S32 r,g,b,a;
  364. dSscanf(data.c_str(),"%i %i %i %i",&r,&g,&b,&a);
  365. result.set(r,g,b,a);
  366. }
  367. return true;
  368. }
  369. bool default_print(String & result, const ColorI & data)
  370. {
  371. if(data.alpha == 255)
  372. result = String::ToString("%d %d %d",data.red,data.green,data.blue);
  373. else
  374. result = String::ToString("%d %d %d %d",data.red,data.green,data.blue,data.alpha);
  375. return true;
  376. }
  377. //-----------------------------------------------------------------------------
  378. // String
  379. //-----------------------------------------------------------------------------
  380. bool default_scan(const String &data, String & result)
  381. {
  382. result = data;
  383. return true;
  384. }
  385. bool default_print(String & result, const String & data)
  386. {
  387. result = data;
  388. return true;
  389. }
  390. //-----------------------------------------------------------------------------
  391. // FileName
  392. //-----------------------------------------------------------------------------
  393. bool default_scan(const String &data, FileName & result)
  394. {
  395. char buffer[1024];
  396. if(data.c_str()[0] == '$')
  397. {
  398. dStrncpy(buffer, data.c_str(), sizeof(buffer) - 1);
  399. buffer[sizeof(buffer)-1] = 0;
  400. }
  401. else if (!Con::expandScriptFilename(buffer, sizeof(buffer), data))
  402. {
  403. Con::warnf("(TypeFilename) illegal filename detected: %s", data.c_str());
  404. return false;
  405. }
  406. result = String(buffer);
  407. return true;
  408. }
  409. bool default_print(String & result, const FileName & data)
  410. {
  411. result = data;
  412. return true;
  413. }
  414. //-----------------------------------------------------------------------------
  415. // SimObject
  416. //-----------------------------------------------------------------------------
  417. bool default_scan(const String &data, SimObject * & result)
  418. {
  419. result = Sim::findObject(data);
  420. return result != NULL;
  421. }
  422. bool default_print(String & result, SimObject * const & data)
  423. {
  424. if(data)
  425. {
  426. if(String(data->getName()).isEmpty())
  427. result = data->getIdString();
  428. else
  429. result = data->getName();
  430. return true;
  431. }
  432. return false;
  433. }
  434. //-----------------------------------------------------------------------------
  435. // Print scan ints of various sizes as hex
  436. //-----------------------------------------------------------------------------
  437. //-------
  438. // 16 bit
  439. //-------
  440. bool hex_scan(const String & string, U32 & hex)
  441. {
  442. dSscanf(string.c_str(),"%i", &hex);
  443. return true;
  444. }
  445. bool hex_print(String & string, const U32 & hex)
  446. {
  447. string = String::ToString("0x%X",hex);
  448. return true;
  449. }
  450. bool hex_scan(const String & string, S32 & hex)
  451. {
  452. dSscanf(string.c_str(),"%i", &hex);
  453. return true;
  454. }
  455. bool hex_print(String & string, const S32 & hex)
  456. {
  457. string = String::ToString("0x%X",hex);
  458. return true;
  459. }
  460. //-------
  461. // 16 bit
  462. //-------
  463. bool hex_scan(const String & string, U16 & hex)
  464. {
  465. U32 tmp;
  466. bool ret = hex_scan(string,tmp);
  467. hex = tmp;
  468. return ret;
  469. }
  470. bool hex_print(String & string, const U16 & hex)
  471. {
  472. U32 tmp = hex;
  473. return hex_print(string,tmp);
  474. }
  475. bool hex_scan(const String & string, S16 & hex)
  476. {
  477. S32 tmp;
  478. bool ret = hex_scan(string,tmp);
  479. hex = tmp;
  480. return ret;
  481. }
  482. bool hex_print(String & string, const S16 & hex)
  483. {
  484. U32 tmp = hex;
  485. return hex_print(string,tmp);
  486. }
  487. //-------
  488. // 8 bit
  489. //-------
  490. bool hex_scan(const String & string, U8 & hex)
  491. {
  492. U32 tmp;
  493. bool ret = hex_scan(string,tmp);
  494. hex = tmp;
  495. return ret;
  496. }
  497. bool hex_print(String & string, const U8 & hex)
  498. {
  499. U32 tmp = hex;
  500. return hex_print(string,tmp);
  501. }
  502. bool hex_scan(const String & string, S8 & hex)
  503. {
  504. S32 tmp;
  505. bool ret = hex_scan(string,tmp);
  506. hex = tmp;
  507. return ret;
  508. }
  509. bool hex_print(String & string, const S8 & hex)
  510. {
  511. U32 tmp = hex;
  512. return hex_print(string,tmp);
  513. }
  514. }