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 SCENE_API_ECS_SCENE_H
17 #define SCENE_API_ECS_SCENE_H
18
19 #include <scene/api/scene.h>
20 #include <scene/ext/intf_ecs_context.h>
21 #include <scene/ext/intf_ecs_object_access.h>
22 #include <scene/interface/intf_render_context.h>
23
24 #include <core/ecs/intf_ecs.h>
25
SCENE_BEGIN_NAMESPACE()26 SCENE_BEGIN_NAMESPACE()
27
28 /**
29 * @brief Accessor class for underlying ECS of a Scene.
30 * @note No thread safety is guaranteed for EcsScene object, the user is responsible for running any operation in the
31 * correct thread.
32 */
33 class EcsScene : public META_NS::InterfaceObject<IScene> {
34 public:
35 META_INTERFACE_OBJECT(EcsScene, META_NS::InterfaceObject<IScene>, IScene)
36 /**
37 * @brief Returns the underlying ECS of a Scene.
38 */
39 CORE_NS::IEcs::Ptr GetEcs() const
40 {
41 auto is = META_INTERFACE_OBJECT_CALL_PTR(GetInternalScene());
42 return is ? is->GetEcsContext().GetNativeEcs() : nullptr;
43 }
44 /**
45 * @brief Add a task to be run in the ECS update thread. Usually any underlying ECS access should be done in the
46 * this thread.
47 * @note If the call is made from the ECS thread, the task is executed immediately.
48 * @param fn The function to execute.
49 * @return A future object that can be waited on for task completion and result.
50 */
51 template<typename Fn>
52 auto AddEcsThreadTask(Fn&& fn)
53 {
54 auto is = META_INTERFACE_OBJECT_CALL_PTR(GetInternalScene());
55 auto ctx = is ? is->GetContext() : IRenderContext::Ptr {};
56 return ctx ? AddTask(is, BASE_NS::forward<Fn>(fn), ctx->GetRenderQueue())
57 : Future<META_NS::PlainType_t<decltype(fn())>> {};
58 }
59 /**
60 * @brief Add a task to be run in application thread.
61 * @note If the call is made from the application thread, the task is executed immediately.
62 * @param fn The function to execute.
63 * @return A future object that can be waited on for task completion and result.
64 */
65 template<typename Fn>
66 auto AddApplicationThreadTask(Fn&& fn)
67 {
68 auto is = META_INTERFACE_OBJECT_CALL_PTR(GetInternalScene());
69 auto ctx = is ? is->GetContext() : IRenderContext::Ptr {};
70 return ctx ? AddTask(is, BASE_NS::forward<Fn>(fn), ctx->GetApplicationQueue())
71 : Future<META_NS::PlainType_t<decltype(fn())>> {};
72 }
73
74 private:
75 template<typename Fn>
76 auto AddTask(const IInternalScene::Ptr& is, Fn&& fn, const META_NS::ITaskQueue::Ptr& queue)
77 {
78 return is ? is->AddTask(BASE_NS::forward<Fn>(fn), queue) : Future<META_NS::PlainType_t<decltype(fn())>> {};
79 }
80 };
81
82 /**
83 * @brief Accessor class for underlying ECS Entity of a Scene object.
84 * @note No thread safety is guaranteed for EcsObject object, the user is responsible for running any operation in the
85 * correct thread.
86 */
87 class EcsObject : public META_NS::InterfaceObject<IEcsObjectAccess> {
88 public:
META_INTERFACE_OBJECT(EcsObject,META_NS::InterfaceObject<IEcsObjectAccess>,IEcsObjectAccess)89 META_INTERFACE_OBJECT(EcsObject, META_NS::InterfaceObject<IEcsObjectAccess>, IEcsObjectAccess)
90 /**
91 * @brief Returns the underlying ECS entity of an object in a Scene.
92 */
93 CORE_NS::Entity GetEntity() const
94 {
95 auto ecso = META_INTERFACE_OBJECT_CALL_PTR(GetEcsObject());
96 return ecso ? ecso->GetEntity() : CORE_NS::Entity {};
97 }
98 };
99
100 SCENE_END_NAMESPACE()
101
102 #endif // SCENE_API_ECS_SCENE_H
103