Let ModelCache use std::map instead of unordered_map
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / common / model-cache-manager.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/internal/common/model-cache-manager.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/map-wrapper.h>
23 #include <dali/devel-api/common/singleton-service.h>
24 #include <dali/public-api/object/base-object.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-scene3d/public-api/loader/load-result.h>
28 #include <dali-scene3d/public-api/loader/scene-definition.h>
29
30 namespace Dali::Scene3D::Internal
31 {
32 class ModelCacheManager::Impl : public Dali::BaseObject
33 {
34 public:
35   /**
36    * @brief Constructor
37    */
38   Impl()
39   {
40   }
41
42   Dali::Scene3D::Loader::LoadResult GetModelLoadResult(std::string modelUri)
43   {
44     ModelCache& cache = mModelCache[modelUri];
45     return Dali::Scene3D::Loader::LoadResult{cache.resources, cache.scene, cache.metaData, cache.animationDefinitions, cache.amimationGroupDefinitions, cache.cameraParameters, cache.lights};
46   }
47
48   uint32_t GetModelCacheRefCount(std::string modelUri)
49   {
50     ModelCache& cache = mModelCache[modelUri];
51     return cache.refCount;
52   }
53
54   Dali::ConditionalWait& GetLoadSceneConditionalWaitInstance(std::string modelUri)
55   {
56     ModelCache& cache = mModelCache[modelUri];
57     return cache.loadSceneConditionalWait;
58   }
59
60   void ReferenceModelCache(std::string modelUri)
61   {
62     ModelCache& cache = mModelCache[modelUri];
63     cache.refCount++;
64   }
65
66   void UnreferenceModelCache(std::string modelUri)
67   {
68     ModelCache& cache = mModelCache[modelUri];
69     if(cache.refCount > 0)
70     {
71       cache.refCount--;
72     }
73
74     if(cache.refCount == 0)
75     {
76       mModelCache.erase(modelUri);
77     }
78   }
79
80   bool IsSceneLoaded(std::string modelUri)
81   {
82     ModelCache& cache = mModelCache[modelUri];
83     return cache.isSceneLoaded;
84   }
85
86   void SetSceneLoaded(std::string modelUri, bool isSceneLoaded)
87   {
88     ModelCache& cache   = mModelCache[modelUri];
89     cache.isSceneLoaded = isSceneLoaded;
90   }
91
92   bool IsSceneLoading(std::string modelUri)
93   {
94     ModelCache& cache = mModelCache[modelUri];
95     return cache.isSceneLoading;
96   }
97
98   void SetSceneLoading(std::string modelUri, bool isSceneLoading)
99   {
100     ModelCache& cache    = mModelCache[modelUri];
101     cache.isSceneLoading = isSceneLoading;
102   }
103
104 protected:
105   /**
106    * A reference counted object may only be deleted by calling Unreference()
107    */
108   virtual ~Impl()
109   {
110   }
111
112 private:
113   struct ModelCache
114   {
115     Dali::Scene3D::Loader::ResourceBundle  resources{}; ///< The bundle to store resources in.
116     Dali::Scene3D::Loader::SceneDefinition scene{};     ///< The scene definition to populate.
117     Dali::Scene3D::Loader::SceneMetadata   metaData{};  ///< The metadata of the scene.
118
119     std::vector<Dali::Scene3D::Loader::AnimationDefinition>      animationDefinitions{};      ///< The list of animation definitions, in lexicographical order of their names.
120     std::vector<Dali::Scene3D::Loader::AnimationGroupDefinition> amimationGroupDefinitions{}; ///< The list of animation group definitions, in lexicographical order of their names.
121     std::vector<Dali::Scene3D::Loader::CameraParameters>         cameraParameters{};          ///< The camera parameters that were loaded from the scene.
122     std::vector<Dali::Scene3D::Loader::LightParameters>          lights{};                    ///< The light parameters that were loaded from the scene.
123
124     uint32_t              refCount{0};                ///< The reference count of this model cache.
125     Dali::ConditionalWait loadSceneConditionalWait{}; ///< The conditionalWait instance used to synchronise the loading of the scene for the same model in different threads.
126
127     bool isSceneLoaded{false};  ///< Whether the scene of the model has been loaded.
128     bool isSceneLoading{false}; ///< Whether the scene loading of the model is in progress.
129   };
130
131   using ModelResourceCache = std::map<std::string, ModelCache>;
132   ModelResourceCache mModelCache;
133 };
134
135 ModelCacheManager::ModelCacheManager() = default;
136
137 ModelCacheManager::~ModelCacheManager() = default;
138
139 ModelCacheManager ModelCacheManager::Get()
140 {
141   ModelCacheManager manager;
142
143   // Check whether the ModelCacheManager is already created
144   SingletonService singletonService(SingletonService::Get());
145   if(singletonService)
146   {
147     Dali::BaseHandle handle = singletonService.GetSingleton(typeid(ModelCacheManager));
148     if(handle)
149     {
150       // If so, downcast the handle of singleton to ModelCacheManager
151       manager = ModelCacheManager(dynamic_cast<ModelCacheManager::Impl*>(handle.GetObjectPtr()));
152     }
153
154     if(!manager)
155     {
156       // If not, create the ModelCacheManager and register it as a singleton
157       manager = ModelCacheManager(new ModelCacheManager::Impl());
158       singletonService.Register(typeid(manager), manager);
159     }
160   }
161
162   return manager;
163 }
164
165 ModelCacheManager::ModelCacheManager(ModelCacheManager::Impl* impl)
166 : BaseHandle(impl)
167 {
168 }
169
170 Dali::Scene3D::Loader::LoadResult ModelCacheManager::GetModelLoadResult(std::string modelUri)
171 {
172   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
173   return impl.GetModelLoadResult(modelUri);
174 }
175
176 uint32_t ModelCacheManager::GetModelCacheRefCount(std::string modelUri)
177 {
178   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
179   return impl.GetModelCacheRefCount(modelUri);
180 }
181
182 Dali::ConditionalWait& ModelCacheManager::GetLoadSceneConditionalWaitInstance(std::string modelUri)
183 {
184   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
185   return impl.GetLoadSceneConditionalWaitInstance(modelUri);
186 }
187
188 void ModelCacheManager::ReferenceModelCache(std::string modelUri)
189 {
190   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
191   impl.ReferenceModelCache(modelUri);
192 }
193
194 void ModelCacheManager::UnreferenceModelCache(std::string modelUri)
195 {
196   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
197   impl.UnreferenceModelCache(modelUri);
198 }
199
200 bool ModelCacheManager::IsSceneLoaded(std::string modelUri)
201 {
202   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
203   return impl.IsSceneLoaded(modelUri);
204 }
205
206 void ModelCacheManager::SetSceneLoaded(std::string modelUri, bool isSceneLoaded)
207 {
208   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
209   impl.SetSceneLoaded(modelUri, isSceneLoaded);
210 }
211
212 bool ModelCacheManager::IsSceneLoading(std::string modelUri)
213 {
214   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
215   return impl.IsSceneLoading(modelUri);
216 }
217
218 void ModelCacheManager::SetSceneLoading(std::string modelUri, bool isSceneLoading)
219 {
220   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
221   impl.SetSceneLoading(modelUri, isSceneLoading);
222 }
223
224 } // namespace Dali::Scene3D::Internal