Angel 3.2
A 2D Game Prototyping Engine
LuaModule.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../Scripting/LuaModule.h"
32 
33 #include "../Infrastructure/Common.h"
34 #include "../Messaging/Switchboard.h"
35 #include "../Util/StringUtil.h"
36 #include "../Infrastructure/Log.h"
37 #include "../Infrastructure/World.h"
38 #if !ANGEL_MOBILE
39  #include "../Scripting/LuaConsole.h"
40  #include "../Util/FileUtil.h"
41 #endif
42 
43 extern "C"
44 {
45  int luaopen_angel(lua_State* L);
46 }
47 
48 bool LuaScriptingModule::isInitialized = false;
49 lua_State* LuaScriptingModule::L = NULL;
50 ConfigUpdater* LuaScriptingModule::_configUpdater = NULL;
51 
53 {
54  L = luaL_newstate();
55 
56  lua_gc(L, LUA_GCSTOP, 0);
57  luaL_openlibs(L);
58  luaopen_angel(L);
59  lua_gc(L, LUA_GCRESTART, 0);
60 
61  // need to manually clean up the stack since SWIG is acting funny with Lua 5.1 now.
62  while (lua_gettop(L) > 0)
63  {
64  lua_pop(L, 1);
65  }
66 
67  #if !ANGEL_MOBILE
68  lua_pushboolean(L, 0);
69  lua_setglobal(L, "ANGEL_MOBILE");
70  #else
71  lua_pushboolean(L, 1);
72  lua_setglobal(L, "ANGEL_MOBILE");
73  #endif
74 
75  luaL_dofile(L, "./Resources/Scripts/pref_load.lua");
76 }
77 
79 {
80  #if !ANGEL_MOBILE
81  LuaConsole *lc = new LuaConsole();
82  theWorld.RegisterConsole(lc);
83  #endif
84 
85  int result = luaL_dofile(L, "./Resources/Scripts/start.lua");
86 
87  isInitialized = !result;
88  if (isInitialized)
89  {
90  sysLog.Log("Lua initialized!");
91  }
92  else
93  {
94  sysLog.Log(lua_tostring(L, -1));
95  }
96 
97  _configUpdater = new ConfigUpdater();
98 }
99 
101 {
102  if (!isInitialized)
103  {
104  return;
105  }
106 
107  lua_close(L);
108 }
109 
110 void LuaScriptingModule::ExecuteInScript(const String& code)
111 {
112  if (!isInitialized)
113  {
114  return;
115  }
116 
117  if (luaL_loadstring(L, code.c_str()))
118  {
119  String error(lua_tostring(L, -1));
120  lua_pop(L, 1);
121 
122  if (error.substr(error.length()-6, 5) != "<eof>")
123  {
124  #if !ANGEL_MOBILE
125  theWorld.GetConsole()->WriteToOutput("ERROR: " + error + "\n");
126  #endif
127  }
128  else
129  {
130  // partial input -- do we want to handle this?
131  }
132  return;
133  }
134  else
135  {
136  if (lua_pcall(L, 0, LUA_MULTRET, 0 ))
137  {
138  const char* errs = lua_tostring(L, -1);
139  sysLog.Printf("ERROR: %s\n", errs);
140  // error, will be in the stack trace
141  lua_gc(L, LUA_GCCOLLECT, 0); // garbage collect on error
142  }
143  }
144  // print out any return values left on the stack
145  if (lua_gettop(L) > 0)
146  {
147  lua_getglobal(L, "print");
148  lua_insert(L, 1);
149  lua_pcall(L, lua_gettop(L)-1, 0, 0);
150  }
151 
152  lua_settop(L, 0);
153 }
154 
156 {
157  return L;
158 }
159 
161 {
162  int top = lua_gettop(L);
163 
164  sysLog.Printf("Total in stack: %d\n", top);
165 
166  for (int i=1; i <= top; i++)
167  {
168  int t = lua_type(L, i);
169  switch (t) {
170  case LUA_TSTRING:
171  printf("string: '%s'\n", lua_tostring(L, i));
172  break;
173  case LUA_TBOOLEAN:
174  printf("boolean %s\n",lua_toboolean(L, i) ? "true" : "false");
175  break;
176  case LUA_TNUMBER:
177  printf("number: %g\n", lua_tonumber(L, i));
178  break;
179  default:
180  printf("%s\n", lua_typename(L, t));
181  break;
182  }
183  printf(" ");
184  }
185  printf("\n");
186 }
187 
188 #define TUNING_FILE_CHECK_DELAY 1.0f
189 #define TUNING_MESSAGE_NAME "TuningCheckTick"
190 
191 
192 ConfigUpdater::ConfigUpdater()
193 {
194  Reload();
195 
196  #if !defined(ANGEL_MOBILE)
197  _updateTime = GetModificationTime("Config/tuning.lua");
198  theSwitchboard.SubscribeTo(this, TUNING_MESSAGE_NAME);
199  theSwitchboard.DeferredBroadcast(new Message(TUNING_MESSAGE_NAME), TUNING_FILE_CHECK_DELAY);
200  #endif
201 }
202 
203 void ConfigUpdater::Reload()
204 {
205  lua_State* L = LuaScriptingModule::GetLuaState();
206  lua_getglobal(L, "LoadTuningVariables");
207  if (lua_pcall(L, 0, 0, 0))
208  {
209  const char* errs = lua_tostring(L, -1);
210  sysLog.Printf("ERROR: %s\n", errs);
211  // error, will be in the stack trace
212  lua_gc(L, LUA_GCCOLLECT, 0); // garbage collect on error
213  }
214 }
215 
217 {
218  #if !defined(ANGEL_MOBILE)
219  if (message->GetMessageName() == TUNING_MESSAGE_NAME)
220  {
221  long modTime = GetModificationTime("Config/tuning.lua");
222  if (_updateTime < modTime)
223  {
224  Reload();
225  _updateTime = modTime;
226  }
227  theSwitchboard.DeferredBroadcast(new Message(TUNING_MESSAGE_NAME), TUNING_FILE_CHECK_DELAY);
228  }
229  #endif
230 }