diff options
Diffstat (limited to 'src/emu/mconfig.h')
-rw-r--r-- | src/emu/mconfig.h | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 03a35fb4773..317acc91309 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -48,6 +48,34 @@ class machine_config friend class running_machine; public: + class token + { + public: + token(machine_config &host, device_t &device) : m_host(host), m_device(&device) + { + assert(m_device == m_host.m_current_device); + } + token(token &&that) : m_host(that.m_host), m_device(that.m_device) + { + that.m_device = nullptr; + assert(!m_device || (m_device == m_host.m_current_device)); + } + token(token const &) = delete; + token &operator=(token &&) = delete; + token &operator=(token const &) = delete; + ~token() + { + if (m_device) + { + assert(m_device == m_host.m_current_device); + m_host.m_current_device = nullptr; + } + } + private: + machine_config &m_host; + device_t *m_device; + }; + // construction/destruction machine_config(const game_driver &gamedrv, emu_options &options); ~machine_config(); @@ -67,35 +95,44 @@ public: const internal_layout * m_default_layout; // default layout for this machine // helpers during configuration; not for general use - device_t *device_add(device_t *owner, const char *tag, device_type type, u32 clock); + token begin_configuration(device_t &device) + { + assert(!m_current_device); + m_current_device = &device; + return token(*this, device); + } + device_t *device_add(const char *tag, device_type type, u32 clock); template <typename... Params> - device_t *device_add(device_t *owner, const char *tag, device_type type, const XTAL &clock, Params &&... args) + device_t *device_add(const char *tag, device_type type, const XTAL &clock, Params &&... args) { clock.validate(std::string("Instantiating device ") + tag); - return device_add(owner, tag, type, clock.value(), std::forward<Params>(args)...); + return device_add(tag, type, clock.value(), std::forward<Params>(args)...); } - device_t *device_replace(device_t *owner, const char *tag, device_type type, u32 clock); - device_t *device_replace(device_t *owner, const char *tag, device_type type, const XTAL &xtal); - device_t *device_remove(device_t *owner, const char *tag); + device_t *device_replace(const char *tag, device_type type, u32 clock); + device_t *device_replace(const char *tag, device_type type, const XTAL &xtal); + device_t *device_remove(const char *tag); device_t *device_find(device_t *owner, const char *tag); private: + class current_device_stack; + // internal helpers void remove_references(ATTR_UNUSED device_t &device); // internal state - const game_driver & m_gamedrv; - emu_options & m_options; - std::unique_ptr<device_t> m_root_device; + game_driver const & m_gamedrv; + emu_options & m_options; + std::unique_ptr<device_t> m_root_device; + device_t * m_current_device; }; namespace emu { namespace detail { template <class DeviceClass> template <typename... Params> -DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config &config, device_t *owner, char const *tag, Params &&... args) const +DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config &config, char const *tag, Params &&... args) const { - return dynamic_cast<DeviceClass &>(*config.device_add(owner, tag, *this, std::forward<Params>(args)...)); + return dynamic_cast<DeviceClass &>(*config.device_add(tag, *this, std::forward<Params>(args)...)); } } } // namespace emu::detail @@ -143,11 +180,11 @@ Ends a machine_config. // add/remove devices #define MCFG_DEVICE_ADD(_tag, _type, _clock) \ - device = config.device_add(this, _tag, _type, _clock); + device = config.device_add(_tag, _type, _clock); #define MCFG_DEVICE_REPLACE(_tag, _type, _clock) \ - device = config.device_replace(this, _tag, _type, _clock); + device = config.device_replace(_tag, _type, _clock); #define MCFG_DEVICE_REMOVE(_tag) \ - device = config.device_remove(this, _tag); + device = config.device_remove(_tag); #define MCFG_DEVICE_MODIFY(_tag) \ device = config.device_find(this, _tag); |