Angel 3.2
A 2D Game Prototyping Engine
LuaConsole.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/LuaConsole.h"
32 
33 #include "../Infrastructure/World.h"
34 #include "../Scripting/LuaModule.h"
35 
37 {
38  String motd = String(LUA_COPYRIGHT) + "\n\n";
39  motd += "This console is almost the same as the interactive Lua interpreter. Just make sure not\n";
40  motd += "to run any code that blocks on console input, or the whole engine will hang.\n\n";
41  WriteToOutput(motd);
42 
43  _mainPrompt = "> ";
44  _secondaryPrompt = ">> ";
45  _partialInput.clear();
46  _firstLine = true;
47  _tabWidth = 16; //makes most Lua tables a bit easier to read when they're printed
48  SetPrompt(_mainPrompt);
49 }
50 
51 
52 void LuaConsole::Execute(String input)
53 {
54  lua_State *L = LuaScriptingModule::GetLuaState();
55 
56  WriteToOutput(_prompt + input + "\n");
57 
58  if (_firstLine && input.substr(0,1) == "=")
59  {
60  input = "return tostring(" + input.substr(1, input.length()-1) + ")";
61  }
62 
63  _partialInput += " " + input;
64  _firstLine = false;
65 
66  if (luaL_loadstring(L, _partialInput.c_str()))
67  {
68  String error(lua_tostring(L, -1));
69  lua_pop(L, 1);
70 
71  // this may seem hacky, but it's exactly the same way the official
72  // interpreter does it!
73  if (error.substr(error.length()-6, 5) != "<eof>")
74  {
75  _partialInput.clear();
76  _firstLine = true;
77  WriteToOutput("ERROR: " + error + "\n");
78  SetPrompt(_mainPrompt);
79  }
80  else
81  {
82  SetPrompt(_secondaryPrompt);
83  }
84  return;
85  }
86  else
87  {
88  if (lua_pcall(L, 0, LUA_MULTRET, 0 ) )
89  {
90  // error, will be in the stack trace
91  lua_gc(L, LUA_GCCOLLECT, 0); // garbage collect on error
92  }
93  }
94 
95  // print out any return values left on the stack
96  if (lua_gettop(L) > 0)
97  {
98  lua_getglobal(L, "print");
99  lua_insert(L, 1);
100  lua_pcall(L, lua_gettop(L)-1, 0, 0);
101  }
102 
103  _partialInput.clear();
104  _firstLine = true;
105  SetPrompt(_mainPrompt);
106 
107  lua_settop(L, 0);
108 }
109 
110 
111 StringList LuaConsole::GetCompletions(const String& input)
112 {
113  StringList forReturn;
114 
115  lua_State *L = LuaScriptingModule::GetLuaState();
116  lua_getglobal(L, "getAutoCompletions");
117  lua_pushstring(L, input.c_str());
118  if (lua_pcall(L, 1, 1, 0) != 0)
119  {
120  String out = "ERROR: running autocompletions: ";
121  out += lua_tostring(L, -1);
122  out += "\n";
123  WriteToOutput(out);
124  }
125  if (lua_istable(L, -1))
126  {
127  // get table values
128  int size = lua_rawlen(L, -1);
129  for (int i=0; i < size; i++)
130  {
131  lua_pushinteger(L, i+1);
132  lua_gettable(L, -2);
133  forReturn.push_back(lua_tostring(L, -1));
134  lua_pop(L, 1);
135  }
136  }
137 
138 
139  //pop it
140  lua_pop(L, 1);
141 
142  return forReturn;
143 }
144 
145 void LuaWrite(String output)
146 {
147  LuaConsole* lc = (LuaConsole*)theWorld.GetConsole();
148  lc->WriteToOutput(output + "\n");
149 }