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
{
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;
P(mod, mask, key, cmd);
lsnes_mapper.bind(mod, mask, key, cmd);
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;
P(mod, mask, key);
lsnes_mapper.unbind(mod, mask, key);
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;
P(alias, cmds);
@ -31,5 +34,12 @@ namespace
lsnes_cmd.set_alias_for(alias, cmds);
refresh_alias_binds();
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;
}
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 num;
@ -119,9 +120,10 @@ namespace
}
L.pushnumber(ret);
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;
for(size_t i = 0;; i++) {
if(P.is_number()) {
@ -132,25 +134,20 @@ namespace
}
L.pushnumber(ret);
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;
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;
});
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};
@ -164,16 +161,19 @@ namespace
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;
P(a);
L.pushnumber(popcount(a));
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;
unsigned amount, bits;
@ -182,33 +182,22 @@ namespace
uint64_t mask = ((1ULL << bits) - 1);
a &= mask;
b &= mask;
a <<= amount;
a &= mask;
a |= (b >> (bits - amount));
b <<= amount;
b &= mask;
if(right) {
b >>= amount;
b |= (a << (bits - amount));
b &= mask;
a >>= amount;
} else {
a <<= amount;
a &= mask;
a |= (b >> (bits - amount));
b <<= amount;
b &= mask;
}
L.pushnumber(a);
L.pushnumber(b);
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>
int flagdecode_core(lua::state& L, lua::parameters& P)
@ -235,23 +224,37 @@ namespace
return 1;
}
lua::fnptr2 lua_flagdecode(lua_func_bit, "bit.flagdecode", flagdecode_core<false>);
lua::fnptr2 lua_rflagdecode(lua_func_bit, "bit.rflagdecode", flagdecode_core<true>);
lua::fnptr2 bit_none(lua_func_bit, "bit.none", fold<combine_none, BITWISE_MASK>);
lua::fnptr2 bit_any(lua_func_bit, "bit.any", fold<combine_any, 0>);
lua::fnptr2 bit_all(lua_func_bit, "bit.all", fold<combine_all, BITWISE_MASK>);
lua::fnptr2 bit_parity(lua_func_bit, "bit.parity", fold<combine_parity, 0>);
lua::fnptr2 bit_lrotate(lua_func_bit, "bit.lrotate", shift<shift_lrotate>);
lua::fnptr2 bit_rrotate(lua_func_bit, "bit.rrotate", shift<shift_rrotate>);
lua::fnptr2 bit_lshift(lua_func_bit, "bit.lshift", shift<shift_lshift>);
lua::fnptr2 bit_arshift(lua_func_bit, "bit.arshift", shift<shift_arshift>);
lua::fnptr2 bit_lrshift(lua_func_bit, "bit.lrshift", shift<shift_lrshift>);
lua::fnptr2 bit_swapword(lua_func_bit, "bit.swapword", bswap<uint16_t>);
lua::fnptr2 bit_swaphword(lua_func_bit, "bit.swaphword", bswap<ss_uint24_t>);
lua::fnptr2 bit_swapdword(lua_func_bit, "bit.swapdword", bswap<uint32_t>);
lua::fnptr2 bit_swapqword(lua_func_bit, "bit.swapqword", bswap<uint64_t>);
lua::fnptr2 bit_swapsword(lua_func_bit, "bit.swapsword", bswap<int16_t>);
lua::fnptr2 bit_swapshword(lua_func_bit, "bit.swapshword", bswap<ss_int24_t>);
lua::fnptr2 bit_swapsdword(lua_func_bit, "bit.swapsdword", bswap<int32_t>);
lua::fnptr2 bit_swapsqword(lua_func_bit, "bit.swapsqword", bswap<int64_t>);
class lua_bit_dummy {};
lua::_class<lua_bit_dummy> bitops(lua_class_pure, "*bit", {
{"flagdecode", flagdecode_core<false>},
{"rflagdecode", flagdecode_core<true>},
{"none", fold<combine_none, BITWISE_MASK>},
{"any", fold<combine_any, 0>},
{"all", fold<combine_all, BITWISE_MASK>},
{"parity", fold<combine_parity, 0>},
{"bnot", fold<combine_none, BITWISE_MASK>},
{"bor", fold<combine_any, 0>},
{"band", fold<combine_all, BITWISE_MASK>},
{"bxor", fold<combine_parity, 0>},
{"lrotate", shift<shift_lrotate>},
{"rrotate", shift<shift_rrotate>},
{"lshift", shift<shift_lshift>},
{"arshift", shift<shift_arshift>},
{"lrshift", shift<shift_lrshift>},
{"swapword", bswap<uint16_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;
}
lua::fnptr2 hm_read(lua_func_misc, "hostmemory.read", do_read<uint8_t>);
lua::fnptr2 hm_write(lua_func_misc, "hostmemory.write", do_write<uint8_t>);
lua::fnptr2 hm_readb(lua_func_misc, "hostmemory.readbyte", do_read<uint8_t>);
lua::fnptr2 hm_writeb(lua_func_misc, "hostmemory.writebyte", do_write<uint8_t>);
lua::fnptr2 hm_readsb(lua_func_misc, "hostmemory.readsbyte", do_read<int8_t>);
lua::fnptr2 hm_writesb(lua_func_misc, "hostmemory.writesbyte", do_write<int8_t>);
lua::fnptr2 hm_readw(lua_func_misc, "hostmemory.readword", do_read<uint16_t>);
lua::fnptr2 hm_writew(lua_func_misc, "hostmemory.writeword", do_write<uint16_t>);
lua::fnptr2 hm_readsw(lua_func_misc, "hostmemory.readsword", do_read<int16_t>);
lua::fnptr2 hm_writesw(lua_func_misc, "hostmemory.writesword", do_write<int16_t>);
lua::fnptr2 hm_readh(lua_func_misc, "hostmemory.readhword", do_read<ss_uint24_t>);
lua::fnptr2 hm_writeh(lua_func_misc, "hostmemory.writehword", do_write<ss_uint24_t>);
lua::fnptr2 hm_readsh(lua_func_misc, "hostmemory.readshword", do_read<ss_int24_t>);
lua::fnptr2 hm_writesh(lua_func_misc, "hostmemory.writeshword", do_write<ss_int24_t>);
lua::fnptr2 hm_readd(lua_func_misc, "hostmemory.readdword", do_read<uint32_t>);
lua::fnptr2 hm_writed(lua_func_misc, "hostmemory.writedword", do_write<uint32_t>);
lua::fnptr2 hm_readsd(lua_func_misc, "hostmemory.readsdword", do_read<int32_t>);
lua::fnptr2 hm_writesd(lua_func_misc, "hostmemory.writesdword", do_write<int32_t>);
lua::fnptr2 hm_readq(lua_func_misc, "hostmemory.readqword", do_read<uint64_t>);
lua::fnptr2 hm_writeq(lua_func_misc, "hostmemory.writeqword", do_write<uint64_t>);
lua::fnptr2 hm_readsq(lua_func_misc, "hostmemory.readsqword", do_read<int64_t>);
lua::fnptr2 hm_writesq(lua_func_misc, "hostmemory.writesqword", do_write<int64_t>);
lua::fnptr2 hm_readf4(lua_func_misc, "hostmemory.readfloat", do_read<float>);
lua::fnptr2 hm_writef4(lua_func_misc, "hostmemory.writefloat", do_write<float>);
lua::fnptr2 hm_readf8(lua_func_misc, "hostmemory.readdouble", do_read<double>);
lua::fnptr2 hm_writef8(lua_func_misc, "hostmemory.writedouble", do_write<double>);
class lua_hostmemory_dummy {};
lua::_class<lua_hostmemory_dummy> hostops(lua_class_pure, "*hostmemory", {
{"read", do_read<uint8_t>},
{"write", do_write<uint8_t>},
{"readbyte", do_read<uint8_t>},
{"writebyte", do_write<uint8_t>},
{"readsbyte", do_read<int8_t>},
{"writesbyte", do_write<int8_t>},
{"readword", do_read<uint16_t>},
{"writeword", do_write<uint16_t>},
{"readsword", do_read<int16_t>},
{"writesword", do_write<int16_t>},
{"readhword", do_read<ss_uint24_t>},
{"writehword", do_write<ss_uint24_t>},
{"readshword", do_read<ss_int24_t>},
{"writeshword", do_write<ss_int24_t>},
{"readdword", do_read<uint32_t>},
{"writedword", do_write<uint32_t>},
{"readsdword", do_read<int32_t>},
{"writesdword", do_write<int32_t>},
{"readqword", do_read<uint64_t>},
{"writeqword", do_write<uint64_t>},
{"readsqword", do_read<int64_t>},
{"writesqword", do_write<int64_t>},
{"readfloat", do_read<float>},
{"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);
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;
P(low);
@ -51,18 +53,20 @@ namespace
uint64_t rsize = high - low + 1;
L.pushnumber(low + randnum_mod(rsize));
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;
uint64_t* bits = (uint64_t*)&_bits;
*bits = randnum() & 0xFFFFFFFFFFFFFULL;
*bits |= 0x3FF0000000000000ULL;
L.pushnumber(_bits - 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;
while(P.more()) {
P.skip();
@ -76,9 +80,9 @@ namespace
uint64_t n = randnum_mod(args);
L.pushvalue(n + 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;
P(P.table(ltbl));
@ -103,5 +107,14 @@ namespace
if(!L.next(ltbl))
throw std::runtime_error("random.amongtable: Inconsistent table size");
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
{
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;
P(name, value);
@ -17,9 +18,10 @@ namespace
}
L.pushboolean(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;
P(name);
@ -33,5 +35,11 @@ namespace
L.pushstring(e.what());
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
{
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>();
uint64_t j = 0;
for(auto i : get_subtitles()) {
@ -15,28 +16,39 @@ namespace
j++;
}
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 length = P.arg<uint64_t>();
std::string x = get_subtitle_for(frame, length);
L.pushstring(x.c_str());
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 length = P.arg<uint64_t>();
std::string text = P.arg<std::string>();
set_subtitle_for(frame, length, text);
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 length = P.arg<uint64_t>();
set_subtitle_for(frame, length, "");
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;
string.byteU=_lsnes_string_byteU;
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 _all_classes = all_classes;
local classes_meta = {
["__newindex"] = function() error("Classes table is not writable"); end,
["__index"] = function(a, b) return _lookup_class(b); end
@ -40,6 +36,32 @@ local classes_meta = {
classes = {};
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
memory.mmap = classes.MMAP_STRUCT;
zip.writer = classes.ZIPWRITER;