summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend
diff options
context:
space:
mode:
authorGravatarGravatar R. Belmont <rb6502@users.noreply.github.com>2019-08-05 15:42:05 -0400
committerGravatarGravatar GitHub <noreply@github.com>2019-08-05 15:42:05 -0400
commit43fc80c5aa4fc09d712b00b47908f472cb4dc7f1 (patch)
tree4ca324612fbfb8b919b04cbdfa0e55a023687108 /src/frontend
parent9c89109d15a1c43563c40eee624e3d033fcbb891 (diff)
parent12e0982f3cdb8d1683884847ad628663407706b7 (diff)
Merge pull request #5438 from npwoods/lua_manadatory_file_manager_override_changes
Changed mechanisms for overriding the mandatory file manager
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/mame/luaengine.cpp56
-rw-r--r--src/frontend/mame/luaengine.h2
-rw-r--r--src/frontend/mame/mame.cpp26
-rw-r--r--src/frontend/mame/mame.h2
-rw-r--r--src/frontend/mame/ui/info.cpp29
-rw-r--r--src/frontend/mame/ui/info.h1
-rw-r--r--src/frontend/mame/ui/ui.cpp39
7 files changed, 112 insertions, 43 deletions
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index bb4c585516a..0182a5cbeeb 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -650,17 +650,23 @@ bool lua_engine::menu_callback(const std::string &menu, int index, const std::st
return ret;
}
-bool lua_engine::execute_function(const char *id)
+int lua_engine::enumerate_functions(const char *id, std::function<bool(const sol::protected_function &func)> &&callback)
{
+ int count = 0;
sol::object functable = sol().registry()[id];
- if(functable.is<sol::table>())
+ if (functable.is<sol::table>())
{
- for(auto &func : functable.as<sol::table>())
+ for (auto &func : functable.as<sol::table>())
{
- if(func.second.is<sol::protected_function>())
+ if (func.second.is<sol::protected_function>())
{
+ bool cont = callback(func.second.as<sol::protected_function>());
+ count++;
+ if (!cont)
+ break;
+
auto ret = invoke(func.second.as<sol::protected_function>());
- if(!ret.valid())
+ if (!ret.valid())
{
sol::error err = ret;
osd_printf_error("[LUA ERROR] in execute_function: %s\n", err.what());
@@ -669,7 +675,22 @@ bool lua_engine::execute_function(const char *id)
}
return true;
}
- return false;
+ return count;
+}
+
+bool lua_engine::execute_function(const char *id)
+{
+ int count = enumerate_functions(id, [this](const sol::protected_function &func)
+ {
+ auto ret = invoke(func);
+ if(!ret.valid())
+ {
+ sol::error err = ret;
+ osd_printf_error("[LUA ERROR] in execute_function: %s\n", err.what());
+ }
+ return true;
+ });
+ return count > 0;
}
void lua_engine::register_function(sol::function func, const char *id)
@@ -721,6 +742,27 @@ void lua_engine::on_periodic()
execute_function("LUA_ON_PERIODIC");
}
+bool lua_engine::on_missing_mandatory_image(const std::string &instance_name)
+{
+ bool handled = false;
+ enumerate_functions("LUA_ON_MANDATORY_FILE_MANAGER_OVERRIDE", [this, &instance_name, &handled](const sol::protected_function &func)
+ {
+ auto ret = invoke(func, instance_name);
+
+ if(!ret.valid())
+ {
+ sol::error err = ret;
+ osd_printf_error("[LUA ERROR] in on_missing_mandatory_image: %s\n", err.what());
+ }
+ else if (ret.get<bool>())
+ {
+ handled = true;
+ }
+ return !handled;
+ });
+ return handled;
+}
+
void lua_engine::attach_notifiers()
{
machine().add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&lua_engine::on_machine_prestart, this), true);
@@ -767,6 +809,7 @@ void lua_engine::initialize()
* emu.register_periodic(callback) - register periodic callback while program is running
* emu.register_callback(callback, name) - register callback to be used by MAME via lua_engine::call_plugin()
* emu.register_menu(event_callback, populate_callback, name) - register callbacks for plugin menu
+ * emu.register_mandatory_file_manager_override(callback) - register callback invoked to override mandatory file manager
* emu.show_menu(menu_name) - show menu by name and pause the machine
*
* emu.print_verbose(str) - output to stderr at verbose level
@@ -806,6 +849,7 @@ void lua_engine::initialize()
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_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_menu"] = [this](sol::function cb, sol::function pop, const std::string &name) {
std::string cbfield = "menu_cb_" + name;
std::string popfield = "menu_pop_" + name;
diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h
index 2937b723b74..b5938d2aee8 100644
--- a/src/frontend/mame/luaengine.h
+++ b/src/frontend/mame/luaengine.h
@@ -50,6 +50,7 @@ public:
void attach_notifiers();
void on_frame_done();
void on_periodic();
+ bool on_missing_mandatory_image(const std::string &instance_name);
template<typename T, typename U>
bool call_plugin(const std::string &name, const T in, U &out)
@@ -126,6 +127,7 @@ private:
void resume(void *ptr, int nparam);
void register_function(sol::function func, const char *id);
+ int enumerate_functions(const char *id, std::function<bool(const sol::protected_function &func)> &&callback);
bool execute_function(const char *id);
sol::object call_plugin(const std::string &name, sol::object in);
diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp
index b7ec46717d3..1266370fe4b 100644
--- a/src/frontend/mame/mame.cpp
+++ b/src/frontend/mame/mame.cpp
@@ -341,6 +341,32 @@ void mame_machine_manager::load_cheatfiles(running_machine& machine)
m_cheat = std::make_unique<cheat_manager>(machine);
}
+//-------------------------------------------------
+// missing_mandatory_images - search for devices
+// which need an image to be loaded
+//-------------------------------------------------
+
+std::vector<std::reference_wrapper<const std::string>> mame_machine_manager::missing_mandatory_images()
+{
+ std::vector<std::reference_wrapper<const std::string>> results;
+ assert(m_machine);
+
+ // make sure that any required image has a mounted file
+ for (device_image_interface &image : image_interface_iterator(m_machine->root_device()))
+ {
+ if (image.must_be_loaded())
+ {
+ if (m_machine->options().image_option(image.instance_name()).value().empty())
+ {
+ // this is a missing image; give LUA plugins a chance to handle it
+ if (!lua()->on_missing_mandatory_image(image.instance_name()))
+ results.push_back(std::reference_wrapper<const std::string>(image.instance_name()));
+ }
+ }
+ }
+ return results;
+}
+
const char * emulator_info::get_bare_build_version() { return bare_build_version; }
const char * emulator_info::get_build_version() { return build_version; }
diff --git a/src/frontend/mame/mame.h b/src/frontend/mame/mame.h
index 01a7235972b..36a284ed978 100644
--- a/src/frontend/mame/mame.h
+++ b/src/frontend/mame/mame.h
@@ -50,6 +50,8 @@ public:
virtual void ui_initialize(running_machine& machine) override;
+ std::vector<std::reference_wrapper<const std::string>> missing_mandatory_images();
+
/* execute as configured by the OPTION_SYSTEMNAME option on the specified options */
int execute();
void start_luaengine();
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index 46d092722d2..b28af0eb817 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -408,35 +408,6 @@ std::string machine_info::game_info_string() const
//-------------------------------------------------
-// mandatory_images - search for devices which
-// need an image to be loaded
-//-------------------------------------------------
-
-std::string machine_info::mandatory_images() const
-{
- std::ostringstream buf;
- bool is_first = true;
-
- // make sure that any required image has a mounted file
- for (device_image_interface &image : image_interface_iterator(m_machine.root_device()))
- {
- if (image.must_be_loaded())
- {
- if (m_machine.options().image_option(image.instance_name()).value().empty())
- {
- if (is_first)
- is_first = false;
- else
- buf << ", ";
- buf << "\"" << image.instance_name() << "\"";
- }
- }
- }
- return buf.str();
-}
-
-
-//-------------------------------------------------
// get_screen_desc - returns the description for
// a given screen
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index 2aa5b99c63c..a3746ce6b03 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -76,7 +76,6 @@ public:
// text generators
std::string warnings_string() const;
std::string game_info_string() const;
- std::string mandatory_images() const;
std::string get_screen_desc(screen_device &screen) const;
private:
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index e3d48c13be1..ce1ea2855c1 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -274,6 +274,26 @@ void mame_ui_manager::set_handler(ui_callback_type callback_type, const std::fun
//-------------------------------------------------
+// output_joined_collection
+//-------------------------------------------------
+
+template<typename TColl, typename TEmitMemberFunc, typename TEmitDelimFunc>
+static void output_joined_collection(const TColl &collection, TEmitMemberFunc emit_member, TEmitDelimFunc emit_delim)
+{
+ bool is_first = true;
+
+ for (const auto &member : collection)
+ {
+ if (is_first)
+ is_first = false;
+ else
+ emit_delim();
+ emit_member(member);
+ }
+}
+
+
+//-------------------------------------------------
// display_startup_screens - display the
// various startup screens
//-------------------------------------------------
@@ -283,13 +303,13 @@ void mame_ui_manager::display_startup_screens(bool first_time)
const int maxstate = 3;
int str = machine().options().seconds_to_run();
bool show_gameinfo = !machine().options().skip_gameinfo();
- bool show_warnings = true, show_mandatory_fileman = !machine().options().skip_mandatory_fileman();
+ bool show_warnings = true;
bool video_none = strcmp(downcast<osd_options &>(machine().options()).video(), "none") == 0;
// disable everything if we are using -str for 300 or fewer seconds, or if we're the empty driver,
// or if we are debugging, or if there's no mame window to send inputs to
if (!first_time || (str > 0 && str < 60*5) || &machine().system() == &GAME_NAME(___empty) || (machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 || video_none)
- show_gameinfo = show_warnings = show_mandatory_fileman = false;
+ show_gameinfo = show_warnings = false;
#if defined(EMSCRIPTEN)
// also disable for the JavaScript port since the startup screens do not run asynchronously
@@ -326,12 +346,17 @@ void mame_ui_manager::display_startup_screens(bool first_time)
break;
case 2:
- if (show_mandatory_fileman)
- messagebox_text = machine_info().mandatory_images();
- if (!messagebox_text.empty())
+ std::vector<std::reference_wrapper<const std::string>> mandatory_images = mame_machine_manager::instance()->missing_mandatory_images();
+ if (!mandatory_images.empty())
{
- std::string warning = std::string(_("This driver requires images to be loaded in the following device(s): ")) + messagebox_text;
- ui::menu_file_manager::force_file_manager(*this, machine().render().ui_container(), warning.c_str());
+ std::ostringstream warning;
+ warning << _("This driver requires images to be loaded in the following device(s): ");
+
+ output_joined_collection(mandatory_images,
+ [&warning](const std::reference_wrapper<const std::string> &img) { warning << "\"" << img.get() << "\""; },
+ [&warning]() { warning << ","; });
+
+ ui::menu_file_manager::force_file_manager(*this, machine().render().ui_container(), warning.str().c_str());
}
break;
}