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 "Utility/BsModule.h" |
7 | |
8 | namespace bs |
9 | { |
10 | /** @addtogroup Resources-Internal |
11 | * @{ |
12 | */ |
13 | |
14 | /** |
15 | * Handles all active implementations of IResourceListener interface and notifies them when events they're listening |
16 | * to occur. |
17 | * |
18 | * @see IResourceListener |
19 | */ |
20 | class BS_CORE_EXPORT ResourceListenerManager : public Module<ResourceListenerManager> |
21 | { |
22 | public: |
23 | ResourceListenerManager(); |
24 | ~ResourceListenerManager(); |
25 | |
26 | /** |
27 | * Register a new listener to notify for events. |
28 | * |
29 | * @note Thread safe |
30 | */ |
31 | void registerListener(IResourceListener* listener); |
32 | |
33 | /** |
34 | * Unregister a listener so it will no longer receive notifications. |
35 | * |
36 | * @note Thread safe |
37 | */ |
38 | void unregisterListener(IResourceListener* listener); |
39 | |
40 | /** |
41 | * Marks the listener as dirty which forces the manager to updates its internal list of resources for the |
42 | * listener. |
43 | * |
44 | * @note Thread safe |
45 | */ |
46 | void markListenerDirty(IResourceListener* listener); |
47 | |
48 | /** Refreshes the resource maps based on dirty listeners and sends out the necessary events. */ |
49 | void update(); |
50 | |
51 | /** |
52 | * Forces the listener to send out events about the specified resource immediately, instead of waiting for the |
53 | * next update() call. |
54 | */ |
55 | void notifyListeners(const UUID& resourceUUID); |
56 | |
57 | private: |
58 | /** Refreshes the listener mapping for any listeners marked as dirty. */ |
59 | void updateListeners(); |
60 | |
61 | /** Triggered by the resources system when a resource has finished loading. */ |
62 | void onResourceLoaded(const HResource& resource); |
63 | |
64 | /** Triggered by the resources system after a resource handle is modified (points to a new resource). */ |
65 | void onResourceModified(const HResource& resource); |
66 | |
67 | /** Sends resource loaded event to all listeners referencing this resource. */ |
68 | void sendResourceLoaded(const HResource& resource); |
69 | |
70 | /** Sends resource modified event to all listeners referencing this resource. */ |
71 | void sendResourceModified(const HResource& resource); |
72 | |
73 | /** Clears all the stored dependencies for the listener. */ |
74 | void clearDependencies(IResourceListener* listener); |
75 | |
76 | /** Registers all the resource dependencies for the listener. */ |
77 | void addDependencies(IResourceListener* listener); |
78 | |
79 | HEvent mResourceLoadedConn; |
80 | HEvent mResourceModifiedConn; |
81 | |
82 | Set<IResourceListener*> mDirtyListeners; |
83 | Map<UINT64, Vector<IResourceListener*>> mResourceToListenerMap; |
84 | Map<IResourceListener*, Vector<UINT64>> mListenerToResourceMap; |
85 | |
86 | Map<UUID, HResource> mLoadedResources; |
87 | Map<UUID, HResource> mModifiedResources; |
88 | |
89 | Vector<HResource> mTempResourceBuffer; |
90 | Vector<IResourceListener*> mTempListenerBuffer; |
91 | |
92 | RecursiveMutex mMutex; |
93 | |
94 | #if BS_DEBUG_MODE |
95 | Set<IResourceListener*> mActiveListeners; |
96 | #endif |
97 | }; |
98 | |
99 | /** @} */ |
100 | } |