3
0

SaveDataSystemComponent.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <SaveData/SaveDataRequestBus.h>
  10. #include <SaveData_Traits_Platform.h>
  11. #include <AzCore/Component/Component.h>
  12. #include <AzCore/Component/TickBus.h>
  13. #include <AzCore/std/containers/list.h>
  14. #include <AzCore/std/parallel/atomic.h>
  15. #include <AzCore/std/parallel/mutex.h>
  16. #include <AzCore/std/smart_ptr/unique_ptr.h>
  17. ////////////////////////////////////////////////////////////////////////////////////////////////////
  18. namespace SaveData
  19. {
  20. ////////////////////////////////////////////////////////////////////////////////////////////////
  21. //! A system component providing functionality related to saving / loading persistent user data.
  22. class SaveDataSystemComponent : public AZ::Component
  23. , public SaveDataRequestBus::Handler
  24. {
  25. public:
  26. ////////////////////////////////////////////////////////////////////////////////////////////
  27. // AZ::Component Setup
  28. AZ_COMPONENT(SaveDataSystemComponent, "{35790061-347E-47F1-B803-9523752ECD39}");
  29. ////////////////////////////////////////////////////////////////////////////////////////////
  30. //! \ref AZ::ComponentDescriptor::Reflect
  31. static void Reflect(AZ::ReflectContext* context);
  32. ////////////////////////////////////////////////////////////////////////////////////////////
  33. //! \ref AZ::ComponentDescriptor::GetProvidedServices
  34. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
  35. ////////////////////////////////////////////////////////////////////////////////////////////
  36. //! \ref AZ::ComponentDescriptor::GetIncompatibleServices
  37. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
  38. ////////////////////////////////////////////////////////////////////////////////////////////
  39. //! Default constructor
  40. SaveDataSystemComponent() = default;
  41. ////////////////////////////////////////////////////////////////////////////////////////////
  42. //! Default destructor
  43. ~SaveDataSystemComponent() override = default;
  44. ////////////////////////////////////////////////////////////////////////////////////////////
  45. //! \ref AZ::Component::Activate
  46. void Activate() override;
  47. ////////////////////////////////////////////////////////////////////////////////////////////
  48. //! \ref AZ::Component::Deactivate
  49. void Deactivate() override;
  50. protected:
  51. ////////////////////////////////////////////////////////////////////////////////////////////
  52. //! \ref SaveData::SaveDataRequests::SaveDataBuffer
  53. void SaveDataBuffer(const SaveDataBufferParams& saveDataBufferParams) override;
  54. ////////////////////////////////////////////////////////////////////////////////////////////
  55. //! \ref SaveData::SaveDataRequests::LoadDataBuffer
  56. void LoadDataBuffer(const LoadDataBufferParams& loadDataBufferParams) override;
  57. ////////////////////////////////////////////////////////////////////////////////////////////
  58. //! \ref SaveData::SaveDataRequests::SetSaveDataDirectoryPath
  59. void SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) override;
  60. public:
  61. ////////////////////////////////////////////////////////////////////////////////////////////
  62. //! Base class for platform specific implementations of the save data system component
  63. class Implementation : public AZ::TickBus::Handler
  64. {
  65. public:
  66. ////////////////////////////////////////////////////////////////////////////////////////
  67. // Allocator
  68. AZ_CLASS_ALLOCATOR(Implementation, AZ::SystemAllocator);
  69. ////////////////////////////////////////////////////////////////////////////////////////
  70. //! Default factory create function
  71. //! \param[in] saveDataSystemComponent Reference to the parent being implemented
  72. static Implementation* Create(SaveDataSystemComponent& saveDataSystemComponent);
  73. ////////////////////////////////////////////////////////////////////////////////////////
  74. //! Constructor
  75. //! \param[in] saveDataSystemComponent Reference to the parent being implemented
  76. Implementation(SaveDataSystemComponent& saveDataSystemComponent);
  77. ////////////////////////////////////////////////////////////////////////////////////////
  78. // Disable copying
  79. AZ_DISABLE_COPY_MOVE(Implementation);
  80. ////////////////////////////////////////////////////////////////////////////////////////
  81. //! Default destructor
  82. virtual ~Implementation();
  83. ////////////////////////////////////////////////////////////////////////////////////////
  84. //! Save a data buffer.
  85. //! \param[in] saveDataBufferRequestParams The save data buffer request parameters.
  86. virtual void SaveDataBuffer(const SaveDataBufferParams& saveDataBufferParams) = 0;
  87. ////////////////////////////////////////////////////////////////////////////////////////
  88. //! Load a data buffer.
  89. //! \param[in] loadDataBufferParams The load data buffer request parameters.
  90. virtual void LoadDataBuffer(const LoadDataBufferParams& loadDataBufferParams) = 0;
  91. ////////////////////////////////////////////////////////////////////////////////////////
  92. //! Set the path to the application's save data dircetory. Does nothing on some systems.
  93. //! \param[in] saveDataDirectoryPath The path to the application's save data dircetory.
  94. virtual void SetSaveDataDirectoryPath(const char* saveDataDirectoryPath) = 0;
  95. protected:
  96. ////////////////////////////////////////////////////////////////////////////////////////
  97. //! Convenience function to broadcast SaveDataNotifications::OnDataBufferSaved events in
  98. //! addition to any callback specified when SaveDataRequests::SaveDataBuffer was called.
  99. //! \param[in] dataBufferName The name of the data buffer that was saved.
  100. //! \param[in] localUserId The local user id the data that was saved is associated with.
  101. //! \param[in] result The result of the save data buffer request.
  102. //! \param[in] callback The data buffer saved callback to invoke.
  103. static void OnSaveDataBufferComplete(const AZStd::string& dataBufferName,
  104. const AzFramework::LocalUserId localUserId,
  105. const SaveDataRequests::OnDataBufferSaved& callback,
  106. const SaveDataNotifications::Result& result);
  107. ////////////////////////////////////////////////////////////////////////////////////////
  108. //! Save a data buffer to the file system.
  109. //! \param[in] saveDataBufferRequestParams The save data buffer request parameters.
  110. //! \param[in] absoluteFilePath The absolute file path where to save the data buffer.
  111. //! \param[in] waitForCompletion Should we wait until the save data thread completes?
  112. //! \param[in] useTemporaryFile Should we write to a temporary file that gets renamed?
  113. void SaveDataBufferToFileSystem(const SaveDataBufferParams& saveDataBufferParams,
  114. const AZStd::string& absoluteFilePath,
  115. bool waitForCompletion = false,
  116. bool useTemporaryFile = true);
  117. ////////////////////////////////////////////////////////////////////////////////////////
  118. //! Convenience function to broadcast SaveDataNotifications::OnDataBufferLoaded events in
  119. //! addition to any callback specified when SaveDataRequests::LoadDataBuffer was called.
  120. //! \param[in] dataBuffer The data buffer that was loaded.
  121. //! \param[in] dataBufferSize The size of the data buffer that was loaded.
  122. //! \param[in] dataBufferName The name of the data buffer that was loaded.
  123. //! \param[in] localUserId The local user id the data that was loaded is associated with.
  124. //! \param[in] result The result of the load data buffer request.
  125. //! \param[in] callback The data buffer loaded callback to invoke.
  126. static void OnLoadDataBufferComplete(SaveDataNotifications::DataBuffer dataBuffer,
  127. AZ::u64 dataBufferSize,
  128. const AZStd::string& dataBufferName,
  129. const AzFramework::LocalUserId localUserId,
  130. const SaveDataRequests::OnDataBufferLoaded& callback,
  131. const SaveDataNotifications::Result& result);
  132. ////////////////////////////////////////////////////////////////////////////////////////
  133. //! Load a data buffer from the file system.
  134. //! \param[in] loadDataBufferParams The load data buffer request parameters.
  135. //! \param[in] absoluteFilePath The absolute file path from where to load the data buffer.
  136. //! \param[in] waitForCompletion Should we wait until the load data thread completes?
  137. void LoadDataBufferFromFileSystem(const LoadDataBufferParams& loadDataBufferParams,
  138. const AZStd::string& absoluteFilePath,
  139. bool waitForCompletion = false);
  140. ////////////////////////////////////////////////////////////////////////////////////////
  141. //! Pairing of a save/load thread with an atomic bool indicating whether it is complete
  142. struct ThreadCompletionPair
  143. {
  144. AZStd::unique_ptr<AZStd::thread> m_thread;
  145. AZStd::atomic_bool m_threadComplete{ false };
  146. };
  147. ////////////////////////////////////////////////////////////////////////////////////////
  148. //! \ref AZ::TickEvents::OnTick
  149. void OnTick(float deltaTime, AZ::ScriptTimePoint scriptTimePoint) override;
  150. ////////////////////////////////////////////////////////////////////////////////////////
  151. //! Convenience function to join all threads that are active
  152. void JoinAllActiveThreads();
  153. ////////////////////////////////////////////////////////////////////////////////////////
  154. //! Convenience function to join all threads that have been marked as completed
  155. void JoinAllCompletedThreads();
  156. ////////////////////////////////////////////////////////////////////////////////////////
  157. // Variables
  158. AZStd::mutex m_activeThreadsMutex; //! Mutex to restrict access to the active threads
  159. AZStd::list<ThreadCompletionPair> m_activeThreads; //!< A container of active threads
  160. SaveDataSystemComponent& m_saveDataSystemComponent; //!< Reference to the parent
  161. };
  162. private:
  163. ////////////////////////////////////////////////////////////////////////////////////////////
  164. //! Private pointer to the platform specific implementation
  165. AZStd::unique_ptr<Implementation> m_pimpl;
  166. };
  167. }