1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     drivenum.h
6 
7     Driver enumeration helpers.
8 
9 ***************************************************************************/
10 
11 #ifndef MAME_EMU_DRIVENUM_H
12 #define MAME_EMU_DRIVENUM_H
13 
14 #pragma once
15 
16 #include <algorithm>
17 #include <cassert>
18 #include <memory>
19 
20 
21 //**************************************************************************
22 //  GLOBAL VARIABLES
23 //**************************************************************************
24 
25 GAME_EXTERN(___empty);
26 
27 
28 //**************************************************************************
29 //  TYPE DEFINITIONS
30 //**************************************************************************
31 
32 // ======================> driver_list
33 
34 // driver_list is a purely static class that wraps the global driver list
35 class driver_list
36 {
37 	DISABLE_COPYING(driver_list);
38 
39 protected:
40 	// construction/destruction
41 	driver_list();
42 
43 public:
44 	// getters
total()45 	static std::size_t total() { return s_driver_count; }
46 
47 	// any item by index
driver(std::size_t index)48 	static const game_driver &driver(std::size_t index) { assert(index < total()); return *s_drivers_sorted[index]; }
clone(std::size_t index)49 	static int clone(std::size_t index) { return find(driver(index).parent); }
non_bios_clone(std::size_t index)50 	static int non_bios_clone(std::size_t index) { int const result = find(driver(index).parent); return ((result >= 0) && !(driver(result).flags & MACHINE_IS_BIOS_ROOT)) ? result : -1; }
compatible_with(std::size_t index)51 	static int compatible_with(std::size_t index) { return find(driver(index).compatible_with); }
52 
53 	// any item by driver
clone(const game_driver & driver)54 	static int clone(const game_driver &driver) { int const index = find(driver); assert(index >= 0); return clone(index); }
non_bios_clone(const game_driver & driver)55 	static int non_bios_clone(const game_driver &driver) { int const index = find(driver); assert(index >= 0); return non_bios_clone(index); }
compatible_with(const game_driver & driver)56 	static int compatible_with(const game_driver &driver) { int const index = find(driver); assert(index >= 0); return compatible_with(index); }
57 
58 	// general helpers
59 	static int find(const char *name);
find(const game_driver & driver)60 	static int find(const game_driver &driver) { return find(driver.name); }
61 
62 	// static helpers
63 	static bool matches(const char *wildstring, const char *string);
64 
65 protected:
66 	static std::size_t const            s_driver_count;
67 	static game_driver const * const    s_drivers_sorted[];
68 };
69 
70 
71 // ======================> driver_enumerator
72 
73 // driver_enumerator enables efficient iteration through the driver list
74 class driver_enumerator : public driver_list
75 {
76 	DISABLE_COPYING(driver_enumerator);
77 
78 public:
79 	// construction/destruction
80 	driver_enumerator(emu_options &options);
81 	driver_enumerator(emu_options &options, const char *filter);
82 	driver_enumerator(emu_options &options, const game_driver &filter);
83 	~driver_enumerator();
84 
85 	// getters
count()86 	std::size_t count() const { return m_filtered_count; }
current()87 	int current() const { return m_current; }
options()88 	emu_options &options() const { return m_options; }
89 
90 	// current item
driver()91 	const game_driver &driver() const { return driver_list::driver(m_current); }
config()92 	std::shared_ptr<machine_config> const &config() const { return config(m_current, m_options); }
clone()93 	int clone() const { return driver_list::clone(m_current); }
non_bios_clone()94 	int non_bios_clone() const { return driver_list::non_bios_clone(m_current); }
compatible_with()95 	int compatible_with() const { return driver_list::compatible_with(m_current); }
include()96 	void include() { include(m_current); }
exclude()97 	void exclude() { exclude(m_current); }
98 
99 	// any item by index
included(std::size_t index)100 	bool included(std::size_t index) const { assert(index < m_included.size()); return m_included[index]; }
excluded(std::size_t index)101 	bool excluded(std::size_t index) const { assert(index < m_included.size()); return !m_included[index]; }
config(std::size_t index)102 	std::shared_ptr<machine_config> const &config(std::size_t index) const { return config(index, m_options); }
103 	std::shared_ptr<machine_config> const &config(std::size_t index, emu_options &options) const;
include(std::size_t index)104 	void include(std::size_t index) { assert(index < m_included.size()); if (!m_included[index]) { m_included[index] = true; m_filtered_count++; }  }
exclude(std::size_t index)105 	void exclude(std::size_t index) { assert(index < m_included.size()); if (m_included[index]) { m_included[index] = false; m_filtered_count--; } }
106 	using driver_list::driver;
107 	using driver_list::clone;
108 	using driver_list::non_bios_clone;
109 	using driver_list::compatible_with;
110 
111 	// filtering/iterating
112 	std::size_t filter(const char *string = nullptr);
113 	std::size_t filter(const game_driver &driver);
114 	void include_all();
exclude_all()115 	void exclude_all() { std::fill(m_included.begin(), m_included.end(), false); m_filtered_count = 0; }
reset()116 	void reset() { m_current = -1; }
117 	bool next();
118 	bool next_excluded();
119 
120 	// general helpers
set_current(std::size_t index)121 	void set_current(std::size_t index) { assert(index < s_driver_count); m_current = index; }
122 	void find_approximate_matches(std::string const &string, std::size_t count, int *results);
123 
124 private:
125 	static constexpr std::size_t CONFIG_CACHE_COUNT = 100;
126 
127 	typedef util::lru_cache_map<std::size_t, std::shared_ptr<machine_config> > machine_config_cache;
128 
129 	// internal helpers
130 	void release_current() const;
131 
132 	// internal state
133 	int                             m_current;
134 	std::size_t                     m_filtered_count;
135 	emu_options &                   m_options;
136 	std::vector<bool>               m_included;
137 	mutable machine_config_cache    m_config;
138 };
139 
140 #endif // MAME_EMU_DRIVENUM_H
141