diff options
author | 2020-09-14 00:55:00 +1000 | |
---|---|---|
committer | 2020-09-14 00:55:00 +1000 | |
commit | 9b582574922cb7af1a9a31c1182c300b90a20c43 (patch) | |
tree | d05e9095649fd864c2d83612e62f69d4760c6b26 /src/emu/save.h | |
parent | cba1bff5b0c099d172bcc2cacefd68c50c5f1358 (diff) |
emu/save.h: Added support for saving arrays of attotimes and renamed macros to make purpose more obvious.
Diffstat (limited to 'src/emu/save.h')
-rw-r--r-- | src/emu/save.h | 177 |
1 files changed, 93 insertions, 84 deletions
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 |