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