Variant.pkg 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. $#include "Core/Variant.h"
  2. $#include "IO/VectorBuffer.h"
  3. enum VariantType
  4. {
  5. VAR_NONE = 0,
  6. VAR_INT,
  7. VAR_BOOL,
  8. VAR_FLOAT,
  9. VAR_VECTOR2,
  10. VAR_VECTOR3,
  11. VAR_VECTOR4,
  12. VAR_QUATERNION,
  13. VAR_COLOR,
  14. VAR_STRING,
  15. VAR_BUFFER,
  16. VAR_VOIDPTR,
  17. VAR_RESOURCEREF,
  18. VAR_RESOURCEREFLIST,
  19. VAR_VARIANTVECTOR,
  20. VAR_VARIANTMAP,
  21. VAR_INTRECT,
  22. VAR_INTVECTOR2,
  23. VAR_PTR,
  24. VAR_MATRIX3,
  25. VAR_MATRIX3X4,
  26. VAR_MATRIX4,
  27. VAR_DOUBLE,
  28. VAR_STRINGVECTOR,
  29. MAX_VAR_TYPES
  30. };
  31. struct ResourceRef
  32. {
  33. ResourceRef();
  34. ResourceRef(StringHash type);
  35. ResourceRef(StringHash type, String name);
  36. ResourceRef(const ResourceRef& rhs);
  37. ~ResourceRef();
  38. StringHash type_ @ type;
  39. String name_ @ name;
  40. bool operator ==(const ResourceRef& rhs) const;
  41. };
  42. struct ResourceRefList
  43. {
  44. ResourceRefList();
  45. ResourceRefList(StringHash type);
  46. ~ResourceRefList();
  47. StringHash type_ @ type;
  48. bool operator ==(const ResourceRefList& rhs) const;
  49. };
  50. class Variant
  51. {
  52. static void _Setup(const char* type);
  53. Variant();
  54. //NOTE: do not change the constructor overloads order without also changing the special case handling below
  55. Variant(const Vector<Variant>& value); // VariantVector and StringVector are special cases as they are converted to Lua tables
  56. Variant(const Vector<String>& value);
  57. Variant(void* value); // Non-specific types must be declared first so that they get considered last
  58. Variant(RefCounted* value);
  59. Variant(int value);
  60. Variant(unsigned value);
  61. Variant(const StringHash& value);
  62. Variant(bool value);
  63. Variant(float value);
  64. Variant(double value);
  65. Variant(const Vector2& value);
  66. Variant(const Vector3& value);
  67. Variant(const Vector4& value);
  68. Variant(const Quaternion& value);
  69. Variant(const Color& value);
  70. Variant(const String value);
  71. Variant(const char* value);
  72. Variant(const PODVector<unsigned char>& value);
  73. Variant(const VectorBuffer& value);
  74. Variant(const ResourceRef& value);
  75. Variant(const ResourceRefList& value);
  76. Variant(const VariantMap& value);
  77. Variant(const IntRect& value);
  78. Variant(const IntVector2& value);
  79. Variant(const Matrix3& value);
  80. Variant(const Matrix3x4& value);
  81. Variant(const Matrix4& value);
  82. Variant(const String type, const String value);
  83. Variant(VariantType type, const String value);
  84. Variant(const char* type, const char* value);
  85. Variant(VariantType type, const char* value);
  86. Variant(const Variant& value);
  87. ~Variant();
  88. void Clear();
  89. bool operator ==(void* rhs) const;
  90. bool operator ==(RefCounted* rhs) const;
  91. bool operator ==(const Variant& rhs) const;
  92. bool operator ==(int rhs) const;
  93. bool operator ==(unsigned rhs) const;
  94. bool operator ==(bool rhs) const;
  95. bool operator ==(float rhs) const;
  96. bool operator ==(double rhs) const;
  97. bool operator ==(const Vector2& rhs);
  98. bool operator ==(const Vector3& rhs) const;
  99. bool operator ==(const Vector4& rhs) const;
  100. bool operator ==(const Quaternion& rhs) const;
  101. bool operator ==(const Color& rhs) const;
  102. bool operator ==(const String rhs) const;
  103. bool operator ==(const PODVector<unsigned char>& rhs) const;
  104. bool operator ==(const VectorBuffer& rhs) const;
  105. bool operator ==(const ResourceRef& rhs) const;
  106. bool operator ==(const ResourceRefList& rhs) const;
  107. bool operator ==(const Vector<Variant>& rhs) const;
  108. bool operator ==(const Vector<String>& rhs) const;
  109. bool operator ==(const VariantMap& rhs) const;
  110. bool operator ==(const IntRect& rhs) const;
  111. bool operator ==(const IntVector2& rhs) const;
  112. bool operator ==(const StringHash& rhs) const;
  113. bool operator ==(const Matrix3& rhs) const;
  114. bool operator ==(const Matrix3x4& rhs) const;
  115. bool operator ==(const Matrix4& rhs) const;
  116. int GetInt() const;
  117. unsigned GetUInt() const;
  118. StringHash GetStringHash();
  119. bool GetBool() const;
  120. float GetFloat() const;
  121. double GetDouble() const;
  122. const Vector2& GetVector2() const;
  123. const Vector3& GetVector3() const;
  124. const Vector4& GetVector4() const;
  125. const Quaternion& GetQuaternion() const;
  126. const Color& GetColor() const;
  127. const String GetString() const;
  128. const PODVector<unsigned char>& GetBuffer @ GetRawBuffer() const;
  129. const VectorBuffer GetVectorBuffer @ GetBuffer() const; // For backward compatibility reason, keep the old alias
  130. void* GetVoidPtr(const char* type) const;
  131. const ResourceRef& GetResourceRef() const;
  132. const ResourceRefList& GetResourceRefList() const;
  133. const Vector<Variant>& GetVariantVector() const;
  134. const VariantMap& GetVariantMap() const;
  135. const Vector<String>& GetStringVector() const;
  136. const IntRect& GetIntRect() const;
  137. const IntVector2& GetIntVector2() const;
  138. RefCounted* GetPtr(const char* type) const;
  139. const Matrix3& GetMatrix3() const;
  140. const Matrix3x4& GetMatrix3x4() const;
  141. const Matrix4& GetMatrix4() const;
  142. VariantType GetType() const;
  143. String GetTypeName() const;
  144. String ToString() const;
  145. bool IsZero() const;
  146. bool IsEmpty() const;
  147. tolua_readonly tolua_property__get_set VariantType type;
  148. tolua_readonly tolua_property__get_set String typeName;
  149. tolua_readonly tolua_property__is_set bool zero;
  150. tolua_readonly tolua_property__is_set bool empty;
  151. };
  152. $[
  153. -- Call the setup method and then hide it immediately
  154. Variant:_Setup("Variant")
  155. Variant:_Setup("const Variant")
  156. Variant._Setup = nil
  157. $]
  158. ${
  159. static int VariantToStringEventHandler(lua_State* tolua_S)
  160. {
  161. lua_pushstring(tolua_S, static_cast<Variant*>(tolua_tousertype(tolua_S, -1, 0))->ToString().CString());
  162. return 1;
  163. }
  164. static int VariantConcatEventHandler(lua_State* tolua_S)
  165. {
  166. // __concat event handler has two operands, check whether the first operand is variant or the second is (one of them must be)
  167. // This event handler has two code branches to handle both cases differently based on the isFirst flag
  168. // In case of both operands are variant then the handler handles the case as if it is isFirst case then below lua_concat() call
  169. // would in turn trigger the handler the second time to handle the second operand using the !isFirst code branch
  170. bool isFirst = lua_isuserdata(tolua_S, 1);
  171. if (isFirst)
  172. lua_pushvalue(tolua_S, 1); // isFirst stack: variant1 operand2 variant1
  173. VariantToStringEventHandler(tolua_S); // isFirst stack: variant1 operand2 variant1 string1 | !isFirst: operand1 variant2 string2
  174. if (isFirst)
  175. {
  176. lua_replace(tolua_S, 1); // isFirst stack: string1 operand2 variant1
  177. lua_pop(tolua_S, 1); // isFirst stack: string1 operand2
  178. }
  179. else
  180. lua_remove(tolua_S, -2); // !isFirst stack: operand1 string2
  181. lua_concat(tolua_S, 2);
  182. return 1;
  183. }
  184. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant__Setup00
  185. static int tolua_CoreLuaAPI_Variant__Setup00(lua_State* tolua_S)
  186. {
  187. // Register our own version of metamethod to handle __tostring and __concat events
  188. luaL_getmetatable(tolua_S, tolua_tostring(tolua_S, 2, 0));
  189. lua_pushstring(tolua_S, "__tostring");
  190. lua_pushcfunction(tolua_S, VariantToStringEventHandler);
  191. lua_rawset(tolua_S, -3);
  192. lua_pushstring(tolua_S, "__concat");
  193. lua_pushcfunction(tolua_S, VariantConcatEventHandler);
  194. lua_rawset(tolua_S, -3);
  195. lua_pop(tolua_S, 1);
  196. return 0;
  197. }
  198. // NOTE: the index number must match with the above variant constructor overloads order)
  199. // Special cases handling for converted VariantVector and StringVector as Lua table
  200. // The auto-generated code are almost correct, except for the tolua_isnoobj() always return false for third index,
  201. // probably due to another tolua++ bug not setting the stack correctly, instead of noobj, 3rd index contains first table member
  202. // Forward declaration
  203. static int tolua_CoreLuaAPI_Variant_new00(lua_State* tolua_S);
  204. static int tolua_CoreLuaAPI_Variant_new00_local(lua_State* tolua_S);
  205. // Correct auto-generated code
  206. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new01
  207. static int tolua_CoreLuaAPI_Variant_new01(lua_State* tolua_S)
  208. {
  209. tolua_Error tolua_err;
  210. if (
  211. !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
  212. (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<Variant>(tolua_S,2,"const Vector<Variant>",0,&tolua_err)) /*||
  213. !tolua_isnoobj(tolua_S,3,&tolua_err)*/
  214. )
  215. goto tolua_lerror;
  216. else
  217. {
  218. const Vector<Variant>* value = ((const Vector<Variant>*) ToluaToVector<Variant>(tolua_S,2,0));
  219. {
  220. Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
  221. tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
  222. }
  223. }
  224. return 1;
  225. tolua_lerror:
  226. return tolua_CoreLuaAPI_Variant_new00(tolua_S);
  227. }
  228. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new01_local
  229. static int tolua_CoreLuaAPI_Variant_new01_local(lua_State* tolua_S)
  230. {
  231. tolua_Error tolua_err;
  232. if (
  233. !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
  234. (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<Variant>(tolua_S,2,"const Vector<Variant>",0,&tolua_err)) /*||
  235. !tolua_isnoobj(tolua_S,3,&tolua_err)*/
  236. )
  237. goto tolua_lerror;
  238. else
  239. {
  240. const Vector<Variant>* value = ((const Vector<Variant>*) ToluaToVector<Variant>(tolua_S,2,0));
  241. {
  242. Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
  243. tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
  244. tolua_register_gc(tolua_S,lua_gettop(tolua_S));
  245. }
  246. }
  247. return 1;
  248. tolua_lerror:
  249. return tolua_CoreLuaAPI_Variant_new00_local(tolua_S);
  250. }
  251. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new02
  252. static int tolua_CoreLuaAPI_Variant_new02(lua_State* tolua_S)
  253. {
  254. tolua_Error tolua_err;
  255. if (
  256. !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
  257. (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<String>(tolua_S,2,"const Vector<String>",0,&tolua_err)) /*||
  258. !tolua_isnoobj(tolua_S,3,&tolua_err)*/
  259. )
  260. goto tolua_lerror;
  261. else
  262. {
  263. const Vector<String>* value = ((const Vector<String>*) ToluaToVector<String>(tolua_S,2,0));
  264. {
  265. Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
  266. tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
  267. }
  268. }
  269. return 1;
  270. tolua_lerror:
  271. return tolua_CoreLuaAPI_Variant_new01(tolua_S);
  272. }
  273. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_new02_local
  274. static int tolua_CoreLuaAPI_Variant_new02_local(lua_State* tolua_S)
  275. {
  276. tolua_Error tolua_err;
  277. if (
  278. !tolua_isusertable(tolua_S,1,"Variant",0,&tolua_err) ||
  279. (tolua_isvaluenil(tolua_S,2,&tolua_err) || !ToluaIsVector<String>(tolua_S,2,"const Vector<String>",0,&tolua_err)) /*||
  280. !tolua_isnoobj(tolua_S,3,&tolua_err)*/
  281. )
  282. goto tolua_lerror;
  283. else
  284. {
  285. const Vector<String>* value = ((const Vector<String>*) ToluaToVector<String>(tolua_S,2,0));
  286. {
  287. Variant* tolua_ret = (Variant*) Mtolua_new((Variant)(*value));
  288. tolua_pushusertype(tolua_S,(void*)tolua_ret,"Variant");
  289. tolua_register_gc(tolua_S,lua_gettop(tolua_S));
  290. }
  291. }
  292. return 1;
  293. tolua_lerror:
  294. return tolua_CoreLuaAPI_Variant_new01_local(tolua_S);
  295. }
  296. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_GetVoidPtr00
  297. static int tolua_CoreLuaAPI_Variant_GetVoidPtr00(lua_State* tolua_S)
  298. {
  299. #ifndef TOLUA_RELEASE
  300. tolua_Error tolua_err;
  301. if (
  302. !tolua_isusertype(tolua_S,1,"const Variant",0,&tolua_err) ||
  303. !tolua_isstring(tolua_S,2,0,&tolua_err) ||
  304. !tolua_isnoobj(tolua_S,3,&tolua_err)
  305. )
  306. goto tolua_lerror;
  307. else
  308. #endif
  309. {
  310. const Variant* self = (const Variant*) tolua_tousertype(tolua_S,1,0);
  311. const char* type = ((const char*) tolua_tostring(tolua_S,2,0));
  312. #ifndef TOLUA_RELEASE
  313. if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetVoidPtr'", NULL);
  314. #endif
  315. {
  316. void* tolua_ret = self->GetVoidPtr();
  317. tolua_pushusertype(tolua_S, tolua_ret, type);
  318. }
  319. }
  320. return 1;
  321. #ifndef TOLUA_RELEASE
  322. tolua_lerror:
  323. tolua_error(tolua_S,"#ferror in function 'GetVoidPtr'.",&tolua_err);
  324. return 0;
  325. #endif
  326. }
  327. #define TOLUA_DISABLE_tolua_CoreLuaAPI_Variant_GetPtr00
  328. static int tolua_CoreLuaAPI_Variant_GetPtr00(lua_State* tolua_S)
  329. {
  330. #ifndef TOLUA_RELEASE
  331. tolua_Error tolua_err;
  332. if (
  333. !tolua_isusertype(tolua_S,1,"const Variant",0,&tolua_err) ||
  334. !tolua_isstring(tolua_S,2,1,&tolua_err) ||
  335. !tolua_isnoobj(tolua_S,3,&tolua_err)
  336. )
  337. goto tolua_lerror;
  338. else
  339. #endif
  340. {
  341. const Variant* self = (const Variant*) tolua_tousertype(tolua_S,1,0);
  342. const char* type = ((const char*) tolua_tostring(tolua_S,2,0));
  343. #ifndef TOLUA_RELEASE
  344. if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPtr'", NULL);
  345. #endif
  346. {
  347. RefCounted* tolua_ret = self->GetPtr();
  348. tolua_pushusertype(tolua_S, (void*)tolua_ret, type);
  349. }
  350. }
  351. return 1;
  352. #ifndef TOLUA_RELEASE
  353. tolua_lerror:
  354. tolua_error(tolua_S,"#ferror in function 'GetPtr'.",&tolua_err);
  355. return 0;
  356. #endif
  357. }
  358. $}
  359. class VariantMap
  360. {
  361. static void _Setup(const char* type);
  362. VariantMap();
  363. ~VariantMap();
  364. };
  365. $[
  366. VariantMap:_Setup("VariantMap")
  367. VariantMap:_Setup("const VariantMap")
  368. VariantMap._Setup = nil
  369. $]
  370. ${
  371. static int VariantMapIndexEventHandler(lua_State* tolua_S)
  372. {
  373. int t = lua_type(tolua_S, 2);
  374. StringHash key;
  375. if (t == LUA_TSTRING)
  376. key = StringHash(lua_tostring(tolua_S, 2));
  377. else if (t == LUA_TNUMBER)
  378. key = StringHash((unsigned)lua_tonumber(tolua_S, 2));
  379. else
  380. {
  381. lua_pushnil(tolua_S);
  382. return 1;
  383. }
  384. Variant* variant = static_cast<const VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key);
  385. if (variant)
  386. tolua_pushusertype(tolua_S, variant, "Variant");
  387. else
  388. lua_pushnil(tolua_S);
  389. return 1;
  390. }
  391. static int VariantMapNewIndexEventHandler(lua_State* tolua_S)
  392. {
  393. int t = lua_type(tolua_S, 2);
  394. StringHash key;
  395. if (t == LUA_TSTRING)
  396. key = StringHash(lua_tostring(tolua_S, 2));
  397. else if (t == LUA_TNUMBER)
  398. key = StringHash((unsigned)lua_tonumber(tolua_S, 2));
  399. else
  400. return 0;
  401. Variant& variant = static_cast<VariantMap*>(tolua_tousertype(tolua_S, 1, 0))->operator [](key); // autovivification
  402. switch (lua_type(tolua_S, 3)) // Use the type of lua object to determine the final variant type
  403. {
  404. case LUA_TNIL:
  405. variant = Variant::EMPTY;
  406. break;
  407. case LUA_TBOOLEAN:
  408. variant = (bool)lua_toboolean(tolua_S, 3); // Still need to cast to bool as Lua/LuaJIT return it as int
  409. break;
  410. case LUA_TNUMBER:
  411. {
  412. // Use the original variant type to further determine the final variant type
  413. // CAVEAT: if lhs has integral data type and double is desired then lhs needs to be reset first before assigning
  414. double value = lua_tonumber(tolua_S, 3);
  415. switch (variant.GetType())
  416. {
  417. case VAR_INT:
  418. variant = (int)value;
  419. break;
  420. case VAR_BOOL:
  421. variant = value != 0.0f;
  422. break;
  423. case VAR_FLOAT:
  424. variant = (float)value;
  425. break;
  426. default:
  427. variant = value;
  428. }
  429. }
  430. break;
  431. case LUA_TSTRING:
  432. variant = lua_tostring(tolua_S, 3);
  433. break;
  434. case LUA_TUSERDATA:
  435. {
  436. if (lua_getmetatable(tolua_S, 3))
  437. {
  438. lua_rawget(tolua_S, LUA_REGISTRYINDEX); // registry[mt]
  439. const char* typeName = lua_tostring(tolua_S, -1);
  440. lua_pop(tolua_S, 1);
  441. void* value = tolua_tousertype(tolua_S, 3, 0);
  442. switch (Variant::GetTypeFromName(typeName))
  443. {
  444. case VAR_NONE:
  445. // Handle special cases
  446. if (typeName)
  447. {
  448. tolua_Error error;
  449. if (strcmp(typeName, "Variant") == 0)
  450. variant = *static_cast<Variant*>(value);
  451. else if (strcmp(typeName, "VectorBuffer") == 0)
  452. variant = *static_cast<VectorBuffer*>(value);
  453. else if (tolua_isusertype(tolua_S, 3, "RefCounted", 0, &error))
  454. variant = static_cast<RefCounted*>(value);
  455. else
  456. variant = value; // void*
  457. }
  458. break;
  459. case VAR_VECTOR2:
  460. variant = *static_cast<Vector2*>(value);
  461. break;
  462. case VAR_VECTOR3:
  463. variant = *static_cast<Vector3*>(value);
  464. break;
  465. case VAR_VECTOR4:
  466. variant = *static_cast<Vector4*>(value);
  467. break;
  468. case VAR_QUATERNION:
  469. variant = *static_cast<Quaternion*>(value);
  470. break;
  471. case VAR_COLOR:
  472. variant = *static_cast<Color*>(value);
  473. break;
  474. case VAR_INTRECT:
  475. variant = *static_cast<IntRect*>(value);
  476. break;
  477. case VAR_INTVECTOR2:
  478. variant = *static_cast<IntVector2*>(value);
  479. break;
  480. case VAR_MATRIX3:
  481. variant = *static_cast<Matrix3*>(value);
  482. break;
  483. case VAR_MATRIX3X4:
  484. variant = *static_cast<Matrix3x4*>(value);
  485. break;
  486. case VAR_MATRIX4:
  487. variant = *static_cast<Matrix4*>(value);
  488. break;
  489. case VAR_RESOURCEREF:
  490. variant = *static_cast<ResourceRef*>(value);
  491. break;
  492. case VAR_RESOURCEREFLIST:
  493. variant = *static_cast<ResourceRefList*>(value);
  494. break;
  495. case VAR_VARIANTMAP:
  496. variant = *static_cast<VariantMap*>(value);
  497. break;
  498. default: break;
  499. }
  500. };
  501. }
  502. break;
  503. case LUA_TTABLE:
  504. {
  505. tolua_Error error;
  506. if (ToluaIsPODVector<unsigned char>(0.f, tolua_S, 3, "unsigned char", 0, &error))
  507. variant = *static_cast<PODVector<unsigned char>*>(ToluaToPODVector<unsigned char>(0.f, tolua_S, 3, 0));
  508. else if (ToluaIsVector<Variant>(tolua_S, 3, "Variant", 0, &error))
  509. variant = *static_cast<VariantVector*>(ToluaToVector<Variant>(tolua_S, 3, 0));
  510. else if (ToluaIsVector<String>(tolua_S, 3, "String", 0, &error))
  511. variant = *static_cast<StringVector*>(ToluaToVector<String>(tolua_S, 3, 0));
  512. }
  513. break;
  514. default: break;
  515. }
  516. return 0;
  517. }
  518. #define TOLUA_DISABLE_tolua_CoreLuaAPI_VariantMap__Setup00
  519. static int tolua_CoreLuaAPI_VariantMap__Setup00(lua_State* tolua_S)
  520. {
  521. // Register our own version of metamethod to handle __index and __newindex events
  522. luaL_getmetatable(tolua_S, tolua_tostring(tolua_S, 2, 0));
  523. lua_pushstring(tolua_S, "__index");
  524. lua_pushcfunction(tolua_S, VariantMapIndexEventHandler);
  525. lua_rawset(tolua_S, -3);
  526. lua_pushstring(tolua_S, "__newindex");
  527. lua_pushcfunction(tolua_S, VariantMapNewIndexEventHandler);
  528. lua_rawset(tolua_S, -3);
  529. lua_pop(tolua_S, 1);
  530. return 0;
  531. }
  532. $}