Lua: Convert some functions to static-only classes

This commit is contained in:
Ilari Liusvaara 2014-01-29 13:09:00 +02:00
parent 02eed4668c
commit 1fd5a490bf
7 changed files with 188 additions and 117 deletions

View file

@ -5,25 +5,28 @@
namespace namespace
{ {
lua::fnptr2 kbind(lua_func_misc, "keyboard.bind", [](lua::state& L, lua::parameters& P) -> int { int kbd_bind(lua::state& L, lua::parameters& P)
{
std::string mod, mask, key, cmd; std::string mod, mask, key, cmd;
P(mod, mask, key, cmd); P(mod, mask, key, cmd);
lsnes_mapper.bind(mod, mask, key, cmd); lsnes_mapper.bind(mod, mask, key, cmd);
return 0; return 0;
}); }
lua::fnptr2 kunbind(lua_func_misc, "keyboard.unbind", [](lua::state& L, lua::parameters& P) -> int { int kbd_unbind(lua::state& L, lua::parameters& P)
{
std::string mod, mask, key; std::string mod, mask, key;
P(mod, mask, key); P(mod, mask, key);
lsnes_mapper.unbind(mod, mask, key); lsnes_mapper.unbind(mod, mask, key);
return 0; return 0;
}); }
lua::fnptr2 kalias(lua_func_misc, "keyboard.alias", [](lua::state& L, lua::parameters& P) -> int { int kbd_alias(lua::state& L, lua::parameters& P)
{
std::string alias, cmds; std::string alias, cmds;
P(alias, cmds); P(alias, cmds);
@ -31,5 +34,12 @@ namespace
lsnes_cmd.set_alias_for(alias, cmds); lsnes_cmd.set_alias_for(alias, cmds);
refresh_alias_binds(); refresh_alias_binds();
return 0; return 0;
}
class lua_keyboard_dummy {};
lua::_class<lua_keyboard_dummy> lua_kbd(lua_class_bind, "*keyboard", {
{"bind", kbd_bind},
{"unbind", kbd_unbind},
{"alias", kbd_alias},
}); });
} }

View file

@ -102,7 +102,8 @@ namespace
return 1; return 1;
} }
lua::fnptr2 lua_bextract(lua_func_bit, "bit.extract", [](lua::state& L, lua::parameters& P) -> int { int bit_extract(lua::state& L, lua::parameters& P)
{
uint64_t ret = 0; uint64_t ret = 0;
uint64_t num; uint64_t num;
@ -119,9 +120,10 @@ namespace
} }
L.pushnumber(ret); L.pushnumber(ret);
return 1; return 1;
}); }
lua::fnptr2 lua_bvalue(lua_func_bit, "bit.value", [](lua::state& L, lua::parameters& P) -> int { int bit_value(lua::state& L, lua::parameters& P)
{
uint64_t ret = 0; uint64_t ret = 0;
for(size_t i = 0;; i++) { for(size_t i = 0;; i++) {
if(P.is_number()) { if(P.is_number()) {
@ -132,25 +134,20 @@ namespace
} }
L.pushnumber(ret); L.pushnumber(ret);
return 1; return 1;
}); }
lua::fnptr2 lua_testany(lua_func_bit, "bit.test_any", [](lua::state& L, lua::parameters& P) -> int { template<bool all>
int bit_test(lua::state& L, lua::parameters& P)
{
uint64_t a, b; uint64_t a, b;
P(a, b); P(a, b);
L.pushboolean((a & b) != 0); uint64_t t = a & b;
bool c = all ? (t == b) : (t != 0);
L.pushboolean(c);
return 1; return 1;
}); }
lua::fnptr2 lua_testall(lua_func_bit, "bit.test_all", [](lua::state& L, lua::parameters& P) -> int {
uint64_t a, b;
P(a, b);
L.pushboolean((a & b) == b);
return 1;
});
int poptable[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; int poptable[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
@ -164,16 +161,19 @@ namespace
return c; return c;
} }
lua::fnptr2 lua_popcount(lua_func_bit, "bit.popcount", [](lua::state& L, lua::parameters& P) -> int { int bit_popcount(lua::state& L, lua::parameters& P)
{
uint64_t a; uint64_t a;
P(a); P(a);
L.pushnumber(popcount(a)); L.pushnumber(popcount(a));
return 1; return 1;
}); }
lua::fnptr2 lua_clshift(lua_func_bit, "bit.clshift", [](lua::state& L, lua::parameters& P) -> int { template<bool right>
int bit_cshift(lua::state& L, lua::parameters& P)
{
uint64_t a, b; uint64_t a, b;
unsigned amount, bits; unsigned amount, bits;
@ -182,33 +182,22 @@ namespace
uint64_t mask = ((1ULL << bits) - 1); uint64_t mask = ((1ULL << bits) - 1);
a &= mask; a &= mask;
b &= mask; b &= mask;
a <<= amount; if(right) {
a &= mask; b >>= amount;
a |= (b >> (bits - amount)); b |= (a << (bits - amount));
b <<= amount; b &= mask;
b &= mask; a >>= amount;
} else {
a <<= amount;
a &= mask;
a |= (b >> (bits - amount));
b <<= amount;
b &= mask;
}
L.pushnumber(a); L.pushnumber(a);
L.pushnumber(b); L.pushnumber(b);
return 2; return 2;
}); }
lua::fnptr2 lua_crshift(lua_func_bit, "bit.crshift", [](lua::state& L, lua::parameters& P) -> int {
uint64_t a, b;
unsigned amount, bits;
P(a, b, P.optional(amount, 1), P.optional(bits, BITWISE_BITS));
uint64_t mask = ((1ULL << bits) - 1);
a &= mask;
b &= mask;
b >>= amount;
b |= (a << (bits - amount));
b &= mask;
a >>= amount;
L.pushnumber(a);
L.pushnumber(b);
return 2;
});
template<bool reverse> template<bool reverse>
int flagdecode_core(lua::state& L, lua::parameters& P) int flagdecode_core(lua::state& L, lua::parameters& P)
@ -235,23 +224,37 @@ namespace
return 1; return 1;
} }
lua::fnptr2 lua_flagdecode(lua_func_bit, "bit.flagdecode", flagdecode_core<false>); class lua_bit_dummy {};
lua::fnptr2 lua_rflagdecode(lua_func_bit, "bit.rflagdecode", flagdecode_core<true>); lua::_class<lua_bit_dummy> bitops(lua_class_pure, "*bit", {
lua::fnptr2 bit_none(lua_func_bit, "bit.none", fold<combine_none, BITWISE_MASK>); {"flagdecode", flagdecode_core<false>},
lua::fnptr2 bit_any(lua_func_bit, "bit.any", fold<combine_any, 0>); {"rflagdecode", flagdecode_core<true>},
lua::fnptr2 bit_all(lua_func_bit, "bit.all", fold<combine_all, BITWISE_MASK>); {"none", fold<combine_none, BITWISE_MASK>},
lua::fnptr2 bit_parity(lua_func_bit, "bit.parity", fold<combine_parity, 0>); {"any", fold<combine_any, 0>},
lua::fnptr2 bit_lrotate(lua_func_bit, "bit.lrotate", shift<shift_lrotate>); {"all", fold<combine_all, BITWISE_MASK>},
lua::fnptr2 bit_rrotate(lua_func_bit, "bit.rrotate", shift<shift_rrotate>); {"parity", fold<combine_parity, 0>},
lua::fnptr2 bit_lshift(lua_func_bit, "bit.lshift", shift<shift_lshift>); {"bnot", fold<combine_none, BITWISE_MASK>},
lua::fnptr2 bit_arshift(lua_func_bit, "bit.arshift", shift<shift_arshift>); {"bor", fold<combine_any, 0>},
lua::fnptr2 bit_lrshift(lua_func_bit, "bit.lrshift", shift<shift_lrshift>); {"band", fold<combine_all, BITWISE_MASK>},
lua::fnptr2 bit_swapword(lua_func_bit, "bit.swapword", bswap<uint16_t>); {"bxor", fold<combine_parity, 0>},
lua::fnptr2 bit_swaphword(lua_func_bit, "bit.swaphword", bswap<ss_uint24_t>); {"lrotate", shift<shift_lrotate>},
lua::fnptr2 bit_swapdword(lua_func_bit, "bit.swapdword", bswap<uint32_t>); {"rrotate", shift<shift_rrotate>},
lua::fnptr2 bit_swapqword(lua_func_bit, "bit.swapqword", bswap<uint64_t>); {"lshift", shift<shift_lshift>},
lua::fnptr2 bit_swapsword(lua_func_bit, "bit.swapsword", bswap<int16_t>); {"arshift", shift<shift_arshift>},
lua::fnptr2 bit_swapshword(lua_func_bit, "bit.swapshword", bswap<ss_int24_t>); {"lrshift", shift<shift_lrshift>},
lua::fnptr2 bit_swapsdword(lua_func_bit, "bit.swapsdword", bswap<int32_t>); {"swapword", bswap<uint16_t>},
lua::fnptr2 bit_swapsqword(lua_func_bit, "bit.swapsqword", bswap<int64_t>); {"swaphword", bswap<ss_uint24_t>},
{"swapdword", bswap<uint32_t>},
{"swapqword", bswap<uint64_t>},
{"swapsword", bswap<int16_t>},
{"swapshword", bswap<ss_int24_t>},
{"swapsdword", bswap<int32_t>},
{"swapsqword", bswap<int64_t>},
{"extract", bit_extract},
{"value", bit_value},
{"test_any", bit_test<false>},
{"test_all", bit_test<true>},
{"popcount", bit_popcount},
{"clshift", bit_cshift<false>},
{"crshift", bit_cshift<true>},
});
} }

View file

@ -36,30 +36,33 @@ namespace
return 0; return 0;
} }
lua::fnptr2 hm_read(lua_func_misc, "hostmemory.read", do_read<uint8_t>); class lua_hostmemory_dummy {};
lua::fnptr2 hm_write(lua_func_misc, "hostmemory.write", do_write<uint8_t>); lua::_class<lua_hostmemory_dummy> hostops(lua_class_pure, "*hostmemory", {
lua::fnptr2 hm_readb(lua_func_misc, "hostmemory.readbyte", do_read<uint8_t>); {"read", do_read<uint8_t>},
lua::fnptr2 hm_writeb(lua_func_misc, "hostmemory.writebyte", do_write<uint8_t>); {"write", do_write<uint8_t>},
lua::fnptr2 hm_readsb(lua_func_misc, "hostmemory.readsbyte", do_read<int8_t>); {"readbyte", do_read<uint8_t>},
lua::fnptr2 hm_writesb(lua_func_misc, "hostmemory.writesbyte", do_write<int8_t>); {"writebyte", do_write<uint8_t>},
lua::fnptr2 hm_readw(lua_func_misc, "hostmemory.readword", do_read<uint16_t>); {"readsbyte", do_read<int8_t>},
lua::fnptr2 hm_writew(lua_func_misc, "hostmemory.writeword", do_write<uint16_t>); {"writesbyte", do_write<int8_t>},
lua::fnptr2 hm_readsw(lua_func_misc, "hostmemory.readsword", do_read<int16_t>); {"readword", do_read<uint16_t>},
lua::fnptr2 hm_writesw(lua_func_misc, "hostmemory.writesword", do_write<int16_t>); {"writeword", do_write<uint16_t>},
lua::fnptr2 hm_readh(lua_func_misc, "hostmemory.readhword", do_read<ss_uint24_t>); {"readsword", do_read<int16_t>},
lua::fnptr2 hm_writeh(lua_func_misc, "hostmemory.writehword", do_write<ss_uint24_t>); {"writesword", do_write<int16_t>},
lua::fnptr2 hm_readsh(lua_func_misc, "hostmemory.readshword", do_read<ss_int24_t>); {"readhword", do_read<ss_uint24_t>},
lua::fnptr2 hm_writesh(lua_func_misc, "hostmemory.writeshword", do_write<ss_int24_t>); {"writehword", do_write<ss_uint24_t>},
lua::fnptr2 hm_readd(lua_func_misc, "hostmemory.readdword", do_read<uint32_t>); {"readshword", do_read<ss_int24_t>},
lua::fnptr2 hm_writed(lua_func_misc, "hostmemory.writedword", do_write<uint32_t>); {"writeshword", do_write<ss_int24_t>},
lua::fnptr2 hm_readsd(lua_func_misc, "hostmemory.readsdword", do_read<int32_t>); {"readdword", do_read<uint32_t>},
lua::fnptr2 hm_writesd(lua_func_misc, "hostmemory.writesdword", do_write<int32_t>); {"writedword", do_write<uint32_t>},
lua::fnptr2 hm_readq(lua_func_misc, "hostmemory.readqword", do_read<uint64_t>); {"readsdword", do_read<int32_t>},
lua::fnptr2 hm_writeq(lua_func_misc, "hostmemory.writeqword", do_write<uint64_t>); {"writesdword", do_write<int32_t>},
lua::fnptr2 hm_readsq(lua_func_misc, "hostmemory.readsqword", do_read<int64_t>); {"readqword", do_read<uint64_t>},
lua::fnptr2 hm_writesq(lua_func_misc, "hostmemory.writesqword", do_write<int64_t>); {"writeqword", do_write<uint64_t>},
lua::fnptr2 hm_readf4(lua_func_misc, "hostmemory.readfloat", do_read<float>); {"readsqword", do_read<int64_t>},
lua::fnptr2 hm_writef4(lua_func_misc, "hostmemory.writefloat", do_write<float>); {"writesqword", do_write<int64_t>},
lua::fnptr2 hm_readf8(lua_func_misc, "hostmemory.readdouble", do_read<double>); {"readfloat", do_read<float>},
lua::fnptr2 hm_writef8(lua_func_misc, "hostmemory.writedouble", do_write<double>); {"writefloat", do_write<float>},
{"readdouble", do_read<double>},
{"writedouble", do_write<double>},
});
} }

View file

@ -28,12 +28,14 @@ namespace
} }
} }
lua::fnptr2 rboolean(lua_func_misc, "random.boolean", [](lua::state& L, lua::parameters& P) -> int { int rand_boolean(lua::state& L, lua::parameters& P)
{
L.pushboolean(randnum() % 2); L.pushboolean(randnum() % 2);
return 1; return 1;
}); }
lua::fnptr2 rinteger(lua_func_misc, "random.integer", [](lua::state& L, lua::parameters& P) -> int { int rand_integer(lua::state& L, lua::parameters& P)
{
uint64_t low = 0, high = 0; uint64_t low = 0, high = 0;
P(low); P(low);
@ -51,18 +53,20 @@ namespace
uint64_t rsize = high - low + 1; uint64_t rsize = high - low + 1;
L.pushnumber(low + randnum_mod(rsize)); L.pushnumber(low + randnum_mod(rsize));
return 1; return 1;
}); }
lua::fnptr2 rfloat(lua_func_misc, "random.float", [](lua::state& L, lua::parameters& P) -> int { int rand_float(lua::state& L, lua::parameters& P)
{
double _bits = 0; double _bits = 0;
uint64_t* bits = (uint64_t*)&_bits; uint64_t* bits = (uint64_t*)&_bits;
*bits = randnum() & 0xFFFFFFFFFFFFFULL; *bits = randnum() & 0xFFFFFFFFFFFFFULL;
*bits |= 0x3FF0000000000000ULL; *bits |= 0x3FF0000000000000ULL;
L.pushnumber(_bits - 1); L.pushnumber(_bits - 1);
return 1; return 1;
}); }
lua::fnptr2 ramong(lua_func_misc, "random.among", [](lua::state& L, lua::parameters& P) -> int { int rand_among(lua::state& L, lua::parameters& P)
{
unsigned args = 1; unsigned args = 1;
while(P.more()) { while(P.more()) {
P.skip(); P.skip();
@ -76,9 +80,9 @@ namespace
uint64_t n = randnum_mod(args); uint64_t n = randnum_mod(args);
L.pushvalue(n + 1); L.pushvalue(n + 1);
return 1; return 1;
}); }
lua::fnptr2 ramongt(lua_func_misc, "random.amongtable", [](lua::state& L, lua::parameters& P) int rand_amongtable(lua::state& L, lua::parameters& P)
{ {
int ltbl; int ltbl;
P(P.table(ltbl)); P(P.table(ltbl));
@ -103,5 +107,14 @@ namespace
if(!L.next(ltbl)) if(!L.next(ltbl))
throw std::runtime_error("random.amongtable: Inconsistent table size"); throw std::runtime_error("random.amongtable: Inconsistent table size");
return 1; return 1;
}
class lua_dummy_random {};
lua::_class<lua_dummy_random> lua_random(lua_class_pure, "*random", {
{"boolean", rand_boolean},
{"integer", rand_integer},
{"float", rand_float},
{"among", rand_among},
{"amongtable", rand_amongtable},
}); });
} }

View file

@ -3,7 +3,8 @@
namespace namespace
{ {
lua::fnptr2 ss(lua_func_misc, "settings.set", [](lua::state& L, lua::parameters& P) -> int { int ss_set(lua::state& L, lua::parameters& P)
{
std::string name, value; std::string name, value;
P(name, value); P(name, value);
@ -17,9 +18,10 @@ namespace
} }
L.pushboolean(1); L.pushboolean(1);
return 1; return 1;
}); }
lua::fnptr2 sg(lua_func_misc, "settings.get", [](lua::state& L, lua::parameters& P) -> int { int ss_get(lua::state& L, lua::parameters& P)
{
std::string name; std::string name;
P(name); P(name);
@ -33,5 +35,11 @@ namespace
L.pushstring(e.what()); L.pushstring(e.what());
return 2; return 2;
} }
}
class lua_settings_dummy {};
lua::_class<lua_settings_dummy> lua_settings(lua_class_bind, "*settings", {
{"set", ss_set},
{"get", ss_get},
}); });
} }

View file

@ -3,7 +3,8 @@
namespace namespace
{ {
lua::fnptr2 enumerate(lua_func_misc, "subtitle.byindex", [](lua::state& L, lua::parameters& P) -> int { int sub_byindex(lua::state& L, lua::parameters& P)
{
auto n = P.arg<uint64_t>(); auto n = P.arg<uint64_t>();
uint64_t j = 0; uint64_t j = 0;
for(auto i : get_subtitles()) { for(auto i : get_subtitles()) {
@ -15,28 +16,39 @@ namespace
j++; j++;
} }
return 0; return 0;
}); }
lua::fnptr2 sget(lua_func_misc, "subtitle.get", [](lua::state& L, lua::parameters& P) -> int { int sub_get(lua::state& L, lua::parameters& P)
{
auto frame = P.arg<uint64_t>(); auto frame = P.arg<uint64_t>();
auto length = P.arg<uint64_t>(); auto length = P.arg<uint64_t>();
std::string x = get_subtitle_for(frame, length); std::string x = get_subtitle_for(frame, length);
L.pushstring(x.c_str()); L.pushstring(x.c_str());
return 1; return 1;
}); }
lua::fnptr2 sset(lua_func_misc, "subtitle.set", [](lua::state& L, lua::parameters& P) -> int { int sub_set(lua::state& L, lua::parameters& P)
{
auto frame = P.arg<uint64_t>(); auto frame = P.arg<uint64_t>();
auto length = P.arg<uint64_t>(); auto length = P.arg<uint64_t>();
std::string text = P.arg<std::string>(); std::string text = P.arg<std::string>();
set_subtitle_for(frame, length, text); set_subtitle_for(frame, length, text);
return 0; return 0;
}); }
lua::fnptr2 sdel(lua_func_misc, "subtitle.delete", [](lua::state& L, lua::parameters& P) -> int { int sub_delete(lua::state& L, lua::parameters& P)
{
auto frame = P.arg<uint64_t>(); auto frame = P.arg<uint64_t>();
auto length = P.arg<uint64_t>(); auto length = P.arg<uint64_t>();
set_subtitle_for(frame, length, ""); set_subtitle_for(frame, length, "");
return 0; return 0;
}
class lua_subtitles_dummy {};
lua::_class<lua_subtitles_dummy> lua_subtitles(lua_class_bind, "*subtitle", {
{"byindex", sub_byindex},
{"get", sub_get},
{"set", sub_set},
{"delete", sub_delete},
}); });
} }

View file

@ -26,13 +26,9 @@ render_queue_function=function(rq)
end; end;
string.byteU=_lsnes_string_byteU; string.byteU=_lsnes_string_byteU;
string.charU=_lsnes_string_charU; string.charU=_lsnes_string_charU;
--Bit aliases
bit.bnot=bit.none;
bit.bor=bit.any;
bit.band=bit.all;
bit.bxor=bit.parity;
local _lookup_class = lookup_class; local _lookup_class = lookup_class;
local _all_classes = all_classes;
local classes_meta = { local classes_meta = {
["__newindex"] = function() error("Classes table is not writable"); end, ["__newindex"] = function() error("Classes table is not writable"); end,
["__index"] = function(a, b) return _lookup_class(b); end ["__index"] = function(a, b) return _lookup_class(b); end
@ -40,6 +36,32 @@ local classes_meta = {
classes = {}; classes = {};
setmetatable(classes, classes_meta); setmetatable(classes, classes_meta);
local register_in = function(table, class)
local methods = {classes[class]._static_methods()};
local utable;
if table then
_G[table] = _G[table] or {};
utable = _G[table];
else
utable = _G;
end
local i;
for i=1,#methods do
local m = methods[i];
utable[m] = classes[class][m];
end
end
--Register all classes that have special names at top level.
local classes_list = {_all_classes()};
local idx;
for idx=1,#classes_list do
local c = classes_list[idx];
if string.byte(c) == 42 then
_G[string.sub(c, 2)] = classes[c];
end
end
-- Classes -- Classes
memory.mmap = classes.MMAP_STRUCT; memory.mmap = classes.MMAP_STRUCT;
zip.writer = classes.ZIPWRITER; zip.writer = classes.ZIPWRITER;