diff options
author | 2019-01-14 04:55:29 +1100 | |
---|---|---|
committer | 2019-01-15 03:56:30 +1100 | |
commit | ae727d2cc640fef650d6c76694b83b159d3065ba (patch) | |
tree | c1c5b58eb3a9d51a43737dca62a59b482f7245f2 /src/frontend/mame/ui/utils.cpp | |
parent | 8f330896e2f8b1fc8ec54023fb5d134dc8a5c3d3 (diff) |
UI cleanup continues:
* Fix crash on builds with fewer than 16 drivers
* Fix "available" filter in internal UI
* Get rid of some UI globals that shouldn't be global
* Better encapsulation in UI
* Clean up favourites manager - in particular kill hidden state and O(n) walks
* This breaks adding systems/software to favourites from the main tab menu
Diffstat (limited to 'src/frontend/mame/ui/utils.cpp')
-rw-r--r-- | src/frontend/mame/ui/utils.cpp | 298 |
1 files changed, 136 insertions, 162 deletions
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp index f82435d3864..baebce20bb3 100644 --- a/src/frontend/mame/ui/utils.cpp +++ b/src/frontend/mame/ui/utils.cpp @@ -99,26 +99,6 @@ constexpr char const *SOFTWARE_FILTER_NAMES[software_filter::COUNT] = { //------------------------------------------------- -// static filter data -//------------------------------------------------- - -std::mutex f_filter_data_mutex; -std::condition_variable f_filter_data_condition; -std::atomic<bool> f_mnfct_finalised(false), f_year_finalised(false); -std::vector<std::string> f_mnfct_ui, f_year_ui; -std::unordered_set<std::string> f_mnfct_tmp, f_year_tmp; - -std::string trim_manufacturer(std::string const &mfg) -{ - size_t const found(mfg.find('(')); - if ((found != std::string::npos) && (found > 0)) - return mfg.substr(0, found - 1); - else - return mfg; -} - - -//------------------------------------------------- // base implementation for simple filters //------------------------------------------------- @@ -664,7 +644,7 @@ template <machine_filter::type Type = machine_filter::AVAILABLE> class available_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - available_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + available_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return system.available; } }; @@ -674,7 +654,7 @@ template <machine_filter::type Type = machine_filter::WORKING> class working_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - working_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + working_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return !(system.driver->flags & machine_flags::NOT_WORKING); } }; @@ -684,7 +664,7 @@ template <machine_filter::type Type = machine_filter::MECHANICAL> class mechanical_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - mechanical_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + mechanical_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return system.driver->flags & machine_flags::MECHANICAL; } }; @@ -694,7 +674,7 @@ template <machine_filter::type Type = machine_filter::BIOS> class bios_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - bios_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + bios_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return system.driver->flags & machine_flags::IS_BIOS_ROOT; } }; @@ -704,7 +684,7 @@ template <machine_filter::type Type = machine_filter::PARENTS> class parents_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - parents_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + parents_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { @@ -719,7 +699,7 @@ template <machine_filter::type Type = machine_filter::CHD> class chd_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - chd_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + chd_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { @@ -737,7 +717,7 @@ template <machine_filter::type Type = machine_filter::SAVE> class save_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - save_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + save_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return system.driver->flags & machine_flags::SUPPORTS_SAVE; } }; @@ -747,7 +727,7 @@ template <machine_filter::type Type = machine_filter::VERTICAL> class vertical_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - vertical_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + vertical_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return system.driver->flags & machine_flags::SWAP_XY; } }; @@ -761,8 +741,8 @@ public: class manufacturer_machine_filter : public choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER> { public: - manufacturer_machine_filter(char const *value, emu_file *file, unsigned indent) - : choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER>(c_mnfct::ui(), value) + manufacturer_machine_filter(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) + : choice_filter_impl_base<machine_filter, machine_filter::MANUFACTURER>(data.manufacturers(), value) { } @@ -773,7 +753,7 @@ public: else if (!selection_valid()) return false; - std::string const name(trim_manufacturer(system.driver->manufacturer)); + std::string const name(machine_filter_data::extract_manufacturer(system.driver->manufacturer)); return !name.empty() && (selection_text() == name); } }; @@ -782,8 +762,8 @@ public: class year_machine_filter : public choice_filter_impl_base<machine_filter, machine_filter::YEAR> { public: - year_machine_filter(char const *value, emu_file *file, unsigned indent) - : choice_filter_impl_base<machine_filter, machine_filter::YEAR>(c_year::ui(), value) + year_machine_filter(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) + : choice_filter_impl_base<machine_filter, machine_filter::YEAR>(data.years(), value) { } @@ -800,7 +780,10 @@ template <template <machine_filter::type T> class Base, machine_filter::type Typ class inverted_machine_filter : public Base<Type> { public: - inverted_machine_filter(char const *value, emu_file *file, unsigned indent) : Base<Type>(value, file, indent) { } + inverted_machine_filter(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) + : Base<Type>(data, value, file, indent) + { + } virtual bool apply(ui_system_info const &system) const override { return !Base<Type>::apply(system); } }; @@ -833,7 +816,7 @@ template <machine_filter::type Type> class inclusive_machine_filter_impl : public simple_filter_impl_base<machine_filter, Type> { public: - inclusive_machine_filter_impl(char const *value, emu_file *file, unsigned indent) { } + inclusive_machine_filter_impl(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { } virtual bool apply(ui_system_info const &system) const override { return true; } }; @@ -850,7 +833,7 @@ using favorite_machine_filter = inclusive_machine_filter_impl<machine_filt class category_machine_filter : public simple_filter_impl_base<machine_filter, machine_filter::CATEGORY> { public: - category_machine_filter(char const *value, emu_file *file, unsigned indent) + category_machine_filter(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) : m_ini(0) , m_group(0) , m_include_clones(false) @@ -1183,14 +1166,15 @@ void category_machine_filter::menu_configure::handle() class custom_machine_filter : public composite_filter_impl_base<custom_machine_filter, machine_filter, machine_filter::CUSTOM> { public: - custom_machine_filter(char const *value, emu_file *file, unsigned indent) + custom_machine_filter(machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) : composite_filter_impl_base<custom_machine_filter, machine_filter, machine_filter::CUSTOM>() + , m_data(data) { populate(value, file, indent); } - ptr create(type n) const { return machine_filter::create(n); } - ptr create(emu_file &file, unsigned indent) const { return machine_filter::create(file, indent); } + ptr create(type n) const { return machine_filter::create(n, m_data); } + ptr create(emu_file &file, unsigned indent) const { return machine_filter::create(file, m_data, indent); } static bool type_allowed(unsigned pos, type n) { @@ -1234,6 +1218,9 @@ public: { return (CATEGORY == n) || (MANUFACTURER == n) || (YEAR == n); } + +private: + machine_filter_data const &m_data; }; @@ -1462,20 +1449,100 @@ private: //------------------------------------------------- +// static data for machine filters +//------------------------------------------------- + +void machine_filter_data::add_manufacturer(std::string const &manufacturer) +{ + std::string name(extract_manufacturer(manufacturer)); + std::vector<std::string>::iterator const pos(std::lower_bound(m_manufacturers.begin(), m_manufacturers.end(), name)); + if ((m_manufacturers.end() == pos) || (*pos != name)) + m_manufacturers.emplace(pos, std::move(name)); +} + +void machine_filter_data::add_year(std::string const &year) +{ + std::vector<std::string>::iterator const pos(std::lower_bound(m_years.begin(), m_years.end(), year)); + if ((m_years.end() == pos) || (*pos != year)) + m_years.emplace(pos, year); +} + +void machine_filter_data::finalise() +{ + std::stable_sort(m_manufacturers.begin(), m_manufacturers.end()); + std::stable_sort(m_years.begin(), m_years.end()); +} + +std::string machine_filter_data::extract_manufacturer(std::string const &manufacturer) +{ + size_t const found(manufacturer.find('(')); + if ((found != std::string::npos) && (found > 0)) + return manufacturer.substr(0, found - 1); + else + return manufacturer; +} + +void machine_filter_data::set_filter(machine_filter::ptr &&filter) +{ + m_filters[filter->get_type()] = std::move(filter); +} + +machine_filter &machine_filter_data::get_filter(machine_filter::type type) +{ + auto it(m_filters.find(type)); + if (m_filters.end() == it) + it = m_filters.emplace(type, machine_filter::create(type, *this)).first; + + assert(it->second); + return *it->second; +} + +std::string machine_filter_data::get_config_string() const +{ + auto const active_filter(m_filters.find(m_current_filter)); + if (m_filters.end() != active_filter) + { + char const *const val(active_filter->second->filter_text()); + return val ? util::string_format("%s,%s", active_filter->second->config_name(), val) : active_filter->second->config_name(); + } + else + { + return machine_filter::config_name(m_current_filter); + } +} + +bool machine_filter_data::load_ini(emu_file &file) +{ + machine_filter::ptr flt(machine_filter::create(file, *this)); + if (flt) + { + // TODO: it should possibly replace an existing item here, but it may be relying on that not happening because it never clears the first start flag + m_current_filter = flt->get_type(); + m_filters.emplace(m_current_filter, std::move(flt)); + return true; + } + else + { + return false; + } +} + + +//------------------------------------------------- // static data for software filters //------------------------------------------------- -void software_filter_data::add_region(std::string const &str) +void software_filter_data::add_region(std::string const &longname) { - std::string name(extract_region(str)); + std::string name(extract_region(longname)); std::vector<std::string>::iterator const pos(std::lower_bound(m_regions.begin(), m_regions.end(), name)); - if ((m_regions.end() == pos) || (*pos != str)) + if ((m_regions.end() == pos) || (*pos != name)) m_regions.emplace(pos, std::move(name)); } -void software_filter_data::add_publisher(std::string const &str) +void software_filter_data::add_publisher(std::string const &publisher) { - std::string name(extract_publisher(str)); + std::string name(extract_publisher(publisher)); std::vector<std::string>::iterator const pos(std::lower_bound(m_publishers.begin(), m_publishers.end(), name)); if ((m_publishers.end() == pos) || (*pos != name)) m_publishers.emplace(pos, std::move(name)); @@ -1540,62 +1607,62 @@ std::string software_filter_data::extract_publisher(std::string const &publisher // public machine filter interface //------------------------------------------------- -machine_filter::ptr machine_filter::create(type n, char const *value, emu_file *file, unsigned indent) +machine_filter::ptr machine_filter::create(type n, machine_filter_data const &data, char const *value, emu_file *file, unsigned indent) { assert(COUNT > n); switch (n) { case ALL: - return std::make_unique<all_machine_filter>(value, file, indent); + return std::make_unique<all_machine_filter>(data, value, file, indent); case AVAILABLE: - return std::make_unique<available_machine_filter>(value, file, indent); + return std::make_unique<available_machine_filter>(data, value, file, indent); case UNAVAILABLE: - return std::make_unique<unavailable_machine_filter>(value, file, indent); + return std::make_unique<unavailable_machine_filter>(data, value, file, indent); case WORKING: - return std::make_unique<working_machine_filter>(value, file, indent); + return std::make_unique<working_machine_filter>(data, value, file, indent); case NOT_WORKING: - return std::make_unique<not_working_machine_filter>(value, file, indent); + return std::make_unique<not_working_machine_filter>(data, value, file, indent); case MECHANICAL: - return std::make_unique<mechanical_machine_filter>(value, file, indent); + return std::make_unique<mechanical_machine_filter>(data, value, file, indent); case NOT_MECHANICAL: - return std::make_unique<not_mechanical_machine_filter>(value, file, indent); + return std::make_unique<not_mechanical_machine_filter>(data, value, file, indent); case CATEGORY: - return std::make_unique<category_machine_filter>(value, file, indent); + return std::make_unique<category_machine_filter>(data, value, file, indent); case FAVORITE: - return std::make_unique<favorite_machine_filter>(value, file, indent); + return std::make_unique<favorite_machine_filter>(data, value, file, indent); case BIOS: - return std::make_unique<bios_machine_filter>(value, file, indent); + return std::make_unique<bios_machine_filter>(data, value, file, indent); case NOT_BIOS: - return std::make_unique<not_bios_machine_filter>(value, file, indent); + return std::make_unique<not_bios_machine_filter>(data, value, file, indent); case PARENTS: - return std::make_unique<parents_machine_filter>(value, file, indent); + return std::make_unique<parents_machine_filter>(data, value, file, indent); case CLONES: - return std::make_unique<clones_machine_filter>(value, file, indent); + return std::make_unique<clones_machine_filter>(data, value, file, indent); case MANUFACTURER: - return std::make_unique<manufacturer_machine_filter>(value, file, indent); + return std::make_unique<manufacturer_machine_filter>(data, value, file, indent); case YEAR: - return std::make_unique<year_machine_filter>(value, file, indent); + return std::make_unique<year_machine_filter>(data, value, file, indent); case SAVE: - return std::make_unique<save_machine_filter>(value, file, indent); + return std::make_unique<save_machine_filter>(data, value, file, indent); case NOSAVE: - return std::make_unique<nosave_machine_filter>(value, file, indent); + return std::make_unique<nosave_machine_filter>(data, value, file, indent); case CHD: - return std::make_unique<chd_machine_filter>(value, file, indent); + return std::make_unique<chd_machine_filter>(data, value, file, indent); case NOCHD: - return std::make_unique<nochd_machine_filter>(value, file, indent); + return std::make_unique<nochd_machine_filter>(data, value, file, indent); case VERTICAL: - return std::make_unique<vertical_machine_filter>(value, file, indent); + return std::make_unique<vertical_machine_filter>(data, value, file, indent); case HORIZONTAL: - return std::make_unique<horizontal_machine_filter>(value, file, indent); + return std::make_unique<horizontal_machine_filter>(data, value, file, indent); case CUSTOM: - return std::make_unique<custom_machine_filter>(value, file, indent); + return std::make_unique<custom_machine_filter>(data, value, file, indent); case COUNT: // not valid, but needed to suppress warnings break; } return nullptr; } -machine_filter::ptr machine_filter::create(emu_file &file, unsigned indent) +machine_filter::ptr machine_filter::create(emu_file &file, machine_filter_data const &data, unsigned indent) { char buffer[MAX_CHAR_INFO]; if (!file.gets(buffer, ARRAY_LENGTH(buffer))) @@ -1620,7 +1687,7 @@ machine_filter::ptr machine_filter::create(emu_file &file, unsigned indent) for (type n = FIRST; COUNT > n; ++n) { if (key == config_name(n)) - return create(n, value.c_str(), &file, indent); + return create(n, data, value.c_str(), &file, indent); } return nullptr; } @@ -1731,115 +1798,22 @@ software_filter::ptr software_filter::create(emu_file &file, software_filter_dat return nullptr; } - -//------------------------------------------------- -// set manufacturers -//------------------------------------------------- - -void c_mnfct::add(std::string &&mfg) -{ - assert(!f_mnfct_finalised.load(std::memory_order_acquire)); - - size_t const found(mfg.find('(')); - if ((found != std::string::npos) && (found > 0)) - mfg.resize(found - 1); - - f_mnfct_tmp.emplace(std::move(mfg)); -} - -void c_mnfct::finalise() -{ - assert(!f_mnfct_finalised.load(std::memory_order_acquire)); - - f_mnfct_ui.reserve(f_mnfct_tmp.size()); - for (auto it = f_mnfct_tmp.begin(); f_mnfct_tmp.end() != it; it = f_mnfct_tmp.erase(it)) - f_mnfct_ui.emplace_back(*it); - std::sort( - f_mnfct_ui.begin(), - f_mnfct_ui.end(), - [] (std::string const &x, std::string const &y) { return 0 > core_stricmp(x.c_str(), y.c_str()); }); - - std::unique_lock<std::mutex> lock(f_filter_data_mutex); - f_mnfct_finalised.store(true, std::memory_order_release); - f_filter_data_condition.notify_all(); -} - -std::vector<std::string> const &c_mnfct::ui() -{ - if (!f_mnfct_finalised.load(std::memory_order_acquire)) - { - std::unique_lock<std::mutex> lock(f_filter_data_mutex); - f_filter_data_condition.wait(lock, [] () { return f_mnfct_finalised.load(std::memory_order_acquire); }); - } - - return f_mnfct_ui; -} - - -//------------------------------------------------- -// set years -//------------------------------------------------- - -void c_year::add(std::string &&year) -{ - assert(!f_year_finalised.load(std::memory_order_acquire)); - - f_year_tmp.emplace(std::move(year)); -} - -void c_year::finalise() -{ - assert(!f_year_finalised.load(std::memory_order_acquire)); - - f_year_ui.reserve(f_year_tmp.size()); - for (auto it = f_year_tmp.begin(); f_year_tmp.end() != it; it = f_year_tmp.erase(it)) - f_year_ui.emplace_back(*it); - std::sort( - f_year_ui.begin(), - f_year_ui.end(), - [] (std::string const &x, std::string const &y) { return 0 > core_stricmp(x.c_str(), y.c_str()); }); - - std::unique_lock<std::mutex> lock(f_filter_data_mutex); - f_year_finalised.store(true, std::memory_order_release); - f_filter_data_condition.notify_all(); -} - -std::vector<std::string> const &c_year::ui() -{ - if (!f_year_finalised.load(std::memory_order_acquire)) - { - std::unique_lock<std::mutex> lock(f_filter_data_mutex); - f_filter_data_condition.wait(lock, [] () { return f_year_finalised.load(std::memory_order_acquire); }); - } - - return f_year_ui; -} - } // namesapce ui extern const char UI_VERSION_TAG[]; const char UI_VERSION_TAG[] = "# UI INFO "; -// Main filters -ui::machine_filter::type main_filters::actual = ui::machine_filter::ALL; -std::map<ui::machine_filter::type, ui::machine_filter::ptr> main_filters::filters; - // Globals uint8_t ui_globals::rpanel = 0; -uint8_t ui_globals::curimage_view = 0; uint8_t ui_globals::curdats_view = 0; uint8_t ui_globals::cur_sw_dats_total = 0; uint8_t ui_globals::curdats_total = 0; uint8_t ui_globals::cur_sw_dats_view = 0; -bool ui_globals::switch_image = false; -bool ui_globals::default_image = true; bool ui_globals::reset = false; -bool ui_globals::redraw_icon = false; int ui_globals::visible_main_lines = 0; int ui_globals::visible_sw_lines = 0; uint16_t ui_globals::panels_status = 0; -bool ui_globals::has_icons = false; char* chartrimcarriage(char str[]) { |