1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "CoreThread/BsCoreObjectCore.h"
7#include "Utility/BsModule.h"
8
9namespace bs
10{
11 /** @addtogroup CoreThread-Internal
12 * @{
13 */
14
15 // TODO Low priority - Add debug option that would remember a call stack for each resource initialization,
16 // so when we fail to release one we know which one it is.
17
18 /**
19 * Manager that keeps track of all active CoreObject%s.
20 *
21 * @note Internal class.
22 * @note Thread safe unless specified otherwise.
23 */
24 class BS_CORE_EXPORT CoreObjectManager : public Module<CoreObjectManager>
25 {
26 /**
27 * Stores dirty data that is to be transferred from sim thread to core thread part of a CoreObject, for a single
28 * object.
29 */
30 struct CoreStoredSyncObjData
31 {
32 CoreStoredSyncObjData()
33 :internalId(0)
34 { }
35
36 CoreStoredSyncObjData(const SPtr<ct::CoreObject> destObj, UINT64 internalId, const CoreSyncData& syncData)
37 :destinationObj(destObj), syncData(syncData), internalId(internalId)
38 { }
39
40 SPtr<ct::CoreObject> destinationObj;
41 CoreSyncData syncData;
42 UINT64 internalId;
43 };
44
45 /**
46 * Stores dirty data that is to be transferred from sim thread to core thread part of a CoreObject, for all dirty
47 * objects in one frame.
48 */
49 struct CoreStoredSyncData
50 {
51 FrameAlloc* alloc = nullptr;
52 Vector<CoreStoredSyncObjData> entries;
53 Vector<SPtr<ct::CoreObject>> destroyedObjects;
54 };
55
56 /** Contains information about a dirty CoreObject that requires syncing to the core thread. */
57 struct DirtyObjectData
58 {
59 CoreObject* object;
60 INT32 syncDataId;
61 };
62
63 public:
64 CoreObjectManager();
65 ~CoreObjectManager();
66
67 /** Generates a new unique ID for a core object. */
68 UINT64 generateId();
69
70 /** Registers a new CoreObject notifying the manager the object is created. */
71 void registerObject(CoreObject* object);
72
73 /** Unregisters a CoreObject notifying the manager the object is destroyed. */
74 void unregisterObject(CoreObject* object);
75
76 /** Notifies the system that a CoreObject is dirty and needs to be synced with the core thread. */
77 void notifyCoreDirty(CoreObject* object);
78
79 /** Notifies the system that CoreObject dependencies are dirty and should be updated. */
80 void notifyDependenciesDirty(CoreObject* object);
81
82 /**
83 * Synchronizes all dirty CoreObjects with the core thread. Their dirty data will be allocated using the global
84 * frame allocator and then queued for update using the core thread queue for the calling thread.
85 *
86 * @note Sim thread only.
87 * @note This is an @ref asyncMethod "asynchronous method".
88 */
89 void syncToCore();
90
91 /**
92 * Synchronizes an individual dirty CoreObject with the core thread. Its dirty data will be allocated using the
93 * global frame allocator and then queued for update the core thread queue for the calling thread.
94 *
95 * @note Sim thread only.
96 * @note This is an @ref asyncMethod "asynchronous method".
97 */
98 void syncToCore(CoreObject* object);
99
100 private:
101 /**
102 * Stores all syncable data from dirty core objects into memory allocated by the provided allocator. Additional
103 * meta-data is stored internally to be used by call to syncUpload().
104 *
105 * @param[in] allocator Allocator to use for allocating memory for stored data.
106 *
107 * @note Sim thread only.
108 * @note Must be followed by a call to syncUpload() with the same type.
109 */
110 void syncDownload(FrameAlloc* allocator);
111
112 /**
113 * Copies all the data stored by previous call to syncDownload() into core thread versions of CoreObjects.
114 *
115 * @note Core thread only.
116 * @note Must be preceded by a call to syncDownload().
117 */
118 void syncUpload();
119
120 /**
121 * Updates the cached list of dependencies and dependants for the specified object.
122 *
123 * @param[in] object Update to update dependencies for.
124 * @param[in] dependencies New set of dependencies, or null to clear all dependencies.
125 */
126 void updateDependencies(CoreObject* object, Vector<CoreObject*>* dependencies);
127
128 UINT64 mNextAvailableID;
129 Map<UINT64, CoreObject*> mObjects;
130 Map<UINT64, DirtyObjectData> mDirtyObjects;
131 Map<UINT64, Vector<CoreObject*>> mDependencies;
132 Map<UINT64, Vector<CoreObject*>> mDependants;
133
134 Vector<CoreStoredSyncObjData> mDestroyedSyncData;
135 List<CoreStoredSyncData> mCoreSyncData;
136
137 Mutex mObjectsMutex;
138 };
139
140 /** @} */
141}
142
143