您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

182 行
4.6 KiB

  1. //
  2. // Base Lua class for Lua script loading
  3. //
  4. // Copyright © 2009—2015 Sam Hocevar <sam@hocevar.net>
  5. // © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
  6. //
  7. // Lol Engine is free software. It comes without any warranty, to
  8. // the extent permitted by applicable law. You can redistribute it
  9. // and/or modify it under the terms of the Do What the Fuck You Want
  10. // to Public License, Version 2, as published by the WTFPL Task Force.
  11. // See http://www.wtfpl.net/ for more details.
  12. //
  13. #include <lol/engine-internal.h>
  14. #include <cstring>
  15. #include <cstdlib>
  16. #include <ctype.h>
  17. namespace lol
  18. {
  19. //-----------------------------------------------------------------------------
  20. class LuaBaseData
  21. {
  22. friend class Lolua::Loader;
  23. //PANIC PANIC -------------------------------------------------------------
  24. static int LuaPanic(LuaState* l)
  25. {
  26. char const *message = lua_tostring(l, -1);
  27. msg::error("%s\n", message);
  28. DebugAbort();
  29. return 0;
  30. }
  31. //Exec lua code -----------------------------------------------------------
  32. static int LuaDoCode(LuaState *l, String const& s)
  33. {
  34. int status = luaL_dostring(l, s.C());
  35. if (status == 1)
  36. {
  37. LuaString error; error.Get(l, -1);
  38. msg::error("Lua error %s\n", error().C());
  39. lua_pop(l, 1);
  40. }
  41. return status;
  42. }
  43. //Open a file and exec lua code -------------------------------------------
  44. static int LuaDoFile(LuaState *l)
  45. {
  46. if (lua_isnoneornil(l, 1))
  47. return LUA_ERRFILE;
  48. LuaCharPtr var; var.Get(l, 1);
  49. char const *filename = var;// lua_tostring(l, 1);
  50. int status = LUA_ERRFILE;
  51. File f;
  52. for (auto candidate : System::GetPathList(filename))
  53. {
  54. f.Open(candidate, FileAccess::Read);
  55. if (f.IsValid())
  56. {
  57. String s = f.ReadString();
  58. f.Close();
  59. msg::debug("loading Lua file %s\n", candidate.C());
  60. status = LuaDoCode(l, s);
  61. break;
  62. }
  63. }
  64. if (status == LUA_ERRFILE)
  65. msg::error("could not find Lua file %s\n", filename);
  66. else if (status == 1)
  67. {
  68. LuaString error; error.Get(l, -1);
  69. msg::error("Lua error %s\n", error().C());
  70. lua_pop(l, 1);
  71. }
  72. lua_pop(l, 1);
  73. return status;
  74. }
  75. };
  76. namespace Lolua
  77. {
  78. //-----------------------------------------------------------------------------
  79. Loader::Loader()
  80. {
  81. m_lua_state = luaL_newstate();
  82. lua_atpanic(m_lua_state, LuaBaseData::LuaPanic);
  83. luaL_openlibs(m_lua_state);
  84. /* Override dofile() */
  85. LuaFunction do_file(m_lua_state, "dofile", LuaBaseData::LuaDoFile);
  86. //Store this instance
  87. Loader::Store(m_lua_state, this);
  88. }
  89. //-----------------------------------------------------------------------------
  90. Loader::~Loader()
  91. {
  92. //Release this instance
  93. Loader::Release(m_lua_state, this);
  94. lua_close(m_lua_state);
  95. }
  96. //Store loader ------------------------------------------------------------
  97. static array<LuaState*, Lolua::Loader*> g_loaders;
  98. void Loader::Store(LuaState* l, Lolua::Loader* loader)
  99. {
  100. g_loaders.push(l, loader);
  101. }
  102. void Loader::Release(LuaState* l, Lolua::Loader* loader)
  103. {
  104. for (int i = 0; i < g_loaders.count(); ++i)
  105. {
  106. if (g_loaders[i].m1 == l && g_loaders[i].m2 == loader)
  107. {
  108. g_loaders.remove(i);
  109. return;
  110. }
  111. }
  112. }
  113. Lolua::Loader *LuaLoader::Find(LuaState* l)
  114. {
  115. for (int i = 0; i < g_loaders.count(); ++i)
  116. if (g_loaders[i].m1 == l)
  117. return g_loaders[i].m2;
  118. return nullptr;
  119. }
  120. //Store lua object --------------------------------------------------------
  121. void Loader::StoreObject(LuaState* l, Object* obj)
  122. {
  123. for (auto loader : g_loaders)
  124. {
  125. if (loader.m1 == l)
  126. {
  127. loader.m2->Store(obj);
  128. return;
  129. }
  130. }
  131. }
  132. //-----------------------------------------------------------------------------
  133. bool Loader::ExecLuaFile(String const &lua)
  134. {
  135. const char* c = lua_pushstring(m_lua_state, lua.C());
  136. int status = LuaBaseData::LuaDoFile(m_lua_state);
  137. return status == 0;
  138. }
  139. //-----------------------------------------------------------------------------
  140. bool Loader::ExecLuaCode(String const &lua)
  141. {
  142. return 0 == LuaBaseData::LuaDoCode(m_lua_state, lua);
  143. }
  144. //-----------------------------------------------------------------------------
  145. LuaState* Loader::GetLuaState()
  146. {
  147. return m_lua_state;
  148. }
  149. } /* namespace Lolua */
  150. } /* namespace lol */