diff options
Diffstat (limited to 'src/emu/mconfig.cpp')
-rw-r--r-- | src/emu/mconfig.cpp | 175 |
1 files changed, 93 insertions, 82 deletions
diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp index 7f142ab5958..342651818bc 100644 --- a/src/emu/mconfig.cpp +++ b/src/emu/mconfig.cpp @@ -116,6 +116,61 @@ machine_config::~machine_config() //------------------------------------------------- +// device_add - configuration helper to add a +// new device +//------------------------------------------------- + +device_t *machine_config::device_add(const char *tag, device_type type, u32 clock) +{ + std::pair<const char *, device_t *> const owner(resolve_owner(tag)); + return &add_device(type.create(*this, owner.first, owner.second, clock), owner.second); +} + + +//------------------------------------------------- +// device_replace - configuration helper to +// replace one device with a new device +//------------------------------------------------- + +device_t *machine_config::device_replace(const char *tag, device_type type, u32 clock) +{ + std::tuple<const char *, device_t *, device_t *> const existing(prepare_replace(tag)); + std::unique_ptr<device_t> device(type.create(*this, std::get<0>(existing), std::get<1>(existing), clock)); + return &replace_device(std::move(device), *std::get<1>(existing), std::get<2>(existing)); +} + + +//------------------------------------------------- +// device_remove - configuration helper to +// remove a device +//------------------------------------------------- + +device_t *machine_config::device_remove(const char *tag) +{ + // find the original device by relative tag (must exist) + assert(m_current_device); + device_t *const device = m_current_device->subdevice(tag); + if (device == nullptr) + { + osd_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag); + } + else + { + // make sure we have the old device's actual owner + device_t *const owner = device->owner(); + assert(owner); + + // remove references to the old device + remove_references(*device); + + // let the device's owner do the work + owner->subdevices().m_list.remove(*device); + } + return nullptr; +} + + +//------------------------------------------------- // resolve_owner - get the actual owner and base // tag given tag relative to current context //------------------------------------------------- @@ -134,11 +189,12 @@ std::pair<const char *, device_t *> machine_config::resolve_owner(const char *ta } // go down the path until we're done with it + std::string part; while (strchr(tag, ':')) { const char *next = strchr(tag, ':'); assert(next != tag); - std::string part(tag, next-tag); + part.assign(tag, next - tag); owner = owner->subdevices().find(part); if (!owner) throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part.c_str(), orig_tag); @@ -151,18 +207,40 @@ std::pair<const char *, device_t *> machine_config::resolve_owner(const char *ta //------------------------------------------------- +// prepare_replace - ensure owner is present and +// existing device is removed if necessary +//------------------------------------------------- + +std::tuple<const char *, device_t *, device_t *> machine_config::prepare_replace(const char *tag) +{ + // make sure we have the old device's actual owner + std::pair<const char *, device_t *> const owner(resolve_owner(tag)); + assert(owner.second); + + // remove references to the old device + device_t *const old_device(owner.second->subdevice(owner.first)); + if (old_device) + remove_references(*old_device); + else + osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag); + + return std::make_tuple(owner.first, owner.second, old_device); +} + + +//------------------------------------------------- // add_device - add a new device at the correct // point in the hierarchy //------------------------------------------------- -device_t *machine_config::add_device(std::unique_ptr<device_t> &&device, device_t *owner) +device_t &machine_config::add_device(std::unique_ptr<device_t> &&device, device_t *owner) { - current_device_stack context(*this); + current_device_stack const context(*this); if (owner) { // allocate the new device and append it to the owner's list - device_t *const result = &owner->subdevices().m_list.append(*device.release()); - result->add_machine_configuration(*this); + device_t &result(owner->subdevices().m_list.append(*device.release())); + result.add_machine_configuration(*this); return result; } else @@ -174,91 +252,24 @@ device_t *machine_config::add_device(std::unique_ptr<device_t> &&device, device_ if (driver) driver->set_game_driver(m_gamedrv); m_root_device->add_machine_configuration(*this); - return m_root_device.get(); + return *m_root_device; } } //------------------------------------------------- -// device_add - configuration helper to add a -// new device -//------------------------------------------------- - -device_t *machine_config::device_add(const char *tag, device_type type, u32 clock) -{ - std::pair<const char *, device_t *> const owner(resolve_owner(tag)); - return add_device(type.create(*this, owner.first, owner.second, clock), owner.second); -} - - -//------------------------------------------------- -// device_replace - configuration helper to -// replace one device with a new device +// replace_device - substitute the new device for +// the old one in the owner's list //------------------------------------------------- -device_t *machine_config::device_replace(const char *tag, device_type type, u32 clock) +device_t &machine_config::replace_device(std::unique_ptr<device_t> &&device, device_t &owner, device_t *existing) { - // find the original device by relative tag (must exist) - assert(m_current_device); - device_t *old_device = m_current_device->subdevice(tag); - if (!old_device) - { - osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag); - return device_add(tag, type, clock); - } - else - { - // make sure we have the old device's actual owner - device_t *const owner = old_device->owner(); - assert(owner); - - // remove references to the old device - remove_references(*old_device); - - // allocate the new device and substitute it for the old one in the owner's list - device_t *const new_device = &owner->subdevices().m_list.replace_and_remove(*type.create(*this, tag, owner, clock).release(), *old_device); - current_device_stack context(*this); - new_device->add_machine_configuration(*this); - return new_device; - } -} - - -device_t *machine_config::device_replace(const char *tag, device_type type, const XTAL &clock) -{ - std::string msg = std::string("Replacing device ") + tag; - clock.validate(msg); - return device_replace(tag, type, clock.value()); -} - - -//------------------------------------------------- -// device_remove - configuration helper to -// remove a device -//------------------------------------------------- - -device_t *machine_config::device_remove(const char *tag) -{ - // find the original device by relative tag (must exist) - assert(m_current_device); - device_t *const device = m_current_device->subdevice(tag); - if (device == nullptr) - { - osd_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag); - } - else - { - // make sure we have the old device's actual owner - device_t *const owner = device->owner(); - assert(owner); - - // remove references to the old device - remove_references(*device); - - // let the device's owner do the work - owner->subdevices().m_list.remove(*device); - } - return nullptr; + current_device_stack const context(*this); + device_t &result(existing + ? owner.subdevices().m_list.replace_and_remove(*device.release(), *existing) + : owner.subdevices().m_list.append(*device.release())); + result.add_machine_configuration(*this); + return result; } |