1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SCENEPLUGINAPI_SCENE_H
17 #define SCENEPLUGINAPI_SCENE_H
18 
19 #include <scene_plugin/api/material.h>
20 #include <scene_plugin/api/mesh.h>
21 #include <scene_plugin/api/node.h>
22 #include <scene_plugin/interface/intf_scene.h>
23 
24 #include <meta/api/internal/object_api.h>
25 
26 #include "scene_uid.h"
SCENE_BEGIN_NAMESPACE()27 SCENE_BEGIN_NAMESPACE()
28 class Animation final : public META_NS::Internal::ObjectInterfaceAPI<Animation, ClassId::Animation> {
29     META_API(Animation)
30     META_API_OBJECT_CONVERTIBLE(META_NS::IAnimation)
31     META_API_OBJECT_CONVERTIBLE(META_NS::IStartableAnimation)
32     META_API_CACHE_INTERFACE(META_NS::IAnimation, Animation)
33     META_API_CACHE_INTERFACE(META_NS::IStartableAnimation, StartableAnimation)
34     META_API_OBJECT_CONVERTIBLE(INode)
35     META_API_CACHE_INTERFACE(INode, Node)
36 
37 public:
38     META_API_INTERFACE_PROPERTY_CACHED(Animation, Enabled, bool)
39     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Animation, Valid, bool)
40     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Animation, TotalDuration, META_NS::TimeSpan)
41     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Animation, Running, bool)
42     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Animation, Progress, float)
43 
44     void Start()
45     {
46         if (auto api = META_API_CACHED_INTERFACE(StartableAnimation)) {
47             api->Start();
48         }
49     }
50 
51     void Stop()
52     {
53         if (auto api = META_API_CACHED_INTERFACE(StartableAnimation)) {
54             api->Stop();
55         }
56     }
57 
58     void Pause()
59     {
60         if (auto api = META_API_CACHED_INTERFACE(StartableAnimation)) {
61             api->Pause();
62         }
63     }
64 
65     void Restart()
66     {
67         if (auto api = META_API_CACHED_INTERFACE(StartableAnimation)) {
68             api->Restart();
69         }
70     }
71 
72     void Reset()
73     {
74         if (auto api = META_API_CACHED_INTERFACE(StartableAnimation)) {
75             api->Stop();
76         }
77     }
78 };
79 
80 /**
81  * @brief The Scene class is implementing a proxy to access engine elements from META::Object framework.
82  */
83 class Scene final : public META_NS::Internal::ObjectInterfaceAPI<Scene, ClassId::Scene> {
84     META_API(Scene)
META_API_OBJECT_CONVERTIBLE(IScene)85     META_API_OBJECT_CONVERTIBLE(IScene)
86     META_API_CACHE_INTERFACE(IScene, Scene)
87 public:
88     META_API_INTERFACE_PROPERTY_CACHED(Scene, Name, BASE_NS::string)
89     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Scene, Status, uint32_t)
90     META_API_INTERFACE_READONLY_PROPERTY_CACHED(Scene, RootNode, INode::Ptr)
91     META_API_INTERFACE_PROPERTY_CACHED(Scene, Uri, BASE_NS::string)
92     META_API_INTERFACE_PROPERTY_CACHED(Scene, Asynchronous, bool)
93     META_API_INTERFACE_PROPERTY_CACHED(Scene, DefaultCamera, ICamera::Ptr)
94 
95 public:
96     /**
97      * @brief Instantiates new Scene instance using a strong ref to IScene::Ptr to object implementing the scene.
98      * @param scene strong ref to scene. This may keep the instance alive even the engine has been already purged.
99      */
100     explicit Scene(const IScene::Ptr& scene)
101     {
102         Initialize(interface_pointer_cast<META_NS::IObject>(scene));
103     }
104 
105     /**
106      * @brief Creates and initializes an empty scene.
107      * @return reference to this instance.
108      */
CreateEmpty()109     Scene& CreateEmpty()
110     {
111         if (auto scene = GetSceneInterface()) {
112             scene->CreateEmpty();
113         }
114         return *this;
115     }
116 
117     /**
118      * @brief Loads a scene from file
119      * @param uri Defines the scene file to be used.
120      * @return reference to this instance.
121      */
Load(const BASE_NS::string_view & uri)122     Scene& Load(const BASE_NS::string_view& uri)
123     {
124         if (auto scene = GetSceneInterface()) {
125             scene->Load(uri);
126         }
127         return *this;
128     }
129 
130     /**
131      * @brief Get new Node instance. Returns always an object. Uses flat cache to existing nodes.
132      * @param path The full path including the node name on engine scene
133      * @return Node instance
134      */
GetNode(const BASE_NS::string_view path)135     Node GetNode(const BASE_NS::string_view path)
136     {
137         return Node(GetSceneInterface()->GetNode<INode>(path));
138     }
139 
140     /**
141      * @brief Get existing material proxy. Returns always an object. Uses flat cache to existing materials.
142      * @param name The material name on engine scene
143      * @return Material instance
144      */
GetMaterial(const BASE_NS::string_view name)145     Material GetMaterial(const BASE_NS::string_view name)
146     {
147         return Material(GetSceneInterface()->GetMaterial(name));
148     }
149 
150     /**
151      * @brief Get existing mesh proxy. Returns always an object. Uses flat cache to existing meshes.
152      * @param name The mesh name on engine scene
153      * @return Material instance
154      */
GetMesh(const BASE_NS::string_view path)155     Mesh GetMesh(const BASE_NS::string_view path)
156     {
157         return Mesh(GetSceneInterface()->GetMesh(path));
158     }
159 
160     /**
161      * @brief Get pointer to node interface. Returns always pointer to an object. Uses flat cache to existing nodes.
162      * @param path The full path including the node name on engine scene
163      * @return pointer to node interface
164      */
165     template<class T>
GetNode(const BASE_NS::string_view path)166     typename T::Ptr GetNode(const BASE_NS::string_view path)
167     {
168         return GetSceneInterface()->GetNode<T>(path);
169     }
170 
171     /**
172      * @brief Create new node to engine scene
173      * @param path The full path including the node name on engine scene
174      * @return pointer to new node interface.
175      */
176     template<class T>
CreateNode(const BASE_NS::string_view path)177     typename T::Ptr CreateNode(const BASE_NS::string_view path)
178     {
179         return GetSceneInterface()->CreateNode<T>(path);
180     }
181 
182     /**
183      * @brief Create new material to engine scene.
184      * @param name The material name on engine scene
185      * @return Material instance
186      */
CreateMaterial(const BASE_NS::string_view name)187     Material CreateMaterial(const BASE_NS::string_view name)
188     {
189         return Material(GetSceneInterface()->CreateMaterial(name));
190     }
191 
192     /**
193      * @brief Gets OnLoaded event reference from IScene-interface
194      * @return IScene::OnLoaded
195      */
OnLoaded()196     auto OnLoaded()
197     {
198         return META_API_CACHED_INTERFACE(Scene)->OnLoaded();
199     }
200 
201     /**
202      * @brief Runs a callback once the scene is loaded on engine. If the scene is already initialized,
203      * callback will not run, unless the scene is changed and reloaded.
204      * @param callback Code to run, if strong reference is passed, it will keep the instance alive
205      *                 causing engine to report memory leak on application exit.
206      * @return reference to this instance of Scene.
207      */
208     template<class Callback>
OnLoaded(Callback && callback)209     auto OnLoaded(Callback&& callback)
210     {
211         OnLoaded()->AddHandler(META_NS::MakeCallback<META_NS::IOnChanged>(callback));
212         return *this;
213     }
214 
215     /**
216      * @brief Get attached scene for the node.
217      * @return New Scene instance. Can be uninitialized.
218      */
219     template<class nodeClass>
GetScene(nodeClass & node)220     static Scene GetScene(nodeClass& node)
221     {
222         if (auto nodeInterface = interface_pointer_cast<INode>(node.GetIObject())) {
223             return Scene(nodeInterface->GetScene());
224         }
225 
226         return Scene();
227     }
228 
229     /**
230      *  Load all material proxies on the current scene.
231      */
InstantiateMaterialProxies()232     void InstantiateMaterialProxies()
233     {
234         META_API_CACHED_INTERFACE(Scene)->InstantiateMaterialProxies();
235     }
236 
237     /**
238      *  Load all mesh proxies on the current scene.
239      */
InstantiateMeshProxies()240     void InstantiateMeshProxies()
241     {
242         META_API_CACHED_INTERFACE(Scene)->InstantiateMeshProxies();
243     }
244 };
245 
246 SCENE_END_NAMESPACE()
247 
248 #endif // SCENEPLUGINAPI_SCENE_H
249