diff options
| -rw-r--r-- | src/emu/attotime.cpp | 17 | ||||
| -rw-r--r-- | src/emu/attotime.h | 2 | ||||
| -rw-r--r-- | src/emu/emufwd.h | 3 | ||||
| -rw-r--r-- | src/emu/save.h | 111 |
4 files changed, 99 insertions, 34 deletions
diff --git a/src/emu/attotime.cpp b/src/emu/attotime.cpp index a1ba4d9ed61..3ba52c3157a 100644 --- a/src/emu/attotime.cpp +++ b/src/emu/attotime.cpp @@ -8,9 +8,8 @@ ***************************************************************************/ -#include "emucore.h" -#include "eminline.h" -#include "attotime.h" +#include "emu.h" + //************************************************************************** // GLOBAL VARIABLES @@ -170,3 +169,15 @@ std::string attotime::to_string() const int nsec = t.attoseconds() / ATTOSECONDS_PER_NANOSECOND; return util::string_format("%s%04d.%03d,%03d,%03d", sign, int(t.seconds()), nsec/1000000, (nsec/1000)%1000, nsec % 1000); } + + +//------------------------------------------------- +// register_save - register for save states +//------------------------------------------------- + +void attotime::register_save(save_registrar &save) +{ + // use names without m_ prefix for backwards compatibility + save.reg(m_attoseconds, "attoseconds"); + save.reg(m_seconds, "seconds"); +} diff --git a/src/emu/attotime.h b/src/emu/attotime.h index c975bbde0d3..d17a5227967 100644 --- a/src/emu/attotime.h +++ b/src/emu/attotime.h @@ -164,6 +164,8 @@ public: attotime &operator*=(u32 factor); attotime &operator/=(u32 factor); + void register_save(save_registrar &save); + // members seconds_t m_seconds; attoseconds_t m_attoseconds; diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h index b3969a8fc99..171b9f7c5fa 100644 --- a/src/emu/emufwd.h +++ b/src/emu/emufwd.h @@ -210,6 +210,9 @@ class rom_entry; // declared in romload.h class rom_load_manager; +// declared in save.h +class save_registrar; + // declared in schedule.h class device_scheduler; class emu_timer; diff --git a/src/emu/save.h b/src/emu/save.h index cfd674e738e..71e6679a36e 100644 --- a/src/emu/save.h +++ b/src/emu/save.h @@ -70,9 +70,43 @@ typedef named_delegate<void ()> save_prepost_delegate; // TYPE DEFINITIONS //************************************************************************** +class save_manager; class ram_state; class rewinder; +// helper class to provide pass-through interface for saving struct items +class save_registrar +{ + friend class save_manager; + +public: + save_registrar(save_manager &manager, device_t *device, char const *module, char const *tag, int index, char const *valname) : + m_manager(manager), + m_device(device), + m_module(module), + m_tag(tag), + m_valname(valname), + m_inner_index(index), + m_outer_index(-1) + { + } + + template <typename ItemType> + void reg(ItemType &value, const char *valname); + + template <typename ItemType> + void reg(ItemType &value, const char *valname, int index); + +private: + save_manager &m_manager; + device_t *m_device; + char const *m_module; + char const *m_tag; + char const *m_valname; + int m_inner_index; + int m_outer_index; +}; + class save_manager { // stuff for working with arrays @@ -102,6 +136,13 @@ class save_manager template <typename ItemType> struct is_atom : public std::false_type { }; template <typename ItemType> struct is_vector_safe : public std::false_type { }; + // template to query if a type is a struct/union that can be saved; note that bitmap_t is explicitly + // excluded because it is handled as a special case + template <typename ItemType> struct is_saveable_struct + { + static constexpr bool value = (std::is_class<ItemType>::value || std::is_union<ItemType>::value) && !std::is_base_of<bitmap_t, ItemType>::value && !is_atom<ItemType>::value; + }; + class state_entry { public: @@ -166,6 +207,23 @@ public: save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT); } + // templatized wrappers for saving saveable structs + template<typename ItemType> + std::enable_if_t<is_saveable_struct<typename array_unwrap<ItemType>::underlying_type>::value && array_unwrap<ItemType>::SAVE_COUNT == 1> + save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) + { + save_registrar save(*this, device, module, tag, index, valname); + value.register_save(save); + } + template<typename ItemType> + std::enable_if_t<is_saveable_struct<typename array_unwrap<ItemType>::underlying_type>::value && array_unwrap<ItemType>::SAVE_COUNT != 1> + save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) + { + save_registrar save(*this, device, module, tag, index, valname); + for (save.m_outer_index = 0; save.m_outer_index < array_unwrap<ItemType>::SAVE_COUNT; save.m_outer_index++) + array_unwrap<ItemType>::ptr(value)[save.m_outer_index].register_save(save); + } + // templatized wrapper for structure members template <typename ItemType, typename StructType, typename ElementType> void save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, ElementType StructType::*element, const char *valname) @@ -236,37 +294,6 @@ public: 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) @@ -377,6 +404,28 @@ public: }; +template <typename ItemType> +void save_registrar::reg(ItemType &value, const char *valname) +{ + std::string fullname; + if (m_outer_index == -1) + fullname = string_format("%s.%s", m_valname, valname); + else + fullname = string_format("%s[%d].%s", m_valname, m_outer_index, valname); + m_manager.save_item(m_device, m_module, m_tag, m_inner_index, value, fullname.c_str()); +} + +template <typename ItemType> +void save_registrar::reg(ItemType &value, const char *valname, int index) +{ + std::string fullname; + if (m_outer_index == -1) + fullname = string_format("%s.%s[%d]", m_valname, valname, index); + else + fullname = string_format("%s[%d].%s[%d]", m_valname, m_outer_index, valname, index); + m_manager.save_item(m_device, m_module, m_tag, m_inner_index, value, fullname.c_str()); +} + // template specializations to enumerate the fundamental atomic types you are allowed to save ALLOW_SAVE_TYPE_AND_VECTOR(char) ALLOW_SAVE_TYPE (bool) // std::vector<bool> may be packed internally |
