diff options
-rw-r--r-- | src/emu/devfind.h | 11 | ||||
-rw-r--r-- | src/emu/save.h | 177 |
2 files changed, 99 insertions, 89 deletions
diff --git a/src/emu/devfind.h b/src/emu/devfind.h index 668defe4523..958ae16c3bc 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -15,6 +15,7 @@ #include <functional> #include <iterator> +#include <memory> #include <stdexcept> #include <string> #include <type_traits> @@ -1063,11 +1064,11 @@ public: // dynamic allocation of a shared pointer void allocate(u32 entries) { - assert(m_allocated.empty()); - m_allocated.resize(entries); - this->m_target = &m_allocated[0]; + assert(!m_allocated); + m_allocated = std::make_unique<PointerType []>(entries); + this->m_target = m_allocated.get(); m_bytes = entries * sizeof(PointerType); - this->m_base.get().save_item(m_allocated, this->m_tag); + this->m_base.get().save_pointer(m_allocated, this->m_tag, entries); } private: @@ -1086,7 +1087,7 @@ private: // internal state u8 const m_width; size_t m_bytes; - std::vector<PointerType> m_allocated; + std::unique_ptr<PointerType []> m_allocated; }; template <typename PointerType> using optional_shared_ptr = shared_ptr_finder<PointerType, false>; diff --git a/src/emu/save.h b/src/emu/save.h index f015534f02c..c892cd0b2ba 100644 --- a/src/emu/save.h +++ b/src/emu/save.h @@ -55,12 +55,12 @@ typedef named_delegate<void ()> save_prepost_delegate; // saved; in general, this is intended only to be used for specific enum types // defined by your device #define ALLOW_SAVE_TYPE(TYPE) \ - template <> struct save_manager::type_checker<TYPE> { static constexpr bool is_atom = true; static constexpr bool is_pointer = false; } + template <> struct save_manager::is_atom<TYPE> { static constexpr bool value = true; }; // use this as above, but also to declare that std::vector<TYPE> is safe as well -#define ALLOW_SAVE_TYPE_AND_ARRAY(TYPE) \ - ALLOW_SAVE_TYPE(TYPE); \ - template <> inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, std::vector<TYPE> &value, const char *name) { save_memory(device, module, tag, index, name, &value[0], sizeof(TYPE), value.size()); } +#define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE) \ + ALLOW_SAVE_TYPE(TYPE) \ + template <> struct save_manager::is_vector_safe<TYPE> { static constexpr bool value = true; }; // use this for saving members of structures in arrays #define STRUCT_MEMBER(s, m) s, &save_manager::pointer_unwrap<decltype(s)>::underlying_type::m, #s "." #m @@ -98,9 +98,9 @@ class save_manager static underlying_type *ptr(std::array<T, N> &value) { return array_unwrap<T>::ptr(value[0]); } }; - // type_checker is a set of templates to identify valid save types - template <typename ItemType> struct type_checker { static constexpr bool is_atom = false; static constexpr bool is_pointer = false; }; - template <typename ItemType> struct type_checker<ItemType *> { static constexpr bool is_atom = false; static constexpr bool is_pointer = true; }; + // set of templates to identify valid save types + template <typename ItemType> struct is_atom { static constexpr bool value = false; }; + template <typename ItemType> struct is_vector_safe { static constexpr bool value = false; }; class state_entry { @@ -160,10 +160,9 @@ public: // templatized wrapper for general objects and arrays template <typename ItemType> - void save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) + std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) { - static_assert(!type_checker<ItemType>::is_pointer, "Called save_item on a pointer with no count!"); - static_assert(type_checker<typename array_unwrap<ItemType>::underlying_type>::is_atom, "Called save_item on a non-fundamental type!"); + static_assert(!std::is_pointer<ItemType>::value, "Called save_item on a pointer with no count!"); save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT); } @@ -173,16 +172,15 @@ public: { static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_item on a non-matching struct member pointer!"); static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_item on an unaligned struct member!"); - static_assert(!type_checker<ElementType>::is_pointer, "Called save_item on a struct member pointer!"); - static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_item on a non-fundamental type!"); + static_assert(!std::is_pointer<ElementType>::value, "Called save_item on a struct member pointer!"); + static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_item on a non-fundamental type!"); save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value)->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT, sizeof(typename array_unwrap<ItemType>::underlying_type) / sizeof(typename array_unwrap<ElementType>::underlying_type)); } // templatized wrapper for pointers template <typename ItemType> - void save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count) + std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count) { - static_assert(type_checker<typename array_unwrap<ItemType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!"); save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count); } @@ -191,8 +189,8 @@ public: { static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!"); static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_pointer on an unaligned struct member!"); - static_assert(!type_checker<ElementType>::is_pointer, "Called save_pointer on a struct member pointer!"); - static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!"); + static_assert(!std::is_pointer<ElementType>::value, "Called save_pointer on a struct member pointer!"); + static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_pointer on a non-fundamental type!"); save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value[0])->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT * count, sizeof(typename array_unwrap<ItemType>::underlying_type) / sizeof(typename array_unwrap<ElementType>::underlying_type)); } @@ -200,20 +198,79 @@ public: template <typename ItemType> void save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, const char *valname, u32 count) { - static_assert(type_checker<typename array_unwrap<ItemType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!"); + static_assert(is_atom<typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-fundamental type!"); save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count); } template <typename ItemType, typename StructType, typename ElementType> - void save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, ElementType StructType::*element, const char *valname, u32 count) + std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, ElementType StructType::*element, const char *valname, u32 count) { static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!"); static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_pointer on an unaligned struct member!"); - static_assert(!type_checker<ElementType>::is_pointer, "Called save_pointer on a struct member pointer!"); - static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!"); + static_assert(!std::is_pointer<ElementType>::value, "Called save_pointer on a struct member pointer!"); + static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_pointer on a non-fundamental type!"); save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value[0])->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT * count, sizeof(typename array_unwrap<ItemType>::underlying_type) / sizeof(typename array_unwrap<ElementType>::underlying_type)); } + // templatized wrapper for std::vector + template <typename ItemType> + std::enable_if_t<is_vector_safe<typename array_unwrap<ItemType>::underlying_type>::value> save_item(device_t *device, const char *module, const char *tag, int index, std::vector<ItemType> &value, const char *valname) + { + save_pointer(device, module, tag, index, &value[0], valname, value.size()); + } + + // specializations for bitmaps + void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind8 &value, const char *valname) + { + save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); + } + + void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind16 &value, const char *valname) + { + save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); + } + + void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind32 &value, const char *valname) + { + save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); + } + + void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_rgb32 &value, const char *valname) + { + save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); + } + + // specializations for attotimes + template <typename ItemType> + std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) + { + std::string tempstr; + tempstr.assign(valname).append(".attoseconds"); + save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str()); + tempstr.assign(valname).append(".seconds"); + save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str()); + } + + template <typename ItemType> + std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count) + { + std::string tempstr; + tempstr.assign(valname).append(".attoseconds"); + save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str(), count); + tempstr.assign(valname).append(".seconds"); + save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str(), count); + } + + template <typename ItemType> + std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, const char *valname, u32 count) + { + std::string tempstr; + tempstr.assign(valname).append(".attoseconds"); + save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str(), count); + tempstr.assign(valname).append(".seconds"); + save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str(), count); + } + // global memory registration template <typename ItemType> void save_item(ItemType &value, const char *valname, int index = 0) @@ -325,70 +382,22 @@ public: // template specializations to enumerate the fundamental atomic types you are allowed to save -ALLOW_SAVE_TYPE_AND_ARRAY(char) -ALLOW_SAVE_TYPE (bool); // std::vector<bool> may be packed internally -ALLOW_SAVE_TYPE_AND_ARRAY(osd::s8) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::u8) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::s16) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::u16) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::s32) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::u32) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::s64) -ALLOW_SAVE_TYPE_AND_ARRAY(osd::u64) -ALLOW_SAVE_TYPE_AND_ARRAY(PAIR) -ALLOW_SAVE_TYPE_AND_ARRAY(PAIR64) -ALLOW_SAVE_TYPE_AND_ARRAY(float) -ALLOW_SAVE_TYPE_AND_ARRAY(double) -ALLOW_SAVE_TYPE_AND_ARRAY(endianness_t) -ALLOW_SAVE_TYPE_AND_ARRAY(rgb_t) - - - -//************************************************************************** -// INLINE FUNCTIONS -//************************************************************************** - -//------------------------------------------------- -// save_item - specialized save_item for bitmaps -//------------------------------------------------- - -template <> -inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind8 &value, const char *name) -{ - save_memory(device, module, tag, index, name, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); -} - -template <> -inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind16 &value, const char *name) -{ - save_memory(device, module, tag, index, name, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); -} - -template <> -inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind32 &value, const char *name) -{ - save_memory(device, module, tag, index, name, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); -} - -template <> -inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, bitmap_rgb32 &value, const char *name) -{ - save_memory(device, module, tag, index, name, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); -} - - -//------------------------------------------------- -// save_item - specialized save_item for attotimes -//------------------------------------------------- - -template <> -inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, attotime &value, const char *name) -{ - std::string tempstr = std::string(name).append(".attoseconds"); - save_memory(device, module, tag, index, tempstr.c_str(), &value.m_attoseconds, sizeof(value.m_attoseconds)); - tempstr.assign(name).append(".seconds"); - save_memory(device, module, tag, index, tempstr.c_str(), &value.m_seconds, sizeof(value.m_seconds)); -} +ALLOW_SAVE_TYPE_AND_VECTOR(char) +ALLOW_SAVE_TYPE (bool) // std::vector<bool> may be packed internally +ALLOW_SAVE_TYPE_AND_VECTOR(osd::s8) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::u8) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::s16) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::u16) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::s32) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::u32) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::s64) +ALLOW_SAVE_TYPE_AND_VECTOR(osd::u64) +ALLOW_SAVE_TYPE_AND_VECTOR(PAIR) +ALLOW_SAVE_TYPE_AND_VECTOR(PAIR64) +ALLOW_SAVE_TYPE_AND_VECTOR(float) +ALLOW_SAVE_TYPE_AND_VECTOR(double) +ALLOW_SAVE_TYPE_AND_VECTOR(endianness_t) +ALLOW_SAVE_TYPE_AND_VECTOR(rgb_t) #endif // MAME_EMU_SAVE_H |