Chromium Code Reviews| 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 |