SampleLua.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright 2013 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkData.h"
  9. #include "include/utils/SkLua.h"
  10. #include "samplecode/Sample.h"
  11. #include "tools/Resources.h"
  12. extern "C" {
  13. #include "lua.h"
  14. #include "lualib.h"
  15. #include "lauxlib.h"
  16. }
  17. //#define LUA_FILENAME "lua/test.lua"
  18. #define LUA_FILENAME "lua/slides.lua"
  19. static const char gDrawName[] = "onDrawContent";
  20. static const char gClickName[] = "onClickHandler";
  21. static const char gUnicharName[] = "onCharHandler";
  22. static const char gMissingCode[] = ""
  23. "local paint = Sk.newPaint()"
  24. "paint:setAntiAlias(true)"
  25. "paint:setTextSize(30)"
  26. ""
  27. "function onDrawContent(canvas)"
  28. " canvas:drawText('missing \"test.lua\"', 20, 50, paint)"
  29. "end"
  30. ;
  31. class LuaView : public Sample {
  32. public:
  33. LuaView() : fLua(nullptr) {}
  34. ~LuaView() override { delete fLua; }
  35. void setImageFilename(lua_State* L) {
  36. SkString str = GetResourcePath("images/mandrill_256.png");
  37. lua_getglobal(L, "setImageFilename");
  38. if (lua_isfunction(L, -1)) {
  39. fLua->pushString(str.c_str());
  40. if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
  41. SkDebugf("lua err: %s\n", lua_tostring(L, -1));
  42. }
  43. }
  44. }
  45. lua_State* ensureLua() {
  46. if (nullptr == fLua) {
  47. fLua = new SkLua;
  48. sk_sp<SkData> data = GetResourceAsData(LUA_FILENAME);
  49. if (data) {
  50. fLua->runCode(data->data(), data->size());
  51. this->setImageFilename(fLua->get());
  52. } else {
  53. fLua->runCode(gMissingCode);
  54. }
  55. }
  56. return fLua->get();
  57. }
  58. protected:
  59. SkString name() override { return SkString("Lua"); }
  60. bool onChar(SkUnichar uni) override {
  61. lua_State* L = this->ensureLua();
  62. lua_getglobal(L, gUnicharName);
  63. if (lua_isfunction(L, -1)) {
  64. SkString str;
  65. str.appendUnichar(uni);
  66. fLua->pushString(str.c_str());
  67. if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
  68. SkDebugf("lua err: %s\n", lua_tostring(L, -1));
  69. } else {
  70. if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
  71. return true;
  72. }
  73. }
  74. }
  75. return false;
  76. }
  77. void onDrawContent(SkCanvas* canvas) override {
  78. lua_State* L = this->ensureLua();
  79. lua_getglobal(L, gDrawName);
  80. if (!lua_isfunction(L, -1)) {
  81. int t = lua_type(L, -1);
  82. SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t);
  83. lua_pop(L, 1);
  84. } else {
  85. // does it make sense to try to "cache" the lua version of this
  86. // canvas between draws?
  87. fLua->pushCanvas(canvas);
  88. fLua->pushScalar(this->width());
  89. fLua->pushScalar(this->height());
  90. if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
  91. SkDebugf("lua err: %s\n", lua_tostring(L, -1));
  92. }
  93. }
  94. }
  95. virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
  96. ModifierKey modi) override {
  97. lua_State* L = this->ensureLua();
  98. lua_getglobal(L, gClickName);
  99. if (lua_isfunction(L, -1)) {
  100. fLua->pushScalar(x);
  101. fLua->pushScalar(y);
  102. fLua->pushString("down");
  103. if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
  104. SkDebugf("lua err: %s\n", lua_tostring(L, -1));
  105. } else {
  106. if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
  107. return new Click();
  108. }
  109. }
  110. }
  111. return this->INHERITED::onFindClickHandler(x, y, modi);
  112. }
  113. bool onClick(Click* click) override {
  114. const char* state = nullptr;
  115. switch (click->fState) {
  116. case InputState::kMove:
  117. state = "moved";
  118. break;
  119. case InputState::kUp:
  120. state = "up";
  121. break;
  122. default:
  123. break;
  124. }
  125. if (state) {
  126. lua_State* L = fLua->get();
  127. lua_getglobal(L, gClickName);
  128. fLua->pushScalar(click->fCurr.x());
  129. fLua->pushScalar(click->fCurr.y());
  130. fLua->pushString(state);
  131. lua_pcall(L, 3, 1, 0);
  132. return lua_isboolean(L, -1) && lua_toboolean(L, -1);
  133. }
  134. return true;
  135. }
  136. private:
  137. SkLua* fLua;
  138. typedef Sample INHERITED;
  139. };
  140. //////////////////////////////////////////////////////////////////////////////
  141. DEF_SAMPLE( return new LuaView(); )