diff options
author | Vas Crabb <vas@vastheman.com> | 2018-04-28 00:01:30 +1000 |
---|---|---|
committer | Vas Crabb <vas@vastheman.com> | 2018-04-28 00:01:30 +1000 |
commit | 57fd28d36a082eb0fc6ab48e4ded752eb3179976 (patch) | |
tree | 8440d006dceee816e613f8a6e366821bbea27e43 /src/emu | |
parent | cc27fb97e0aa24e734f553ce99ad6484fced8d6f (diff) |
Sarayan made me do it.
Concrete device types now have a call operator that instantiates a
device.
This change means you *must* use DECLARE_DEVICE_TYPE to declare the
public interface of your device, even if it's device_t. If you want
to use private implementation classes, use DEFINE_DEVICE_TYPE_PRIVATE
and instantiate the object finders.
Diffstat (limited to 'src/emu')
-rw-r--r-- | src/emu/device.cpp | 8 | ||||
-rw-r--r-- | src/emu/device.h | 68 | ||||
-rw-r--r-- | src/emu/drawgfx.h | 2 | ||||
-rw-r--r-- | src/emu/mconfig.cpp | 13 | ||||
-rw-r--r-- | src/emu/mconfig.h | 18 | ||||
-rw-r--r-- | src/emu/tilemap.h | 2 |
6 files changed, 68 insertions, 43 deletions
diff --git a/src/emu/device.cpp b/src/emu/device.cpp index a039ec1dc0c..7fa09a20974 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -25,9 +25,9 @@ namespace { struct device_registrations { - device_type_impl *first = nullptr; - device_type_impl *last = nullptr; - device_type_impl *unsorted = nullptr; + device_type_impl_base *first = nullptr; + device_type_impl_base *last = nullptr; + device_type_impl_base *unsorted = nullptr; }; device_registrations &device_registration_data() @@ -53,7 +53,7 @@ device_registrar::const_iterator device_registrar::cend() const } -device_type_impl *device_registrar::register_device(device_type_impl &type) +device_type_impl_base *device_registrar::register_device(device_type_impl_base &type) { device_registrations &data(device_registration_data()); diff --git a/src/emu/device.h b/src/emu/device.h index 8710ae1cf10..36e701eaa16 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -72,7 +72,7 @@ static const char DEVICE_SELF_OWNER[] = "^"; namespace emu { namespace detail { -class device_type_impl; +class device_type_impl_base; struct device_feature @@ -112,9 +112,9 @@ public: { public: typedef std::ptrdiff_t difference_type; - typedef device_type_impl value_type; - typedef device_type_impl *pointer; - typedef device_type_impl &reference; + typedef device_type_impl_base value_type; + typedef device_type_impl_base *pointer; + typedef device_type_impl_base &reference; typedef std::forward_iterator_tag iterator_category; const_iterator() = default; @@ -143,15 +143,15 @@ public: const_iterator cend() const; private: - friend class device_type_impl; + friend class device_type_impl_base; class const_iterator_helper : public const_iterator { public: - const_iterator_helper(device_type_impl *type) { m_type = type; } + const_iterator_helper(device_type_impl_base *type) { m_type = type; } }; - static device_type_impl *register_device(device_type_impl &type); + static device_type_impl_base *register_device(device_type_impl_base &type); }; @@ -165,26 +165,26 @@ auto device_tag_func() { return device_tag_struct<DeviceClass, ShortName, FullNa template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_feature::type Unemulated, device_feature::type Imperfect> auto driver_tag_func() { return driver_tag_struct<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect>{ }; }; -class device_type_impl +class device_type_impl_base { private: friend class device_registrar; - typedef std::unique_ptr<device_t> (*create_func)(device_type_impl const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + typedef std::unique_ptr<device_t> (*create_func)(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); - device_type_impl(device_type_impl const &) = delete; - device_type_impl(device_type_impl &&) = delete; - device_type_impl &operator=(device_type_impl const &) = delete; - device_type_impl &operator=(device_type_impl &&) = delete; + device_type_impl_base(device_type_impl_base const &) = delete; + device_type_impl_base(device_type_impl_base &&) = delete; + device_type_impl_base &operator=(device_type_impl_base const &) = delete; + device_type_impl_base &operator=(device_type_impl_base &&) = delete; template <typename DeviceClass> - static std::unique_ptr<device_t> create_device(device_type_impl const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + static std::unique_ptr<device_t> create_device(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) { return make_unique_clear<DeviceClass>(mconfig, tag, owner, clock); } template <typename DriverClass> - static std::unique_ptr<device_t> create_driver(device_type_impl const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + static std::unique_ptr<device_t> create_driver(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) { assert(!owner); assert(!clock); @@ -200,10 +200,10 @@ private: device_feature::type const m_unemulated_features; device_feature::type const m_imperfect_features; - device_type_impl *m_next; + device_type_impl_base *m_next; public: - device_type_impl(std::nullptr_t) + device_type_impl_base(std::nullptr_t) : m_creator(nullptr) , m_type(typeid(std::nullptr_t)) , m_shortname(nullptr) @@ -216,7 +216,7 @@ public: } template <class DeviceClass, char const *ShortName, char const *FullName, char const *Source> - device_type_impl(device_tag_struct<DeviceClass, ShortName, FullName, Source> (*)()) + device_type_impl_base(device_tag_struct<DeviceClass, ShortName, FullName, Source> (*)()) : m_creator(&create_device<DeviceClass>) , m_type(typeid(DeviceClass)) , m_shortname(ShortName) @@ -229,7 +229,7 @@ public: } template <class DriverClass, char const *ShortName, char const *FullName, char const *Source, device_feature::type Unemulated, device_feature::type Imperfect> - device_type_impl(driver_tag_struct<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect> (*)()) + device_type_impl_base(driver_tag_struct<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect> (*)()) : m_creator(&create_driver<DriverClass>) , m_type(typeid(DriverClass)) , m_shortname(ShortName) @@ -254,8 +254,17 @@ public: } explicit operator bool() const { return bool(m_creator); } - bool operator==(device_type_impl const &that) const { return &that == this; } - bool operator!=(device_type_impl const &that) const { return &that != this; } + bool operator==(device_type_impl_base const &that) const { return &that == this; } + bool operator!=(device_type_impl_base const &that) const { return &that != this; } +}; + + +template <class DeviceClass> +class device_type_impl : public device_type_impl_base +{ +public: + using device_type_impl_base::device_type_impl_base; + template <typename... Params> DeviceClass &operator()(machine_config &config, device_t *owner, char const *tag, Params &&... args) const; }; @@ -265,7 +274,7 @@ inline device_registrar::const_iterator &device_registrar::const_iterator::opera // device types -typedef emu::detail::device_type_impl const &device_type; +typedef emu::detail::device_type_impl_base const &device_type; typedef std::add_pointer_t<device_type> device_type_ptr; extern emu::detail::device_registrar const registered_device_types; @@ -286,13 +295,13 @@ template < constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass, ShortName, FullName, Source, Unemulated, Imperfect>; #define DECLARE_DEVICE_TYPE(Type, Class) \ - extern device_type const Type; \ class Class; \ + extern emu::detail::device_type_impl<Class> const &Type; \ extern template class device_finder<Class, false>; \ extern template class device_finder<Class, true>; #define DECLARE_DEVICE_TYPE_NS(Type, Namespace, Class) \ - extern device_type const Type; \ + extern emu::detail::device_type_impl<Namespace::Class> const &Type; \ extern template class device_finder<Namespace::Class, false>; \ extern template class device_finder<Namespace::Class, true>; @@ -301,16 +310,23 @@ constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass struct Class##_device_traits { static constexpr char const shortname[] = ShortName, fullname[] = FullName, source[] = __FILE__; }; \ constexpr char const Class##_device_traits::shortname[], Class##_device_traits::fullname[], Class##_device_traits::source[]; \ } \ - device_type const Type = device_creator<Class, (Class##_device_traits::shortname), (Class##_device_traits::fullname), (Class##_device_traits::source)>; \ + emu::detail::device_type_impl<Class> const &Type = device_creator<Class, (Class##_device_traits::shortname), (Class##_device_traits::fullname), (Class##_device_traits::source)>; \ template class device_finder<Class, false>; \ template class device_finder<Class, true>; +#define DEFINE_DEVICE_TYPE_PRIVATE(Type, Base, Class, ShortName, FullName) \ + namespace { \ + struct Class##_device_traits { static constexpr char const shortname[] = ShortName, fullname[] = FullName, source[] = __FILE__; }; \ + constexpr char const Class##_device_traits::shortname[], Class##_device_traits::fullname[], Class##_device_traits::source[]; \ + } \ + emu::detail::device_type_impl<Base> const &Type = device_creator<Class, (Class##_device_traits::shortname), (Class##_device_traits::fullname), (Class##_device_traits::source)>; + #define DEFINE_DEVICE_TYPE_NS(Type, Namespace, Class, ShortName, FullName) \ namespace { \ struct Class##_device_traits { static constexpr char const shortname[] = ShortName, fullname[] = FullName, source[] = __FILE__; }; \ constexpr char const Class##_device_traits::shortname[], Class##_device_traits::fullname[], Class##_device_traits::source[]; \ } \ - device_type const Type = device_creator<Namespace::Class, (Class##_device_traits::shortname), (Class##_device_traits::fullname), (Class##_device_traits::source)>; \ + emu::detail::device_type_impl<Namespace::Class> const &Type = device_creator<Namespace::Class, (Class##_device_traits::shortname), (Class##_device_traits::fullname), (Class##_device_traits::source)>; \ template class device_finder<Namespace::Class, false>; \ template class device_finder<Namespace::Class, true>; diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h index e9833de4a30..9827c96900a 100644 --- a/src/emu/drawgfx.h +++ b/src/emu/drawgfx.h @@ -449,7 +449,7 @@ constexpr u32 alpha_blend_r32(u32 d, u32 s, u8 level) // ======================> gfxdecode_device // device type definition -extern const device_type GFXDECODE; +DECLARE_DEVICE_TYPE(GFXDECODE, gfxdecode_device) class gfxdecode_device : public device_t, public device_gfx_interface { diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp index b62b6a3132f..8269fd9d688 100644 --- a/src/emu/mconfig.cpp +++ b/src/emu/mconfig.cpp @@ -106,7 +106,7 @@ machine_config::~machine_config() device_t *machine_config::device_add(device_t *owner, const char *tag, device_type type, u32 clock) { - const char *orig_tag = tag; + char const *const orig_tag = tag; // if the device path is absolute, start from the root if (tag[0] == ':') @@ -122,13 +122,13 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty assert(next != tag); std::string part(tag, next-tag); owner = owner->subdevices().find(part); - if (owner == nullptr) + if (!owner) throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part.c_str(), orig_tag); tag = next+1; } assert(tag[0] != '\0'); - if (owner != nullptr) + if (!owner) { // allocate the new device and append it to the owner's list device_t *const device = &owner->subdevices().m_list.append(*type(*this, tag, owner, clock).release()); @@ -148,13 +148,6 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty } } -device_t *machine_config::device_add(device_t *owner, const char *tag, device_type type, const XTAL &clock) -{ - std::string msg = std::string("Instantiating device ") + tag; - clock.validate(msg); - return device_add(owner, tag, type, clock.value()); -} - //------------------------------------------------- // device_replace - configuration helper to diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 9df51ec9d64..03a35fb4773 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -68,7 +68,12 @@ public: // helpers during configuration; not for general use device_t *device_add(device_t *owner, const char *tag, device_type type, u32 clock); - device_t *device_add(device_t *owner, const char *tag, device_type type, const XTAL &xtal); + template <typename... Params> + device_t *device_add(device_t *owner, 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)...); + } 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); @@ -85,6 +90,17 @@ private: }; +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 +{ + return dynamic_cast<DeviceClass &>(*config.device_add(owner, tag, *this, std::forward<Params>(args)...)); +} + +} } // namespace emu::detail + + //*************************************************************************/ /** @name Machine config start/end macros */ //*************************************************************************/ diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h index 909f4177647..ae62cdc873b 100644 --- a/src/emu/tilemap.h +++ b/src/emu/tilemap.h @@ -711,7 +711,7 @@ private: // ======================> tilemap_device // device type definition -extern const device_type TILEMAP; +DECLARE_DEVICE_TYPE(TILEMAP, tilemap_device) class tilemap_device : public device_t, public tilemap_t |