mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	boss: Implement Spotpass service (part 1) (#7232)
* boss: Implement Spotpass service (part 1) * boss: Fix save state (de)serialization. * boss: Fix casing of SpotPass in log messages. * boss: Minor logging improvements. * common: Add boost serialization support for std::variant. --------- Co-authored-by: Rokkubro <lachlanb03@gmail.com> Co-authored-by: FearlessTobi <thm.frey@gmail.com>
This commit is contained in:
		
							parent
							
								
									4d9eedd0d8
								
							
						
					
					
						commit
						24b5ffbfca
					
				
					 7 changed files with 1018 additions and 129 deletions
				
			
		|  | @ -127,6 +127,7 @@ add_library(citra_common STATIC | |||
|     serialization/boost_discrete_interval.hpp | ||||
|     serialization/boost_flat_set.h | ||||
|     serialization/boost_small_vector.hpp | ||||
|     serialization/boost_std_variant.hpp | ||||
|     serialization/boost_vector.hpp | ||||
|     static_lru_cache.h | ||||
|     string_literal.h | ||||
|  |  | |||
							
								
								
									
										204
									
								
								src/common/serialization/boost_std_variant.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								src/common/serialization/boost_std_variant.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,204 @@ | |||
| #ifndef BOOST_SERIALIZATION_STD_VARIANT_HPP | ||||
| #define BOOST_SERIALIZATION_STD_VARIANT_HPP | ||||
| 
 | ||||
| // MS compatible compilers support #pragma once
 | ||||
| #if defined(_MSC_VER) | ||||
| # pragma once | ||||
| #endif | ||||
| 
 | ||||
| /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
 | ||||
| // variant.hpp - non-intrusive serialization of variant types
 | ||||
| //
 | ||||
| // copyright (c) 2019 Samuel Debionne, ESRF
 | ||||
| //
 | ||||
| // Use, modification and distribution is subject to the Boost Software
 | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | ||||
| // http://www.boost.org/LICENSE_1_0.txt)
 | ||||
| //
 | ||||
| // See http://www.boost.org for updates, documentation, and revision history.
 | ||||
| //
 | ||||
| // Widely inspired form boost::variant serialization
 | ||||
| //
 | ||||
| 
 | ||||
| #include <boost/serialization/throw_exception.hpp> | ||||
| 
 | ||||
| #include <variant> | ||||
| 
 | ||||
| #include <boost/archive/archive_exception.hpp> | ||||
| 
 | ||||
| #include <boost/serialization/split_free.hpp> | ||||
| #include <boost/serialization/serialization.hpp> | ||||
| #include <boost/serialization/nvp.hpp> | ||||
| 
 | ||||
| namespace boost { | ||||
| namespace serialization { | ||||
| 
 | ||||
| template<class Archive> | ||||
| struct std_variant_save_visitor | ||||
| { | ||||
|     std_variant_save_visitor(Archive& ar) : | ||||
|         m_ar(ar) | ||||
|     {} | ||||
|     template<class T> | ||||
|     void operator()(T const & value) const | ||||
|     { | ||||
|         m_ar << BOOST_SERIALIZATION_NVP(value); | ||||
|     } | ||||
| private: | ||||
|     Archive & m_ar; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| template<class Archive> | ||||
| struct std_variant_load_visitor | ||||
| { | ||||
|     std_variant_load_visitor(Archive& ar) : | ||||
|         m_ar(ar) | ||||
|     {} | ||||
|     template<class T> | ||||
|     void operator()(T & value) const | ||||
|     { | ||||
|         m_ar >> BOOST_SERIALIZATION_NVP(value); | ||||
|     } | ||||
| private: | ||||
|     Archive & m_ar; | ||||
| }; | ||||
| 
 | ||||
| template<class Archive, class ...Types> | ||||
| void save( | ||||
|     Archive & ar, | ||||
|     std::variant<Types...> const & v, | ||||
|     unsigned int /*version*/ | ||||
| ){ | ||||
|     const std::size_t which = v.index(); | ||||
|     ar << BOOST_SERIALIZATION_NVP(which); | ||||
|     std_variant_save_visitor<Archive> visitor(ar); | ||||
|     std::visit(visitor, v); | ||||
| } | ||||
| 
 | ||||
| // Minimalist metaprogramming for handling parameter pack
 | ||||
| namespace mp { | ||||
|     namespace detail { | ||||
|     template <typename Seq> | ||||
|     struct front_impl; | ||||
| 
 | ||||
|     template <template <typename...> class Seq, typename T, typename... Ts> | ||||
|     struct front_impl<Seq<T, Ts...>> { | ||||
|         using type = T; | ||||
|     }; | ||||
| 
 | ||||
|     template <typename Seq> | ||||
|     struct pop_front_impl; | ||||
| 
 | ||||
|     template <template <typename...> class Seq, typename T, typename... Ts> | ||||
|     struct pop_front_impl<Seq<T, Ts...>> { | ||||
|         using type = Seq<Ts...>; | ||||
|     }; | ||||
|     } //namespace detail
 | ||||
| 
 | ||||
|     template <typename... Ts> | ||||
|     struct typelist {}; | ||||
| 
 | ||||
|     template <typename Seq> | ||||
|     using front = typename detail::front_impl<Seq>::type; | ||||
| 
 | ||||
|     template <typename Seq> | ||||
|     using pop_front = typename detail::pop_front_impl<Seq>::type; | ||||
| }  // namespace mp
 | ||||
| 
 | ||||
| template<std::size_t N, class Seq> | ||||
| struct variant_impl | ||||
| { | ||||
|     template<class Archive, class V> | ||||
|     static void load ( | ||||
|         Archive & ar, | ||||
|         std::size_t which, | ||||
|         V & v, | ||||
|         const unsigned int version | ||||
|     ){ | ||||
|         if(which == 0){ | ||||
|             // note: A non-intrusive implementation (such as this one)
 | ||||
|             // necessary has to copy the value.  This wouldn't be necessary
 | ||||
|             // with an implementation that de-serialized to the address of the
 | ||||
|             // aligned storage included in the variant.
 | ||||
|             using type = mp::front<Seq>; | ||||
|             type value; | ||||
|             ar >> BOOST_SERIALIZATION_NVP(value); | ||||
|             v = std::move(value); | ||||
|             type * new_address = & std::get<type>(v); | ||||
|             ar.reset_object_address(new_address, & value); | ||||
|             return; | ||||
|         } | ||||
|         //typedef typename mpl::pop_front<S>::type type;
 | ||||
|         using types = mp::pop_front<Seq>; | ||||
|         variant_impl<N - 1, types>::load(ar, which - 1, v, version); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| template<class Seq> | ||||
| struct variant_impl<0, Seq> | ||||
| { | ||||
|     template<class Archive, class V> | ||||
|     static void load ( | ||||
|         Archive & /*ar*/, | ||||
|         std::size_t /*which*/, | ||||
|         V & /*v*/, | ||||
|         const unsigned int /*version*/ | ||||
|     ){} | ||||
| }; | ||||
| 
 | ||||
| template<class Archive, class... Types> | ||||
| void load( | ||||
|     Archive & ar, | ||||
|     std::variant<Types...>& v, | ||||
|     const unsigned int version | ||||
| ){ | ||||
|     std::size_t which; | ||||
|     ar >> BOOST_SERIALIZATION_NVP(which); | ||||
|     if(which >=  sizeof...(Types)) | ||||
|         // this might happen if a type was removed from the list of variant types
 | ||||
|         boost::serialization::throw_exception( | ||||
|             boost::archive::archive_exception( | ||||
|                 boost::archive::archive_exception::unsupported_version | ||||
|             ) | ||||
|         ); | ||||
|     variant_impl<sizeof...(Types), mp::typelist<Types...>>::load(ar, which, v, version); | ||||
| } | ||||
| 
 | ||||
| template<class Archive,class... Types> | ||||
| inline void serialize( | ||||
|     Archive & ar, | ||||
|     std::variant<Types...> & v, | ||||
|     const unsigned int file_version | ||||
| ){ | ||||
|     split_free(ar,v,file_version); | ||||
| } | ||||
| 
 | ||||
| // Specialization for std::monostate
 | ||||
| template<class Archive> | ||||
| void serialize(Archive &ar, std::monostate &, const unsigned int /*version*/) | ||||
| {} | ||||
| 
 | ||||
| } // namespace serialization
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| //template<typename T0_, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)>
 | ||||
| 
 | ||||
| #include <boost/serialization/tracking.hpp> | ||||
| 
 | ||||
| namespace boost { | ||||
|     namespace serialization { | ||||
| 
 | ||||
| template<class... Types> | ||||
| struct tracking_level< | ||||
|     std::variant<Types...> | ||||
| >{ | ||||
|     typedef mpl::integral_c_tag tag; | ||||
|     typedef mpl::int_< ::boost::serialization::track_always> type; | ||||
|     BOOST_STATIC_CONSTANT(int, value = type::value); | ||||
| }; | ||||
| 
 | ||||
| } // namespace serialization
 | ||||
| } // namespace boost
 | ||||
| 
 | ||||
| #endif //BOOST_SERIALIZATION_VARIANT_HPP
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue