summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
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
commit57fd28d36a082eb0fc6ab48e4ded752eb3179976 (patch)
tree8440d006dceee816e613f8a6e366821bbea27e43 /src/emu
parentcc27fb97e0aa24e734f553ce99ad6484fced8d6f (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.cpp8
-rw-r--r--src/emu/device.h68
-rw-r--r--src/emu/drawgfx.h2
-rw-r--r--src/emu/mconfig.cpp13
-rw-r--r--src/emu/mconfig.h18
-rw-r--r--src/emu/tilemap.h2
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