Cleanup lua code by introducing lua::functions
[lsnes.git] / src / lua / core.cpp
blob7658b1f46a7526b4efa2e3ca57b391136f658d94
1 #include "core/command.hpp"
2 #include "lua/internal.hpp"
3 #include "core/framerate.hpp"
4 #include "core/moviefile.hpp"
5 #include "core/moviedata.hpp"
6 #include "core/window.hpp"
7 #include "interface/romtype.hpp"
8 #include "library/string.hpp"
9 #include <sstream>
11 namespace
13 std::string luavalue_to_string(lua::state& L, int index, std::set<const void*>& printed, bool quote)
15 switch(L.type(index)) {
16 case LUA_TNONE:
17 return "none";
18 case LUA_TNIL:
19 return "nil";
20 case LUA_TBOOLEAN:
21 return L.toboolean(index) ? "true" : "false";
22 case LUA_TNUMBER:
23 return (stringfmt() << L.tonumber(index)).str();
24 case LUA_TSTRING: {
25 const char* tmp2;
26 size_t len;
27 tmp2 = L.tolstring(index, &len);
28 if(quote)
29 return "\"" + std::string(tmp2, tmp2 + len) + "\"";
30 else
31 return std::string(tmp2, tmp2 + len);
33 case LUA_TLIGHTUSERDATA:
34 return (stringfmt() << "Lightuserdata:" << L.touserdata(index)).str();
35 case LUA_TFUNCTION:
36 return (stringfmt() << "Function:" << L.topointer(index)).str();
37 case LUA_TTHREAD:
38 return (stringfmt() << "Thread:" << L.topointer(index)).str();
39 break;
40 case LUA_TUSERDATA:
41 return (stringfmt() << "Userdata<" << try_recognize_userdata(L, index) << "@"
42 << L.touserdata(index) << ">:[" << try_print_userdata(L, index) << "]").str();
43 case LUA_TTABLE: {
44 //Fun with recursion.
45 const void* ptr = L.topointer(index);
46 if(printed.count(ptr))
47 return (stringfmt() << "<table:" << ptr << ">").str();
48 printed.insert(ptr);
49 std::ostringstream s;
50 s << "<" << ptr << ">{";
51 L.pushnil();
52 bool first = true;
53 while(L.next(index)) {
54 if(!first)
55 s << ", ";
56 int stacktop = L.gettop();
57 s << "[" << luavalue_to_string(L, stacktop - 1, printed, true) << "]="
58 << luavalue_to_string(L, stacktop, printed, true);
59 first = false;
60 L.pop(1);
62 s << "}";
63 return s.str();
65 default:
66 return (stringfmt() << "???:" << L.topointer(index)).str();
70 int identify_class(lua::state& L, lua::parameters& P)
72 if(!P.is_userdata())
73 return 0;
74 L.pushlstring(try_recognize_userdata(L, 1));
75 return 1;
78 int tostringx(lua::state& L, lua::parameters& P)
80 std::set<const void*> tmp2;
81 std::string y = luavalue_to_string(L, 1, tmp2, false);
82 L.pushlstring(y);
83 return 1;
86 int print2(lua::state& L, lua::parameters& P)
88 std::string toprint;
89 bool first = true;
90 while(P.more()) {
91 int i = P.skip();
92 std::set<const void*> tmp2;
93 std::string tmp = luavalue_to_string(L, i, tmp2, false);
94 if(first)
95 toprint = tmp;
96 else
97 toprint = toprint + "\t" + tmp;
98 first = false;
100 platform::message(toprint);
101 return 0;
104 int exec(lua::state& L, lua::parameters& P)
106 std::string text;
108 P(text);
110 lsnes_cmd.invoke(text);
111 return 0;
114 int lookup_class(lua::state& L, lua::parameters& P)
116 std::string clazz;
118 P(clazz);
120 return lua::class_base::lookup_and_push(L, clazz) ? 1 : 0;
123 int all_classes(lua::state& L, lua::parameters& P)
125 auto c = lua::class_base::all_classes(L);
126 int count = 0;
127 for(auto& i : c) {
128 L.pushlstring(i);
129 count++;
131 return count;
134 int emulator_ready(lua::state& L, lua::parameters& P)
136 L.pushboolean(lua_booted_flag ? 1 : 0);
137 return 1;
140 int utime(lua::state& L, lua::parameters& P)
142 uint64_t t = get_utime();
143 L.pushnumber(t / 1000000);
144 L.pushnumber(t % 1000000);
145 return 2;
148 int set_idle_timeout(lua::state& L, lua::parameters& P)
150 uint64_t dt;
152 P(dt);
154 lua_idle_hook_time = get_utime() + dt;
155 return 0;
158 int set_timer_timeout(lua::state& L, lua::parameters& P)
160 uint64_t dt;
162 P(dt);
164 lua_timer_hook_time = get_utime() + dt;
165 return 0;
168 int bus_address(lua::state& L, lua::parameters& P)
170 uint64_t addr;
172 P(addr);
174 auto busrange = our_rom.rtype->get_bus_map();
175 if(!busrange.second)
176 throw std::runtime_error("This platform does not have bus mapping");
177 L.pushnumber(busrange.first + (addr % busrange.second));
178 return 1;
181 int get_lag_flag(lua::state& L, lua::parameters& P)
183 L.pushboolean(!(our_rom.rtype && our_rom.rtype->get_pflag()));
184 return 1;
187 int set_lag_flag(lua::state& L, lua::parameters& P)
189 bool flag;
191 P(flag);
193 if(our_rom.rtype)
194 our_rom.rtype->set_pflag(!flag);
195 return 0;
198 lua::functions misc_fns(lua_func_misc, "", {
199 {"print2", print2},
200 {"exec", exec},
201 {"emulator_ready", emulator_ready},
202 {"utime", utime},
203 {"set_idle_timeout", set_idle_timeout},
204 {"set_timer_timeout", set_timer_timeout},
205 {"bus_address", bus_address},
206 {"memory.get_lag_flag", get_lag_flag},
207 {"memory.set_lag_flag", set_lag_flag},
210 lua::functions pure_fns(lua_func_bit, "", {
211 {"identify_class", identify_class},
212 {"tostringx", tostringx},
213 {"lookup_class", lookup_class},
214 {"all_classes", all_classes},