OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkLua.h" | 8 #include "SkLua.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkPaint.h" | 10 #include "SkPaint.h" |
11 #include "SkPath.h" | 11 #include "SkPath.h" |
12 #include "SkMatrix.h" | 12 #include "SkMatrix.h" |
13 #include "SkRRect.h" | 13 #include "SkRRect.h" |
14 #include "SkString.h" | 14 #include "SkString.h" |
15 | 15 |
16 extern "C" { | 16 extern "C" { |
17 #include "lua.h" | 17 #include "lua.h" |
18 #include "lauxlib.h" | 18 #include "lualib.h" |
19 #include "lauxlib.h" | |
19 } | 20 } |
20 | 21 |
21 static const char gSkCanvas_MTName[] = "SkCanvas_LuaMetaTableName"; | 22 template <typename T> const char* get_mtname(); |
robertphillips
2013/05/22 20:12:36
This is still too much typing
| |
22 static const char gSkMatrix_MTName[] = "SkMatrix_LuaMetaTableName"; | 23 template <> const char* get_mtname<SkCanvas>() { return "SkCanvas_LuaMetaTableNa me"; } |
23 static const char gSkRRect_MTName[] = "SkSkRRect_LuaMetaTableName"; | 24 template <> const char* get_mtname<SkMatrix>() { return "SkMatrix_LuaMetaTableNa me"; } |
24 static const char gSkPath_MTName[] = "SkPath_LuaMetaTableName"; | 25 template <> const char* get_mtname<SkRRect>() { return "SkSkRRect_LuaMetaTableNa me"; } |
25 static const char gSkPaint_MTName[] = "SkPaint_LuaMetaTableName"; | 26 template <> const char* get_mtname<SkPath>() { return "SkPath_LuaMetaTableName"; } |
27 template <> const char* get_mtname<SkPaint>() { return "SkPaint_LuaMetaTableName "; } | |
26 | 28 |
27 static const char* get_mtname(const SkCanvas&) { return gSkCanvas_MTName; } | 29 template <typename T> T* push_new(lua_State* L) { |
28 static const char* get_mtname(const SkMatrix&) { return gSkMatrix_MTName; } | 30 T* addr = (T*)lua_newuserdata(L, sizeof(T)); |
29 static const char* get_mtname(const SkRRect&) { return gSkRRect_MTName; } | 31 new (addr) T; |
30 static const char* get_mtname(const SkPath&) { return gSkPath_MTName; } | 32 luaL_getmetatable(L, get_mtname<T>()); |
31 static const char* get_mtname(const SkPaint&) { return gSkPaint_MTName; } | 33 lua_setmetatable(L, -2); |
34 return addr; | |
35 } | |
32 | 36 |
33 template <typename T> void push_obj(lua_State* L, const T& obj) { | 37 template <typename T> void push_obj(lua_State* L, const T& obj) { |
34 new (lua_newuserdata(L, sizeof(T))) T(obj); | 38 new (lua_newuserdata(L, sizeof(T))) T(obj); |
35 luaL_getmetatable(L, get_mtname(obj)); | 39 luaL_getmetatable(L, get_mtname<T>()); |
36 lua_setmetatable(L, -2); | 40 lua_setmetatable(L, -2); |
37 } | 41 } |
38 | 42 |
39 template <typename T> void push_ref(lua_State* L, T* ref) { | 43 template <typename T> void push_ref(lua_State* L, T* ref) { |
40 *(T**)lua_newuserdata(L, sizeof(T*)) = SkRef(ref); | 44 *(T**)lua_newuserdata(L, sizeof(T*)) = SkRef(ref); |
41 luaL_getmetatable(L, get_mtname(*ref)); | 45 luaL_getmetatable(L, get_mtname<T>()); |
42 lua_setmetatable(L, -2); | 46 lua_setmetatable(L, -2); |
43 } | 47 } |
44 | 48 |
45 template <typename T> T* get_ref(lua_State* L, int index) { | 49 template <typename T> T* get_ref(lua_State* L, int index) { |
46 const T* ref = NULL; | 50 return *(T**)luaL_checkudata(L, index, get_mtname<T>()); |
47 return *(T**)luaL_checkudata(L, index, get_mtname(*ref)); | |
48 } | 51 } |
49 | 52 |
50 template <typename T> T* get_obj(lua_State* L, int index) { | 53 template <typename T> T* get_obj(lua_State* L, int index) { |
51 const T* obj = NULL; | 54 return (T*)luaL_checkudata(L, index, get_mtname<T>()); |
52 return (T*)luaL_checkudata(L, index, get_mtname(*obj)); | |
53 } | 55 } |
54 | 56 |
55 static bool lua2bool(lua_State* L, int index) { | 57 static bool lua2bool(lua_State* L, int index) { |
56 return !!lua_toboolean(L, index); | 58 return !!lua_toboolean(L, index); |
57 } | 59 } |
58 | 60 |
59 /////////////////////////////////////////////////////////////////////////////// | 61 /////////////////////////////////////////////////////////////////////////////// |
60 | 62 |
63 SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) { | |
64 fL = luaL_newstate(); | |
65 luaL_openlibs(fL); | |
66 SkLua::Load(fL); | |
67 } | |
68 | |
69 SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {} | |
70 | |
71 SkLua::~SkLua() { | |
72 if (fWeOwnL) { | |
73 if (fTermCode.size() > 0) { | |
74 lua_getglobal(fL, fTermCode.c_str()); | |
75 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) { | |
76 SkDebugf("lua err: %s\n", lua_tostring(fL, -1)); | |
77 } | |
78 } | |
79 lua_close(fL); | |
80 } | |
81 } | |
82 | |
83 bool SkLua::runCode(const char code[]) { | |
84 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0); | |
85 if (err) { | |
86 SkDebugf("--- lua failed\n"); | |
87 return false; | |
88 } | |
89 return true; | |
90 } | |
91 | |
92 bool SkLua::runCode(const void* code, size_t size) { | |
93 SkString str((const char*)code, size); | |
94 return this->runCode(str.c_str()); | |
95 } | |
96 | |
97 /////////////////////////////////////////////////////////////////////////////// | |
98 | |
99 #define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0) | |
100 | |
61 static void setfield_string(lua_State* L, const char key[], const char value[]) { | 101 static void setfield_string(lua_State* L, const char key[], const char value[]) { |
62 lua_pushstring(L, value); | 102 lua_pushstring(L, value); |
63 lua_setfield(L, -2, key); | 103 lua_setfield(L, -2, key); |
64 } | 104 } |
65 | 105 |
66 static void setfield_number(lua_State* L, const char key[], double value) { | 106 static void setfield_number(lua_State* L, const char key[], double value) { |
67 lua_pushnumber(L, value); | 107 lua_pushnumber(L, value); |
68 lua_setfield(L, -2, key); | 108 lua_setfield(L, -2, key); |
69 } | 109 } |
70 | 110 |
71 SkLua::SkLua(lua_State* L) : fL(L) { | 111 static void setfield_function(lua_State* L, |
72 static bool gOnce; | 112 const char key[], lua_CFunction value) { |
73 if (!gOnce) { | 113 lua_pushcfunction(L, value); |
74 SkLua::Load(L); | 114 lua_setfield(L, -2, key); |
75 gOnce = true; | |
76 } | |
77 } | 115 } |
78 | 116 |
79 SkLua::~SkLua() { | |
80 } | |
81 | |
82 #define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0) | |
83 | |
84 void SkLua::pushBool(bool value, const char key[]) { | 117 void SkLua::pushBool(bool value, const char key[]) { |
85 lua_pushboolean(fL, value); | 118 lua_pushboolean(fL, value); |
86 CHECK_SETFIELD(key); | 119 CHECK_SETFIELD(key); |
87 } | 120 } |
88 | 121 |
89 void SkLua::pushString(const char str[], const char key[]) { | 122 void SkLua::pushString(const char str[], const char key[]) { |
90 lua_pushstring(fL, str); | 123 lua_pushstring(fL, str); |
91 CHECK_SETFIELD(key); | 124 CHECK_SETFIELD(key); |
92 } | 125 } |
93 | 126 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 static int lcanvas_getSaveCount(lua_State* L) { | 250 static int lcanvas_getSaveCount(lua_State* L) { |
218 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount()); | 251 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount()); |
219 return 1; | 252 return 1; |
220 } | 253 } |
221 | 254 |
222 static int lcanvas_getTotalMatrix(lua_State* L) { | 255 static int lcanvas_getTotalMatrix(lua_State* L) { |
223 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix()); | 256 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix()); |
224 return 1; | 257 return 1; |
225 } | 258 } |
226 | 259 |
260 static int lcanvas_translate(lua_State* L) { | |
261 get_ref<SkCanvas>(L, 1)->translate(lua2scalar(L, 2), lua2scalar(L, 3)); | |
262 return 0; | |
263 } | |
264 | |
227 static int lcanvas_gc(lua_State* L) { | 265 static int lcanvas_gc(lua_State* L) { |
228 get_ref<SkCanvas>(L, 1)->unref(); | 266 get_ref<SkCanvas>(L, 1)->unref(); |
229 return 0; | 267 return 0; |
230 } | 268 } |
231 | 269 |
232 static const struct luaL_Reg gSkCanvas_Methods[] = { | 270 static const struct luaL_Reg gSkCanvas_Methods[] = { |
233 { "drawColor", lcanvas_drawColor }, | 271 { "drawColor", lcanvas_drawColor }, |
234 { "drawRect", lcanvas_drawRect }, | 272 { "drawRect", lcanvas_drawRect }, |
235 { "drawOval", lcanvas_drawOval }, | 273 { "drawOval", lcanvas_drawOval }, |
236 { "drawCircle", lcanvas_drawCircle }, | 274 { "drawCircle", lcanvas_drawCircle }, |
237 { "getSaveCount", lcanvas_getSaveCount }, | 275 { "getSaveCount", lcanvas_getSaveCount }, |
238 { "getTotalMatrix", lcanvas_getTotalMatrix }, | 276 { "getTotalMatrix", lcanvas_getTotalMatrix }, |
277 { "translate", lcanvas_translate }, | |
239 { "__gc", lcanvas_gc }, | 278 { "__gc", lcanvas_gc }, |
240 { NULL, NULL } | 279 { NULL, NULL } |
241 }; | 280 }; |
242 | 281 |
243 /////////////////////////////////////////////////////////////////////////////// | 282 /////////////////////////////////////////////////////////////////////////////// |
244 | 283 |
245 static int lpaint_isAntiAlias(lua_State* L) { | 284 static int lpaint_isAntiAlias(lua_State* L) { |
246 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias()); | 285 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias()); |
247 return 1; | 286 return 1; |
248 } | 287 } |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
453 } | 492 } |
454 | 493 |
455 private: | 494 private: |
456 lua_State* fL; | 495 lua_State* fL; |
457 }; | 496 }; |
458 | 497 |
459 #define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb) | 498 #define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb) |
460 | 499 |
461 /////////////////////////////////////////////////////////////////////////////// | 500 /////////////////////////////////////////////////////////////////////////////// |
462 | 501 |
502 static int lsk_newPaint(lua_State* L) { | |
503 push_new<SkPaint>(L); | |
504 return 1; | |
505 } | |
506 | |
507 static int lsk_newPath(lua_State* L) { | |
508 push_new<SkPath>(L); | |
509 return 1; | |
510 } | |
511 | |
512 static int lsk_newRRect(lua_State* L) { | |
513 SkRRect* rr = push_new<SkRRect>(L); | |
514 rr->setEmpty(); | |
515 return 1; | |
516 } | |
517 | |
518 static const struct luaL_Reg gSk_Functions[] = { | |
519 { "newPaint", lsk_newPaint }, | |
520 { "newPath", lsk_newPath }, | |
521 { "newRRect", lsk_newRRect }, | |
522 { NULL, NULL } | |
523 }; | |
524 | |
525 static void register_Sk(lua_State* L) { | |
526 lua_newtable(L); | |
527 lua_pushvalue(L, -1); | |
528 lua_setglobal(L, "Sk"); | |
529 // the Sk table is still on top | |
530 | |
531 setfield_function(L, "newPaint", lsk_newPaint); | |
532 setfield_function(L, "newPath", lsk_newPath); | |
533 setfield_function(L, "newRRect", lsk_newRRect); | |
534 lua_pop(L, 1); // pop off the Sk table | |
535 } | |
536 | |
463 #define REG_CLASS(L, C) \ | 537 #define REG_CLASS(L, C) \ |
464 do { \ | 538 do { \ |
465 luaL_newmetatable(L, g##C##_MTName); \ | 539 luaL_newmetatable(L, get_mtname<C>()); \ |
466 lua_pushvalue(L, -1); \ | 540 lua_pushvalue(L, -1); \ |
467 lua_setfield(L, -2, "__index"); \ | 541 lua_setfield(L, -2, "__index"); \ |
468 luaL_setfuncs(L, g##C##_Methods, 0); \ | 542 luaL_setfuncs(L, g##C##_Methods, 0); \ |
469 lua_pop(L, 1); /* pop off the meta-table */ \ | 543 lua_pop(L, 1); /* pop off the meta-table */ \ |
470 } while (0) | 544 } while (0) |
471 | 545 |
472 void SkLua::Load(lua_State* L) { | 546 void SkLua::Load(lua_State* L) { |
547 register_Sk(L); | |
473 REG_CLASS(L, SkCanvas); | 548 REG_CLASS(L, SkCanvas); |
474 REG_CLASS(L, SkPath); | 549 REG_CLASS(L, SkPath); |
475 REG_CLASS(L, SkPaint); | 550 REG_CLASS(L, SkPaint); |
476 REG_CLASS(L, SkRRect); | 551 REG_CLASS(L, SkRRect); |
477 } | 552 } |
478 | 553 |
OLD | NEW |