mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	APT service serialization
This commit is contained in:
		
							parent
							
								
									3e752002c4
								
							
						
					
					
						commit
						5265c79056
					
				
					 25 changed files with 247 additions and 17 deletions
				
			
		
							
								
								
									
										2
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
										
									
									
									
								
							|  | @ -64,7 +64,7 @@ | |||
|         ✔ AC @started(19-12-23 12:48) @done(19-12-24 22:38) @lasted(1d9h50m3s) | ||||
|         ✔ ACT @done(19-12-24 23:17) | ||||
|         ✔ AM @started(19-12-24 23:17) @done(19-12-24 23:53) @lasted(36m8s) | ||||
|         ☐ APT | ||||
|         ✔ APT @done(19-12-25 21:41) | ||||
|         ☐ BOSS | ||||
|         ☐ CAM | ||||
|         ☐ CECD | ||||
|  |  | |||
							
								
								
									
										91
									
								
								src/common/serialization/optional.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/common/serialization/optional.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <boost/config.hpp> | ||||
| 
 | ||||
| #include <boost/archive/detail/basic_iarchive.hpp> | ||||
| 
 | ||||
| #include <optional> | ||||
| #include <boost/move/utility_core.hpp> | ||||
| 
 | ||||
| #include <boost/serialization/item_version_type.hpp> | ||||
| #include <boost/serialization/split_free.hpp> | ||||
| #include <boost/serialization/level.hpp> | ||||
| #include <boost/serialization/nvp.hpp> | ||||
| #include <boost/serialization/version.hpp> | ||||
| #include <boost/type_traits/is_pointer.hpp> | ||||
| #include <boost/serialization/detail/stack_constructor.hpp> | ||||
| #include <boost/serialization/detail/is_default_constructible.hpp> | ||||
| #include <boost/serialization/force_include.hpp> | ||||
| 
 | ||||
| // function specializations must be defined in the appropriate
 | ||||
| // namespace - boost::serialization
 | ||||
| namespace boost { | ||||
| namespace serialization { | ||||
| 
 | ||||
| template<class Archive, class T> | ||||
| void save( | ||||
|     Archive & ar, | ||||
|     const std::optional< T > & t, | ||||
|     const unsigned int /*version*/ | ||||
| ){ | ||||
|     // It is an inherent limitation to the serialization of optional.hpp
 | ||||
|     // that the underlying type must be either a pointer or must have a
 | ||||
|     // default constructor.  It's possible that this could change sometime
 | ||||
|     // in the future, but for now, one will have to work around it.  This can
 | ||||
|     // be done by serialization the optional<T> as optional<T *>
 | ||||
|     #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) | ||||
|         BOOST_STATIC_ASSERT( | ||||
|             boost::serialization::detail::is_default_constructible<T>::value | ||||
|             || boost::is_pointer<T>::value | ||||
|         ); | ||||
|     #endif | ||||
|     const bool tflag = t.has_value(); | ||||
|     ar << boost::serialization::make_nvp("initialized", tflag); | ||||
|     if (tflag){ | ||||
|         ar << boost::serialization::make_nvp("value", *t); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| template<class Archive, class T> | ||||
| void load( | ||||
|     Archive & ar, | ||||
|     std::optional< T > & t, | ||||
|     const unsigned int version | ||||
| ){ | ||||
|     bool tflag; | ||||
|     ar >> boost::serialization::make_nvp("initialized", tflag); | ||||
|     if(! tflag){ | ||||
|         t.reset(); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(0 == version){ | ||||
|         boost::serialization::item_version_type item_version(0); | ||||
|         boost::archive::library_version_type library_version( | ||||
|             ar.get_library_version() | ||||
|         ); | ||||
|         if(boost::archive::library_version_type(3) < library_version){ | ||||
|             ar >> BOOST_SERIALIZATION_NVP(item_version); | ||||
|         } | ||||
|     } | ||||
|     if(! t.has_value()) | ||||
|         t = T(); | ||||
|     ar >> boost::serialization::make_nvp("value", *t); | ||||
| } | ||||
| 
 | ||||
| template<class Archive, class T> | ||||
| void serialize( | ||||
|     Archive & ar, | ||||
|     std::optional< T > & t, | ||||
|     const unsigned int version | ||||
| ){ | ||||
|     boost::serialization::split_free(ar, t, version); | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| struct version<std::optional<T> > { | ||||
|     BOOST_STATIC_CONSTANT(int, value = 1); | ||||
| }; | ||||
| 
 | ||||
| } // serialization
 | ||||
| } // boost
 | ||||
|  | @ -3,4 +3,9 @@ namespace Core { | |||
| template <class T> | ||||
| T& Global(); | ||||
| 
 | ||||
| // Declare explicit specialisation to prevent im
 | ||||
| class System; | ||||
| template <> | ||||
| System& Global(); | ||||
| 
 | ||||
| } // namespace Core
 | ||||
|  |  | |||
|  | @ -8,10 +8,11 @@ | |||
| #include "core/hle/kernel/memory.h" | ||||
| #include "core/hle/kernel/shared_memory.h" | ||||
| #include "core/memory.h" | ||||
| #include "core/global.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| 
 | ||||
| SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} | ||||
| SharedMemory::SharedMemory() : Object(Core::Global<KernelSystem>()), kernel(Core::Global<KernelSystem>()) {} | ||||
| SharedMemory::~SharedMemory() { | ||||
|     for (const auto& interval : holding_memory) { | ||||
|         kernel.GetMemoryRegion(MemoryRegion::SYSTEM) | ||||
|  | @ -27,7 +28,7 @@ SharedMemory::~SharedMemory() { | |||
| ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory( | ||||
|     Process* owner_process, u32 size, MemoryPermission permissions, | ||||
|     MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { | ||||
|     auto shared_memory{std::make_shared<SharedMemory>(*this)}; | ||||
|     auto shared_memory{std::make_shared<SharedMemory>()}; | ||||
| 
 | ||||
|     shared_memory->owner_process = owner_process; | ||||
|     shared_memory->name = std::move(name); | ||||
|  | @ -72,7 +73,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory( | |||
| std::shared_ptr<SharedMemory> KernelSystem::CreateSharedMemoryForApplet( | ||||
|     u32 offset, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, | ||||
|     std::string name) { | ||||
|     auto shared_memory{std::make_shared<SharedMemory>(*this)}; | ||||
|     auto shared_memory{std::make_shared<SharedMemory>()}; | ||||
| 
 | ||||
|     // Allocate memory in heap
 | ||||
|     MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::SYSTEM); | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ namespace Kernel { | |||
| 
 | ||||
| class SharedMemory final : public Object { | ||||
| public: | ||||
|     explicit SharedMemory(KernelSystem& kernel); | ||||
|     explicit SharedMemory(); | ||||
|     ~SharedMemory() override; | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ public: | |||
|     explicit AC_I(std::shared_ptr<Module> ac); | ||||
| 
 | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AC_I, ac) | ||||
|     SERVICE_SERIALIZATION(AC_I, ac, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AC
 | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ public: | |||
|     explicit AC_U(std::shared_ptr<Module> ac); | ||||
| 
 | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AC_U, ac) | ||||
|     SERVICE_SERIALIZATION(AC_U, ac, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AC
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class ACT_A final : public Module::Interface { | |||
| public: | ||||
|     explicit ACT_A(std::shared_ptr<Module> act); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(ACT_A, act) | ||||
|     SERVICE_SERIALIZATION(ACT_A, act, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::ACT
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class ACT_U final : public Module::Interface { | |||
| public: | ||||
|     explicit ACT_U(std::shared_ptr<Module> act); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(ACT_U, act) | ||||
|     SERVICE_SERIALIZATION(ACT_U, act, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::ACT
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class AM_APP final : public Module::Interface { | |||
| public: | ||||
|     explicit AM_APP(std::shared_ptr<Module> am); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AM_APP, am) | ||||
|     SERVICE_SERIALIZATION(AM_APP, am, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AM
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class AM_NET final : public Module::Interface { | |||
| public: | ||||
|     explicit AM_NET(std::shared_ptr<Module> am); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AM_NET, am) | ||||
|     SERVICE_SERIALIZATION(AM_NET, am, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AM
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class AM_SYS final : public Module::Interface { | |||
| public: | ||||
|     explicit AM_SYS(std::shared_ptr<Module> am); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AM_SYS, am) | ||||
|     SERVICE_SERIALIZATION(AM_SYS, am, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AM
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class AM_U final : public Module::Interface { | |||
| public: | ||||
|     explicit AM_U(std::shared_ptr<Module> am); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(AM_U, am) | ||||
|     SERVICE_SERIALIZATION(AM_U, am, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AM
 | ||||
|  |  | |||
|  | @ -8,9 +8,12 @@ | |||
| #include <memory> | ||||
| #include <optional> | ||||
| #include <vector> | ||||
| #include <boost/serialization/array.hpp> | ||||
| #include "common/serialization/optional.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| #include "core/global.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
|  | @ -84,6 +87,18 @@ struct MessageParameter { | |||
|     SignalType signal = SignalType::None; | ||||
|     std::shared_ptr<Kernel::Object> object = nullptr; | ||||
|     std::vector<u8> buffer; | ||||
| 
 | ||||
| private: | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int) | ||||
|     { | ||||
|         ar & sender_id; | ||||
|         ar & destination_id; | ||||
|         ar & signal; | ||||
|         ar & object; | ||||
|         ar & buffer; | ||||
|     } | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
| 
 | ||||
| /// Holds information about the parameters used in StartLibraryApplet
 | ||||
|  | @ -161,6 +176,17 @@ public: | |||
| 
 | ||||
|         u64 current_title_id; | ||||
|         FS::MediaType current_media_type; | ||||
| 
 | ||||
|     private: | ||||
|         template <class Archive> | ||||
|         void serialize(Archive& ar, const unsigned int) | ||||
|         { | ||||
|             ar & next_title_id; | ||||
|             ar & next_media_type; | ||||
|             ar & current_title_id; | ||||
|             ar & current_media_type; | ||||
|         } | ||||
|         friend class boost::serialization::access; | ||||
|     }; | ||||
| 
 | ||||
|     ApplicationJumpParameters GetApplicationJumpParameters() const { | ||||
|  | @ -199,6 +225,21 @@ private: | |||
|             title_id = 0; | ||||
|             attributes.raw = 0; | ||||
|         } | ||||
| 
 | ||||
|     private: | ||||
|         template <class Archive> | ||||
|         void serialize(Archive& ar, const unsigned int) | ||||
|         { | ||||
|             ar & applet_id; | ||||
|             ar & slot; | ||||
|             ar & title_id; | ||||
|             ar & registered; | ||||
|             ar & loaded; | ||||
|             ar & attributes.raw; | ||||
|             ar & notification_event; | ||||
|             ar & parameter_event; | ||||
|         } | ||||
|         friend class boost::serialization::access; | ||||
|     }; | ||||
| 
 | ||||
|     ApplicationJumpParameters app_jump_parameters{}; | ||||
|  | @ -216,6 +257,25 @@ private: | |||
|     SignalType library_applet_closing_command; | ||||
| 
 | ||||
|     Core::System& system; | ||||
| 
 | ||||
| private: | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int) | ||||
|     { | ||||
|         ar & next_parameter; | ||||
|         ar & app_jump_parameters; | ||||
|         ar & applet_slots; | ||||
|         ar & library_applet_closing_command; | ||||
|     } | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| namespace boost::serialization { | ||||
|     template <class Archive> | ||||
|     inline void load_construct_data(Archive& ar, Service::APT::AppletManager* t, const unsigned int) | ||||
|     { | ||||
|         ::new(t)Service::APT::AppletManager(Core::Global<Core::System>()); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "common/common_paths.h" | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/archives.h" | ||||
| #include "core/core.h" | ||||
| #include "core/file_sys/archive_ncch.h" | ||||
| #include "core/file_sys/file_backend.h" | ||||
|  | @ -26,8 +27,35 @@ | |||
| #include "core/hw/aes/ccm.h" | ||||
| #include "core/hw/aes/key.h" | ||||
| 
 | ||||
| namespace boost::serialization { | ||||
|     template <class Archive> | ||||
|     void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int) | ||||
|     { | ||||
|         ::new(t)Service::APT::Module(Core::Global<Core::System>()); | ||||
|     } | ||||
| 
 | ||||
|     template | ||||
|     void load_construct_data<iarchive>(iarchive& ar, Service::APT::Module* t, const unsigned int); | ||||
| } | ||||
| 
 | ||||
| namespace Service::APT { | ||||
| 
 | ||||
| template <class Archive> | ||||
| void Module::serialize(Archive& ar, const unsigned int) | ||||
| { | ||||
|     ar & shared_font_mem; | ||||
|     ar & shared_font_loaded; | ||||
|     ar & shared_font_relocated; | ||||
|     ar & lock; | ||||
|     ar & cpu_percent; | ||||
|     ar & unknown_ns_state_field; | ||||
|     ar & screen_capture_buffer; | ||||
|     ar & screen_capture_post_permission; | ||||
|     ar & applet_manager; | ||||
| } | ||||
| 
 | ||||
| SERIALIZE_IMPL(Module) | ||||
| 
 | ||||
| Module::NSInterface::NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session) | ||||
|     : ServiceFramework(name, max_session), apt(std::move(apt)) {} | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,11 +6,15 @@ | |||
| 
 | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include <boost/serialization/shared_ptr.hpp> | ||||
| #include <boost/serialization/vector.hpp> | ||||
| #include "common/archives.h" | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/global.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
|  | @ -65,7 +69,7 @@ public: | |||
|         NSInterface(std::shared_ptr<Module> apt, const char* name, u32 max_session); | ||||
|         ~NSInterface(); | ||||
| 
 | ||||
|     private: | ||||
|     protected: | ||||
|         std::shared_ptr<Module> apt; | ||||
|     }; | ||||
| 
 | ||||
|  | @ -601,7 +605,7 @@ public: | |||
|          */ | ||||
|         void CheckNew3DS(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     private: | ||||
|     protected: | ||||
|         bool application_reset_prepared{}; | ||||
|         std::shared_ptr<Module> apt; | ||||
|     }; | ||||
|  | @ -630,8 +634,17 @@ private: | |||
|         ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value
 | ||||
| 
 | ||||
|     std::shared_ptr<AppletManager> applet_manager; | ||||
| 
 | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int); | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
| 
 | ||||
| void InstallInterfaces(Core::System& system); | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| namespace boost::serialization { | ||||
|     template <class Archive> | ||||
|     void load_construct_data(Archive& ar, Service::APT::Module* t, const unsigned int); | ||||
| } | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "core/hle/service/apt/apt_a.h" | ||||
| #include "common/archives.h" | ||||
| 
 | ||||
| namespace Service::APT { | ||||
| 
 | ||||
|  | @ -105,3 +106,5 @@ APT_A::APT_A(std::shared_ptr<Module> apt) | |||
| } | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| SERIALIZE_EXPORT_IMPL(Service::APT::APT_A) | ||||
|  |  | |||
|  | @ -11,6 +11,11 @@ namespace Service::APT { | |||
| class APT_A final : public Module::APTInterface { | ||||
| public: | ||||
|     explicit APT_A(std::shared_ptr<Module> apt); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(APT_A, apt, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| BOOST_CLASS_EXPORT_KEY(Service::APT::APT_A) | ||||
| BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_A) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "core/hle/service/apt/apt_s.h" | ||||
| #include "common/archives.h" | ||||
| 
 | ||||
| namespace Service::APT { | ||||
| 
 | ||||
|  | @ -105,3 +106,5 @@ APT_S::APT_S(std::shared_ptr<Module> apt) | |||
| } | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| SERIALIZE_EXPORT_IMPL(Service::APT::APT_S) | ||||
|  |  | |||
|  | @ -18,6 +18,11 @@ namespace Service::APT { | |||
| class APT_S final : public Module::APTInterface { | ||||
| public: | ||||
|     explicit APT_S(std::shared_ptr<Module> apt); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(APT_S, apt, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| BOOST_CLASS_EXPORT_KEY(Service::APT::APT_S) | ||||
| BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_S) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "core/hle/service/apt/apt_u.h" | ||||
| #include "common/archives.h" | ||||
| 
 | ||||
| namespace Service::APT { | ||||
| 
 | ||||
|  | @ -102,3 +103,5 @@ APT_U::APT_U(std::shared_ptr<Module> apt) | |||
| } | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| SERIALIZE_EXPORT_IMPL(Service::APT::APT_U) | ||||
|  |  | |||
|  | @ -18,6 +18,11 @@ namespace Service::APT { | |||
| class APT_U final : public Module::APTInterface { | ||||
| public: | ||||
|     explicit APT_U(std::shared_ptr<Module> apt); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(APT_U, apt, Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::APT
 | ||||
| 
 | ||||
| BOOST_CLASS_EXPORT_KEY(Service::APT::APT_U) | ||||
| BOOST_SERIALIZATION_CONSTRUCT(Service::APT::APT_U) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "core/hle/service/apt/ns_s.h" | ||||
| #include "common/archives.h" | ||||
| 
 | ||||
| namespace Service::NS { | ||||
| 
 | ||||
|  | @ -29,3 +30,5 @@ NS_S::NS_S(std::shared_ptr<Service::APT::Module> apt) | |||
| } | ||||
| 
 | ||||
| } // namespace Service::NS
 | ||||
| 
 | ||||
| SERIALIZE_EXPORT_IMPL(Service::NS::NS_S) | ||||
|  |  | |||
|  | @ -14,6 +14,11 @@ namespace Service::NS { | |||
| class NS_S final : public Service::APT::Module::NSInterface { | ||||
| public: | ||||
|     explicit NS_S(std::shared_ptr<Service::APT::Module> apt); | ||||
| private: | ||||
|     SERVICE_SERIALIZATION(NS_S, apt, Service::APT::Module) | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::NS
 | ||||
| 
 | ||||
| BOOST_CLASS_EXPORT_KEY(Service::NS::NS_S) | ||||
| BOOST_SERIALIZATION_CONSTRUCT(Service::NS::NS_S) | ||||
|  |  | |||
|  | @ -199,7 +199,7 @@ extern const std::array<ServiceModuleInfo, 40> service_module_map; | |||
| 
 | ||||
| } // namespace Service
 | ||||
| 
 | ||||
| #define SERVICE_SERIALIZATION(T, MFIELD) \ | ||||
| #define SERVICE_SERIALIZATION(T, MFIELD, TMODULE) \ | ||||
|     template <class Archive> \ | ||||
|     void save_construct(Archive& ar, const unsigned int file_version) const \ | ||||
|     { \ | ||||
|  | @ -209,7 +209,7 @@ extern const std::array<ServiceModuleInfo, 40> service_module_map; | |||
|     template <class Archive> \ | ||||
|     static void load_construct(Archive& ar, T* t, const unsigned int file_version) \ | ||||
|     { \ | ||||
|         std::shared_ptr<Module> MFIELD; \ | ||||
|         std::shared_ptr<TMODULE> MFIELD; \ | ||||
|         ar >> MFIELD; \ | ||||
|         ::new(t)T(MFIELD); \ | ||||
|     } \ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue