From 1fd5a490bf87518f80611211deedf011229eafa2 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 29 Jan 2014 13:09:00 +0200 Subject: [PATCH] Lua: Convert some functions to static-only classes --- src/lua/bind.cpp | 20 +++++-- src/lua/bit.cpp | 127 +++++++++++++++++++++-------------------- src/lua/hostmemory.cpp | 55 +++++++++--------- src/lua/random.cpp | 31 +++++++--- src/lua/settings.cpp | 14 ++++- src/lua/subtitles.cpp | 26 ++++++--- src/lua/sysrc.lua | 32 +++++++++-- 7 files changed, 188 insertions(+), 117 deletions(-) diff --git a/src/lua/bind.cpp b/src/lua/bind.cpp index cfc7b289..be496014 100644 --- a/src/lua/bind.cpp +++ b/src/lua/bind.cpp @@ -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_kbd(lua_class_bind, "*keyboard", { + {"bind", kbd_bind}, + {"unbind", kbd_unbind}, + {"alias", kbd_alias}, }); } diff --git a/src/lua/bit.cpp b/src/lua/bit.cpp index fbe6021a..e6615c20 100644 --- a/src/lua/bit.cpp +++ b/src/lua/bit.cpp @@ -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 + 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 + 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 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); - lua::fnptr2 lua_rflagdecode(lua_func_bit, "bit.rflagdecode", flagdecode_core); - lua::fnptr2 bit_none(lua_func_bit, "bit.none", fold); - lua::fnptr2 bit_any(lua_func_bit, "bit.any", fold); - lua::fnptr2 bit_all(lua_func_bit, "bit.all", fold); - lua::fnptr2 bit_parity(lua_func_bit, "bit.parity", fold); - lua::fnptr2 bit_lrotate(lua_func_bit, "bit.lrotate", shift); - lua::fnptr2 bit_rrotate(lua_func_bit, "bit.rrotate", shift); - lua::fnptr2 bit_lshift(lua_func_bit, "bit.lshift", shift); - lua::fnptr2 bit_arshift(lua_func_bit, "bit.arshift", shift); - lua::fnptr2 bit_lrshift(lua_func_bit, "bit.lrshift", shift); - lua::fnptr2 bit_swapword(lua_func_bit, "bit.swapword", bswap); - lua::fnptr2 bit_swaphword(lua_func_bit, "bit.swaphword", bswap); - lua::fnptr2 bit_swapdword(lua_func_bit, "bit.swapdword", bswap); - lua::fnptr2 bit_swapqword(lua_func_bit, "bit.swapqword", bswap); - lua::fnptr2 bit_swapsword(lua_func_bit, "bit.swapsword", bswap); - lua::fnptr2 bit_swapshword(lua_func_bit, "bit.swapshword", bswap); - lua::fnptr2 bit_swapsdword(lua_func_bit, "bit.swapsdword", bswap); - lua::fnptr2 bit_swapsqword(lua_func_bit, "bit.swapsqword", bswap); + class lua_bit_dummy {}; + lua::_class bitops(lua_class_pure, "*bit", { + {"flagdecode", flagdecode_core}, + {"rflagdecode", flagdecode_core}, + {"none", fold}, + {"any", fold}, + {"all", fold}, + {"parity", fold}, + {"bnot", fold}, + {"bor", fold}, + {"band", fold}, + {"bxor", fold}, + {"lrotate", shift}, + {"rrotate", shift}, + {"lshift", shift}, + {"arshift", shift}, + {"lrshift", shift}, + {"swapword", bswap}, + {"swaphword", bswap}, + {"swapdword", bswap}, + {"swapqword", bswap}, + {"swapsword", bswap}, + {"swapshword", bswap}, + {"swapsdword", bswap}, + {"swapsqword", bswap}, + {"extract", bit_extract}, + {"value", bit_value}, + {"test_any", bit_test}, + {"test_all", bit_test}, + {"popcount", bit_popcount}, + {"clshift", bit_cshift}, + {"crshift", bit_cshift}, + }); } diff --git a/src/lua/hostmemory.cpp b/src/lua/hostmemory.cpp index 01d236d4..783fc388 100644 --- a/src/lua/hostmemory.cpp +++ b/src/lua/hostmemory.cpp @@ -36,30 +36,33 @@ namespace return 0; } - lua::fnptr2 hm_read(lua_func_misc, "hostmemory.read", do_read); - lua::fnptr2 hm_write(lua_func_misc, "hostmemory.write", do_write); - lua::fnptr2 hm_readb(lua_func_misc, "hostmemory.readbyte", do_read); - lua::fnptr2 hm_writeb(lua_func_misc, "hostmemory.writebyte", do_write); - lua::fnptr2 hm_readsb(lua_func_misc, "hostmemory.readsbyte", do_read); - lua::fnptr2 hm_writesb(lua_func_misc, "hostmemory.writesbyte", do_write); - lua::fnptr2 hm_readw(lua_func_misc, "hostmemory.readword", do_read); - lua::fnptr2 hm_writew(lua_func_misc, "hostmemory.writeword", do_write); - lua::fnptr2 hm_readsw(lua_func_misc, "hostmemory.readsword", do_read); - lua::fnptr2 hm_writesw(lua_func_misc, "hostmemory.writesword", do_write); - lua::fnptr2 hm_readh(lua_func_misc, "hostmemory.readhword", do_read); - lua::fnptr2 hm_writeh(lua_func_misc, "hostmemory.writehword", do_write); - lua::fnptr2 hm_readsh(lua_func_misc, "hostmemory.readshword", do_read); - lua::fnptr2 hm_writesh(lua_func_misc, "hostmemory.writeshword", do_write); - lua::fnptr2 hm_readd(lua_func_misc, "hostmemory.readdword", do_read); - lua::fnptr2 hm_writed(lua_func_misc, "hostmemory.writedword", do_write); - lua::fnptr2 hm_readsd(lua_func_misc, "hostmemory.readsdword", do_read); - lua::fnptr2 hm_writesd(lua_func_misc, "hostmemory.writesdword", do_write); - lua::fnptr2 hm_readq(lua_func_misc, "hostmemory.readqword", do_read); - lua::fnptr2 hm_writeq(lua_func_misc, "hostmemory.writeqword", do_write); - lua::fnptr2 hm_readsq(lua_func_misc, "hostmemory.readsqword", do_read); - lua::fnptr2 hm_writesq(lua_func_misc, "hostmemory.writesqword", do_write); - lua::fnptr2 hm_readf4(lua_func_misc, "hostmemory.readfloat", do_read); - lua::fnptr2 hm_writef4(lua_func_misc, "hostmemory.writefloat", do_write); - lua::fnptr2 hm_readf8(lua_func_misc, "hostmemory.readdouble", do_read); - lua::fnptr2 hm_writef8(lua_func_misc, "hostmemory.writedouble", do_write); + class lua_hostmemory_dummy {}; + lua::_class hostops(lua_class_pure, "*hostmemory", { + {"read", do_read}, + {"write", do_write}, + {"readbyte", do_read}, + {"writebyte", do_write}, + {"readsbyte", do_read}, + {"writesbyte", do_write}, + {"readword", do_read}, + {"writeword", do_write}, + {"readsword", do_read}, + {"writesword", do_write}, + {"readhword", do_read}, + {"writehword", do_write}, + {"readshword", do_read}, + {"writeshword", do_write}, + {"readdword", do_read}, + {"writedword", do_write}, + {"readsdword", do_read}, + {"writesdword", do_write}, + {"readqword", do_read}, + {"writeqword", do_write}, + {"readsqword", do_read}, + {"writesqword", do_write}, + {"readfloat", do_read}, + {"writefloat", do_write}, + {"readdouble", do_read}, + {"writedouble", do_write}, + }); } diff --git a/src/lua/random.cpp b/src/lua/random.cpp index 07d4a1c4..c14d95ca 100644 --- a/src/lua/random.cpp +++ b/src/lua/random.cpp @@ -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_random(lua_class_pure, "*random", { + {"boolean", rand_boolean}, + {"integer", rand_integer}, + {"float", rand_float}, + {"among", rand_among}, + {"amongtable", rand_amongtable}, }); } diff --git a/src/lua/settings.cpp b/src/lua/settings.cpp index 55d0e095..0b9ec2a9 100644 --- a/src/lua/settings.cpp +++ b/src/lua/settings.cpp @@ -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(lua_class_bind, "*settings", { + {"set", ss_set}, + {"get", ss_get}, }); } diff --git a/src/lua/subtitles.cpp b/src/lua/subtitles.cpp index 314688d8..29bbc875 100644 --- a/src/lua/subtitles.cpp +++ b/src/lua/subtitles.cpp @@ -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 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(); auto length = P.arg(); 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(); auto length = P.arg(); std::string text = P.arg(); 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(); auto length = P.arg(); set_subtitle_for(frame, length, ""); return 0; + } + + class lua_subtitles_dummy {}; + lua::_class lua_subtitles(lua_class_bind, "*subtitle", { + {"byindex", sub_byindex}, + {"get", sub_get}, + {"set", sub_set}, + {"delete", sub_delete}, }); } diff --git a/src/lua/sysrc.lua b/src/lua/sysrc.lua index afd4d92f..32cae47c 100644 --- a/src/lua/sysrc.lua +++ b/src/lua/sysrc.lua @@ -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;