summaryrefslogtreecommitdiffstats
path: root/src/frontend/mame/luaengine.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2020-11-25 19:18:26 +1100
committer Vas Crabb <vas@vastheman.com>2020-11-25 19:18:26 +1100
commitec8042864703f9ce6cc9b0cf528e6a8528104b89 (patch)
tree427556c7d86c7cab5f136aff7f0675adc443144b /src/frontend/mame/luaengine.cpp
parent8ea35743e40bd6dc01e50a0a21524db7b0ad203e (diff)
Fairly significant overhaul of Lua engine and some cleanup.
The things that were previously called device iterators are not iterators in the C++ sense of the word. This is confusing for newcomers. These have been renamed to be device enumerators. Several Lua methods and properties that previously returned tables now return lightweight wrappers for the underlying objects. This means creating them is a lot faster, but you can't modify them, and the performance characteristics of different operations varies. The render manager's target list uses 1-based indexing to be more like idiomatic Lua. It's now possible to create a device enumerator on any device, and then get subdevices (or sibling devices) using a relative tag. Much more render/layout functionality has been exposed to Lua. Layout scripts now have access to the layout file and can directly set the state of an item with no bindings, or register callbacks to obtain state. Some things that were previously methods are now read-only properties. Layout files are no longer required to supply a "name". This was problematic because the same layout file could be loaded for multiple instances of the same device, and each instance of the layout file should use the correct inputs (and in the future outputs) for the device instance it's associated with. This should also fix video output with MSVC builds by avoiding delegates that return things that don't fit in a register.
Diffstat (limited to 'src/frontend/mame/luaengine.cpp')
-rw-r--r--src/frontend/mame/luaengine.cpp485
1 files changed, 302 insertions, 183 deletions
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 880ade2ab23..48ebc897899 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -37,24 +37,144 @@
//**************************************************************************
extern "C" {
- int luaopen_zlib(lua_State *L);
- int luaopen_lfs(lua_State *L);
- int luaopen_linenoise(lua_State *L);
- int luaopen_lsqlite3(lua_State *L);
-}
+
+int luaopen_zlib(lua_State *L);
+int luaopen_lfs(lua_State *L);
+int luaopen_linenoise(lua_State *L);
+int luaopen_lsqlite3(lua_State *L);
+
+} // extern "C"
+
+
+template <typename T>
+struct lua_engine::devenum
+{
+ devenum(device_t &d) : device(d), iter(d) { }
+
+ device_t &device;
+ T iter;
+ int count = -1;
+};
+
namespace sol
{
- sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking)
+
+sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking)
+{
+ return new sol::buffer(stack::get<int>(L, index), L);
+}
+
+int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value)
+{
+ delete value;
+ return 1;
+}
+
+template <typename T>
+struct usertype_container<lua_engine::devenum<T> > : lua_engine::immutable_container_helper<lua_engine::devenum<T>, T>
+{
+private:
+ using enumerator = lua_engine::devenum<T>;
+
+ template <bool Indexed>
+ static int next_pairs(lua_State *L)
{
- return new sol::buffer(stack::get<int>(L, index), L);
+ typename usertype_container::indexed_iterator &i(stack::unqualified_get<user<typename usertype_container::indexed_iterator> >(L, 1));
+ if (i.src.end() == i.it)
+ return stack::push(L, lua_nil);
+ int result;
+ if constexpr (Indexed)
+ result = stack::push(L, i.ix + 1);
+ else
+ result = stack::push(L, i.it->tag());
+ result += stack::push_reference(L, *i.it);
+ ++i;
+ return result;
}
- int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value)
+
+ template <bool Indexed>
+ static int start_pairs(lua_State *L)
{
- delete value;
- return 1;
+ enumerator &self(usertype_container::get_self(L));
+ stack::push(L, next_pairs<Indexed>);
+ stack::push<user<typename usertype_container::indexed_iterator> >(L, self.iter, self.iter.begin());
+ stack::push(L, lua_nil);
+ return 3;
+ }
+
+public:
+ static int at(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
+ auto const dev(self.iter.byindex(index - 1));
+ if (dev)
+ return stack::push_reference(L, *dev);
+ else
+ return stack::push(L, lua_nil);
}
-}
+
+ static int get(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ char const *const tag(stack::unqualified_get<char const *>(L));
+ device_t *const dev(self.device.subdevice(tag));
+ if (dev)
+ {
+ auto *const check(T(*dev, 0).first());
+ bool match;
+ if constexpr (std::is_base_of_v<device_t, decltype(*check)>)
+ match = check && (static_cast<device_t *>(check) == dev);
+ else if constexpr (std::is_base_of_v<device_interface, decltype(*check)>)
+ match = check && (&check->device() == dev);
+ else
+ match = check && (dynamic_cast<device_t *>(check) == dev);
+ if (match)
+ return stack::push_reference(L, *check);
+ }
+ return stack::push(L, lua_nil);
+ }
+
+ static int index_get(lua_State *L)
+ {
+ return get(L);
+ }
+
+ static int index_of(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ auto &dev(stack::unqualified_get<decltype(*self.iter.first())>(L, 2));
+ std::ptrdiff_t found(self.iter.indexof(dev));
+ if (0 > found)
+ return stack::push(L, lua_nil);
+ else
+ return stack::push(L, found + 1);
+ }
+
+ static int size(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ if (0 > self.count)
+ self.count = self.iter.count();
+ return stack::push(L, self.count);
+ }
+
+ static int empty(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ if (0 > self.count)
+ self.count = self.iter.count();
+ return stack::push(L, !self.count);
+ }
+
+ static int next(lua_State *L) { return stack::push(L, next_pairs<false>); }
+ static int pairs(lua_State *L) { return start_pairs<false>(L); }
+ static int ipairs(lua_State *L) { return start_pairs<true>(L); }
+};
+
+} // namespace sol
+
int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value)
{
@@ -461,17 +581,23 @@ void lua_engine::initialize()
* emu.print_error(str) - output to stderr at error level
* emu.print_info(str) - output to stderr at info level
* emu.print_debug(str) - output to stderr at debug level
+ *
+ * emu.device_enumerator(dev) - get device enumerator starting at arbitrary point in tree
+ * emu.screen_enumerator(dev) - get screen device enumerator starting at arbitrary point in tree
+ * emu.image_enumerator(dev) - get image interface enumerator starting at arbitrary point in tree
*/
sol::table emu = sol().create_named_table("emu");
emu["app_name"] = &emulator_info::get_appname_lower;
emu["app_version"] = &emulator_info::get_bare_build_version;
- emu["gamename"] = [this](){ return machine().system().type.fullname(); };
- emu["romname"] = [this](){ return machine().basename(); };
- emu["softname"] = [this]() { return machine().options().software_name(); };
- emu["keypost"] = [this](const char *keys){ machine().ioport().natkeyboard().post_utf8(keys); };
- emu["time"] = [this](){ return machine().time().as_double(); };
- emu["start"] = [this](const char *driver) {
+ emu["gamename"] = [this] () { return machine().system().type.fullname(); };
+ emu["romname"] = [this] () { return machine().basename(); };
+ emu["softname"] = [this] () { return machine().options().software_name(); };
+ emu["keypost"] = [this] (const char *keys) { machine().ioport().natkeyboard().post_utf8(keys); };
+ emu["time"] = [this] () { return machine().time().as_double(); };
+ emu["start"] =
+ [this](const char *driver)
+ {
int i = driver_list::find(driver);
if (i != -1)
{
@@ -480,69 +606,86 @@ void lua_engine::initialize()
}
return 1;
};
- emu["pause"] = [this](){ return machine().pause(); };
- emu["unpause"] = [this](){ return machine().resume(); };
- emu["step"] = [this]() {
+ emu["pause"] = [this] () { return machine().pause(); };
+ emu["unpause"] = [this] () { return machine().resume(); };
+ emu["step"] =
+ [this] ()
+ {
mame_machine_manager::instance()->ui().set_single_step(true);
machine().resume();
};
- emu["register_prestart"] = [this](sol::function func){ register_function(func, "LUA_ON_PRESTART"); };
- emu["register_start"] = [this](sol::function func){ register_function(func, "LUA_ON_START"); };
- emu["register_stop"] = [this](sol::function func){ register_function(func, "LUA_ON_STOP"); };
- emu["register_pause"] = [this](sol::function func){ register_function(func, "LUA_ON_PAUSE"); };
- emu["register_resume"] = [this](sol::function func){ register_function(func, "LUA_ON_RESUME"); };
- emu["register_frame"] = [this](sol::function func){ register_function(func, "LUA_ON_FRAME"); };
- emu["register_frame_done"] = [this](sol::function func){ register_function(func, "LUA_ON_FRAME_DONE"); };
- emu["register_sound_update"] = [this](sol::function func){ register_function(func, "LUA_ON_SOUND_UPDATE"); };
- emu["register_periodic"] = [this](sol::function func){ register_function(func, "LUA_ON_PERIODIC"); };
- emu["register_mandatory_file_manager_override"] = [this](sol::function func) { register_function(func, "LUA_ON_MANDATORY_FILE_MANAGER_OVERRIDE"); };
+ emu["register_prestart"] = [this] (sol::function func) { register_function(func, "LUA_ON_PRESTART"); };
+ emu["register_start"] = [this] (sol::function func) { register_function(func, "LUA_ON_START"); };
+ emu["register_stop"] = [this] (sol::function func) { register_function(func, "LUA_ON_STOP"); };
+ emu["register_pause"] = [this] (sol::function func) { register_function(func, "LUA_ON_PAUSE"); };
+ emu["register_resume"] = [this] (sol::function func) { register_function(func, "LUA_ON_RESUME"); };
+ emu["register_frame"] = [this] (sol::function func) { register_function(func, "LUA_ON_FRAME"); };
+ emu["register_frame_done"] = [this] (sol::function func) { register_function(func, "LUA_ON_FRAME_DONE"); };
+ emu["register_sound_update"] = [this] (sol::function func) { register_function(func, "LUA_ON_SOUND_UPDATE"); };
+ emu["register_periodic"] = [this] (sol::function func) { register_function(func, "LUA_ON_PERIODIC"); };
+ emu["register_mandatory_file_manager_override"] = [this] (sol::function func) { register_function(func, "LUA_ON_MANDATORY_FILE_MANAGER_OVERRIDE"); };
emu["register_before_load_settings"] = [this](sol::function func) { register_function(func, "LUA_ON_BEFORE_LOAD_SETTINGS"); };
- emu["register_menu"] = [this](sol::function cb, sol::function pop, const std::string &name) {
+ emu["register_menu"] =
+ [this] (sol::function cb, sol::function pop, const std::string &name)
+ {
std::string cbfield = "menu_cb_" + name;
std::string popfield = "menu_pop_" + name;
sol().registry()[cbfield] = cb;
sol().registry()[popfield] = pop;
m_menu.push_back(name);
};
- emu["show_menu"] = [this](const char *name) {
+ emu["show_menu"] =
+ [this](const char *name)
+ {
mame_ui_manager &mui = mame_machine_manager::instance()->ui();
render_container &container = machine().render().ui_container();
ui::menu_plugin::show_menu(mui, container, (char *)name);
};
- emu["register_callback"] = [this](sol::function cb, const std::string &name) {
+ emu["register_callback"] =
+ [this] (sol::function cb, const std::string &name)
+ {
std::string field = "cb_" + name;
sol().registry()[field] = cb;
};
- emu["print_verbose"] = [](const char *str) { osd_printf_verbose("%s\n", str); };
- emu["print_error"] = [](const char *str) { osd_printf_error("%s\n", str); };
- emu["print_info"] = [](const char *str) { osd_printf_info("%s\n", str); };
- emu["print_debug"] = [](const char *str) { osd_printf_debug("%s\n", str); };
- emu["driver_find"] = [this](const char *driver) -> sol::object {
- int i = driver_list::find(driver);
- if(i == -1)
+ emu["print_verbose"] = [] (const char *str) { osd_printf_verbose("%s\n", str); };
+ emu["print_error"] = [] (const char *str) { osd_printf_error("%s\n", str); };
+ emu["print_info"] = [] (const char *str) { osd_printf_info("%s\n", str); };
+ emu["print_debug"] = [] (const char *str) { osd_printf_debug("%s\n", str); };
+ emu["driver_find"] =
+ [this] (const char *driver) -> sol::object
+ {
+ const int i = driver_list::find(driver);
+ if (i < 0)
return sol::make_object(sol(), sol::lua_nil);
return sol::make_object(sol(), driver_list::driver(i));
};
- emu["wait"] = lua_CFunction([](lua_State *L) {
- lua_engine *engine = mame_machine_manager::instance()->lua();
- luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
- int ret = lua_pushthread(L);
- if(ret == 1)
- return luaL_error(L, "cannot wait from outside coroutine");
- int ref = luaL_ref(L, LUA_REGISTRYINDEX);
- engine->machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), engine), ref, nullptr);
- return lua_yield(L, 0);
- });
+ emu["wait"] = lua_CFunction(
+ [](lua_State *L)
+ {
+ lua_engine *engine = mame_machine_manager::instance()->lua();
+ luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
+ int ret = lua_pushthread(L);
+ if (ret == 1)
+ return luaL_error(L, "cannot wait from outside coroutine");
+ int ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ engine->machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), engine), ref, nullptr);
+ return lua_yield(L, 0);
+ });
emu["lang_translate"] = &lang_translate;
emu["pid"] = &osd_getpid;
- emu["subst_env"] = [](const std::string &str) {
+ emu["subst_env"] =
+ [] (const std::string &str)
+ {
std::string result;
osd_subst_env(result, str);
return result;
};
+ emu["device_enumerator"] = [] (device_t &d) { return devenum<device_enumerator>(d); };
+ emu["screen_enumerator"] = [] (device_t &d) { return devenum<screen_device_enumerator>(d); };
+ emu["image_enumerator"] = [] (device_t &d) { return devenum<image_interface_enumerator>(d); };
-/* emu_file library
+/* emu_file library
*
* emu.file([opt] searchpath, flags) - flags can be as in osdcore "OPEN_FLAG_*" or lua style
* with 'rwc' with addtional c for create *and truncate*
@@ -820,7 +963,7 @@ void lua_engine::initialize()
});
-/* core_options library
+/* core_options library
*
* manager:options()
* manager:machine():options()
@@ -957,12 +1100,14 @@ void lua_engine::initialize()
*/
auto machine_type = sol().registry().new_usertype<running_machine>("machine", "new", sol::no_constructor);
- machine_type.set("exit", &running_machine::schedule_exit);
- machine_type.set("hard_reset", &running_machine::schedule_hard_reset);
- machine_type.set("soft_reset", &running_machine::schedule_soft_reset);
- machine_type.set("save", &running_machine::schedule_save);
- machine_type.set("load", &running_machine::schedule_load);
- machine_type.set("buffer_save", [](running_machine &m, sol::this_state s) {
+ machine_type["exit"] = &running_machine::schedule_exit;
+ machine_type["hard_reset"] = &running_machine::schedule_hard_reset;
+ machine_type["soft_reset"] = &running_machine::schedule_soft_reset;
+ machine_type["save"] = &running_machine::schedule_save;
+ machine_type["load"] = &running_machine::schedule_load;
+ machine_type["buffer_save"] =
+ [] (running_machine &m, sol::this_state s)
+ {
lua_State *L = s;
luaL_Buffer buff;
int size = ram_state::get_size(m.save());
@@ -975,8 +1120,10 @@ void lua_engine::initialize()
}
luaL_error(L, "State save error.");
return sol::make_reference(L, nullptr);
- });
- machine_type.set("buffer_load", [](running_machine &m, sol::this_state s, std::string str) {
+ };
+ machine_type["buffer_load"] =
+ [] (running_machine &m, sol::this_state s, std::string str)
+ {
lua_State *L = s;
save_error error = m.save().read_buffer((u8 *)str.data(), str.size());
if (error == STATERR_NONE)
@@ -986,65 +1133,36 @@ void lua_engine::initialize()
luaL_error(L,"State load error.");
return false;
}
- });
- machine_type.set("system", &running_machine::system);
- machine_type.set("video", &running_machine::video);
- machine_type.set("sound", &running_machine::sound);
- machine_type.set("render", &running_machine::render);
- machine_type.set("ioport", &running_machine::ioport);
- machine_type.set("parameters", &running_machine::parameters);
- machine_type.set("memory", &running_machine::memory);
- machine_type.set("options", [](running_machine &m) { return static_cast<core_options *>(&m.options()); });
- machine_type.set("outputs", &running_machine::output);
- machine_type.set("input", &running_machine::input);
- machine_type.set("uiinput", &running_machine::ui_input);
- machine_type.set("debugger", [this](running_machine &m) -> sol::object {
+ };
+ machine_type["system"] = &running_machine::system;
+ machine_type["video"] = &running_machine::video;
+ machine_type["sound"] = &running_machine::sound;
+ machine_type["render"] = &running_machine::render;
+ machine_type["ioport"] = &running_machine::ioport;
+ machine_type["parameters"] = &running_machine::parameters;
+ machine_type["memory"] = &running_machine::memory;
+ machine_type["options"] = [] (running_machine &m) { return static_cast<core_options *>(&m.options()); };
+ machine_type["outputs"] = &running_machine::output;
+ machine_type["input"] = &running_machine::input;
+ machine_type["uiinput"] = &running_machine::ui_input;
+ machine_type["debugger"] =
+ [this] (running_machine &m) -> sol::object
+ {
if(!(m.debug_flags & DEBUG_FLAG_ENABLED))
return sol::make_object(sol(), sol::lua_nil);
return sol::make_object(sol(), &m.debugger());
- });
- machine_type.set("paused", sol::property(&running_machine::paused));
- machine_type.set("samplerate", sol::property(&running_machine::sample_rate));
- machine_type.set("exit_pending", sol::property(&running_machine::exit_pending));
- machine_type.set("hard_reset_pending", sol::property(&running_machine::hard_reset_pending));
- machine_type.set("devices", sol::property([this](running_machine &m) {
- std::function<void(device_t &, sol::table)> tree;
- sol::table table = sol().create_table();
- tree = [&tree](device_t &root, sol::table table) {
- for(device_t &dev : root.subdevices())
- {
- if(dev.configured() && dev.started())
- {
- table[dev.tag()] = &dev;
- tree(dev, table);
- }
- }
- };
- tree(m.root_device(), table);
- return table;
- }));
- machine_type.set("screens", sol::property([this](running_machine &r) {
- sol::table table = sol().create_table();
- for (screen_device &sc : screen_device_iterator(r.root_device()))
- {
- if (sc.configured() && sc.started() && sc.type())
- table[sc.tag()] = &sc;
- }
- return table;
- }));
- machine_type.set("images", sol::property([this](running_machine &r) {
- sol::table image_table = sol().create_table();
- for(device_image_interface &image : image_interface_iterator(r.root_device()))
- {
- image_table[image.brief_instance_name()] = &image;
- image_table[image.instance_name()] = &image;
- }
- return image_table;
- }));
- machine_type.set("popmessage", sol::overload(
+ };
+ machine_type["paused"] = sol::property(&running_machine::paused);
+ machine_type["samplerate"] = sol::property(&running_machine::sample_rate);
+ machine_type["exit_pending"] = sol::property(&running_machine::exit_pending);
+ machine_type["hard_reset_pending"] = sol::property(&running_machine::hard_reset_pending);
+ machine_type["devices"] = sol::property([] (running_machine &m) { return devenum<device_enumerator>(m.root_device()); });
+ machine_type["screens"] = sol::property([] (running_machine &m) { return devenum<screen_device_enumerator>(m.root_device()); });
+ machine_type["images"] = sol::property([] (running_machine &m) { return devenum<image_interface_enumerator>(m.root_device()); });
+ machine_type["popmessage"] = sol::overload(
[](running_machine &m, const char *str) { m.popmessage("%s", str); },
- [](running_machine &m) { m.popmessage(); }));
- machine_type.set("logerror", [](running_machine &m, const char *str) { m.logerror("[luaengine] %s\n", str); } );
+ [](running_machine &m) { m.popmessage(); });
+ machine_type["logerror"] = [] (running_machine &m, const char *str) { m.logerror("[luaengine] %s\n", str); };
/* game_driver library
@@ -1270,6 +1388,8 @@ void lua_engine::initialize()
* device:owner() - device parent tag
* device:debug() - debug interface, cpus only
*
+ * device.configured - whether configuration is complete
+ * device.started - whether the device has been started
* device.spaces[] - device address spaces table (k=name, v=addr_space)
* device.state[] - device state entries table (k=name, v=device_state_entry)
* device.items[] - device save state items table (k=name, v=index)
@@ -1277,65 +1397,77 @@ void lua_engine::initialize()
*/
auto device_type = sol().registry().new_usertype<device_t>("device", "new", sol::no_constructor);
- device_type.set("name", &device_t::name);
- device_type.set("shortname", &device_t::shortname);
- device_type.set("tag", &device_t::tag);
- device_type.set("owner", &device_t::owner);
- device_type.set("debug", [this](device_t &dev) -> sol::object {
- if(!(dev.machine().debug_flags & DEBUG_FLAG_ENABLED) || !dynamic_cast<cpu_device *>(&dev)) // debugger not enabled or not cpu
+ device_type["name"] = &device_t::name;
+ device_type["shortname"] = &device_t::shortname;
+ device_type["tag"] = &device_t::tag;
+ device_type["owner"] = &device_t::owner;
+ device_type["debug"] =
+ [this] (device_t &dev) -> sol::object
+ {
+ if (!(dev.machine().debug_flags & DEBUG_FLAG_ENABLED) || !dynamic_cast<cpu_device *>(&dev)) // debugger not enabled or not cpu
return sol::make_object(sol(), sol::lua_nil);
return sol::make_object(sol(), dev.debug());
- });
- device_type.set("spaces", sol::property([this](device_t &dev) {
- device_memory_interface *memdev = dynamic_cast<device_memory_interface *>(&dev);
- sol::table sp_table = sol().create_table();
- if(!memdev)
+ };
+ device_type["configured"] = sol::property(&device_t::configured);
+ device_type["started"] = sol::property(&device_t::started);
+ device_type["spaces"] = sol::property(
+ [this] (device_t &dev)
+ {
+ device_memory_interface *memdev = dynamic_cast<device_memory_interface *>(&dev);
+ sol::table sp_table = sol().create_table();
+ if(!memdev)
+ return sp_table;
+ for(int sp = 0; sp < memdev->max_space_count(); ++sp)
+ {
+ if(memdev->has_space(sp))
+ sp_table[memdev->space(sp).name()] = addr_space(memdev->space(sp), *memdev);
+ }
return sp_table;
- for(int sp = 0; sp < memdev->max_space_count(); ++sp)
+ });
+ device_type["state"] = sol::property(
+ [this] (device_t &dev)
{
- if(memdev->has_space(sp))
- sp_table[memdev->space(sp).name()] = addr_space(memdev->space(sp), *memdev);
- }
- return sp_table;
- }));
- device_type.set("state", sol::property([this](device_t &dev) {
- sol::table st_table = sol().create_table();
- if(!dynamic_cast<device_state_interface *>(&dev))
+ sol::table st_table = sol().create_table();
+ if(!dynamic_cast<device_state_interface *>(&dev))
+ return st_table;
+ // XXX: refrain from exporting non-visible entries?
+ for(auto &s : dev.state().state_entries())
+ st_table[s->symbol()] = s.get();
return st_table;
- // XXX: refrain from exporting non-visible entries?
- for(auto &s : dev.state().state_entries())
- st_table[s->symbol()] = s.get();
- return st_table;
- }));
- device_type.set("items", sol::property([this](device_t &dev) {
- sol::table table = sol().create_table();
- std::string tag = dev.tag();
- // 10000 is enough?
- for(int i = 0; i < 10000; i++)
+ });
+ device_type["items"] = sol::property(
+ [this] (device_t &dev)
{
- std::string name;
- const char *item;
- void *base;
- uint32_t size, valcount, blockcount, stride;
- item = dev.machine().save().indexed_item(i, base, size, valcount, blockcount, stride);
- if(!item)
- break;
- name = &(strchr(item, '/')[1]);
- if(name.substr(0, name.find('/')) == tag)
+ sol::table table = sol().create_table();
+ std::string tag = dev.tag();
+ // 10000 is enough?
+ for(int i = 0; i < 10000; i++)
{
- name = name.substr(name.find('/') + 1, std::string::npos);
- table[name] = i;
+ std::string name;
+ const char *item;
+ void *base;
+ uint32_t size, valcount, blockcount, stride;
+ item = dev.machine().save().indexed_item(i, base, size, valcount, blockcount, stride);
+ if(!item)
+ break;
+ name = &(strchr(item, '/')[1]);
+ if(name.substr(0, name.find('/')) == tag)
+ {
+ name = name.substr(name.find('/') + 1, std::string::npos);
+ table[name] = i;
+ }
}
- }
- return table;
- }));
- device_type.set("roms", sol::property([this](device_t &dev) {
- sol::table table = sol().create_table();
- for(auto rom : dev.rom_region_vector())
- if(!rom.name().empty())
- table[rom.name()] = rom;
- return table;
- }));
+ return table;
+ });
+ device_type["roms"] = sol::property(
+ [this] (device_t &dev)
+ {
+ sol::table table = sol().create_table();
+ for(auto rom : dev.rom_region_vector())
+ if(!rom.name().empty())
+ table[rom.name()] = rom;
+ return table;
+ });
/* parameters_manager library
@@ -1346,9 +1478,9 @@ void lua_engine::initialize()
* parameters:lookup(tag) - get val for tag
*/
- sol().registry().new_usertype<parameters_manager>("parameters", "new", sol::no_constructor,
- "add", &parameters_manager::add,
- "lookup", &parameters_manager::lookup);
+ auto parameters_type = sol().registry().new_usertype<parameters_manager>("parameters", "new", sol::no_constructor);
+ parameters_type["add"] = &parameters_manager::add;
+ parameters_type["lookup"] = &parameters_manager::lookup;
/* video_manager library
@@ -1881,16 +2013,3 @@ void lua_engine::load_string(const char *value)
{
run(sol().load(value));
}
-
-//-------------------------------------------------
-// invoke - invokes a function, wrapping profiler
-//-------------------------------------------------
-
-template<typename TFunc, typename... TArgs>
-sol::protected_function_result lua_engine::invoke(TFunc &&func, TArgs&&... args)
-{
- g_profiler.start(PROFILER_LUA);
- sol::protected_function_result result = func(std::forward<TArgs>(args)...);
- g_profiler.stop();
- return result;
-}