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_NODE_H
17 #define SCENEPLUGINAPI_NODE_H
18 
19 #include <scene_plugin/api/node_uid.h>
20 #include <scene_plugin/interface/intf_environment.h>
21 #include <scene_plugin/interface/intf_mesh.h>
22 #include <scene_plugin/interface/intf_scene.h>
23 
24 #include <meta/api/internal/object_api.h>
SCENE_BEGIN_NAMESPACE()25 SCENE_BEGIN_NAMESPACE()
26 
27 /**
28  * @brief Node class wraps INode interface. It keeps the referenced object alive using strong ref.
29  *        The construction of the object is asynchronous, the properties of the engine may not be available
30  *        right after the object instantiation, but OnLoaded() event can be used to observe the state changes.
31  */
32 class Node final : public META_NS::Internal::ObjectInterfaceAPI<Node, ClassId::Node> {
33     META_API(Node)
34     META_API_OBJECT_CONVERTIBLE(INode)
35     META_API_CACHE_INTERFACE(INode, Node)
36 public:
37     META_API_INTERFACE_PROPERTY_CACHED(Node, Name, BASE_NS::string)
38     META_API_INTERFACE_PROPERTY_CACHED(Node, Position, BASE_NS::Math::Vec3)
39     META_API_INTERFACE_PROPERTY_CACHED(Node, Scale, BASE_NS::Math::Vec3)
40     META_API_INTERFACE_PROPERTY_CACHED(Node, Rotation, BASE_NS::Math::Quat)
41     META_API_INTERFACE_PROPERTY_CACHED(Node, Visible, bool)
42     META_API_INTERFACE_PROPERTY_CACHED(Node, LayerMask, uint64_t)
43     META_API_INTERFACE_PROPERTY_CACHED(Node, LocalMatrix, BASE_NS::Math::Mat4X4)
44 
45     /**
46      * @brief Construct Node instance from INode strong pointer.
47      * @param node the object pointed by interface is kept alive
48      */
49     explicit Node(const INode::Ptr& node)
50     {
51         Initialize(interface_pointer_cast<META_NS::IObject>(node));
52     }
53 
54     /**
55      * @brief Get a mesh attached to node instance
56      * @return A mesh attached to node.
57      */
58     IMesh::Ptr GetMesh()
59     {
60         if (auto impl = META_API_CACHED_INTERFACE(Node)) {
61             return impl->GetMesh();
62         }
63         return IMesh::Ptr {};
64     }
65 
66     /**
67      * @brief Set a mesh to node instance
68      * @param A mesh to attach to node.
69      */
70     void SetMesh(IMesh::Ptr mesh)
71     {
72         if (auto impl = META_API_CACHED_INTERFACE(Node)) {
73             impl->SetMesh(mesh);
74         }
75     }
76 
77     BASE_NS::Math::Mat4X4 GetGlobalTransform() const
78     {
79         if (auto impl = META_API_CACHED_INTERFACE(Node)) {
80             return impl->GetGlobalTransform();
81         }
82         return BASE_NS::Math::IDENTITY_4X4;
83     }
84 
85     void SetGlobalTransform(const BASE_NS::Math::Mat4X4& mat)
86     {
87         if (auto impl = META_API_CACHED_INTERFACE(Node)) {
88             return impl->SetGlobalTransform(mat);
89         }
90     }
91 
92     /**
93      * @brief Gets OnLoaded event reference from INode-interface
94      * @return INode::OnLoaded
95      * @return
96      */
97     auto OnLoaded()
98     {
99         return META_API_CACHED_INTERFACE(Node)->OnLoaded();
100     }
101 
102     /**
103      * @brief Runs a callback once the node is loaded on engine. If node is already initialized, callback will not run.
104      * @param callback Code to run, if strong reference is passed, it will keep the instance alive
105      *                 causing engine to report memory leak on application exit.
106      * @return reference to this instance of Mesh.
107      */
108     template<class Callback>
109     auto OnLoaded(Callback&& callback)
110     {
111         OnLoaded()->AddHandler(META_NS::MakeCallback<META_NS::IOnChanged>(callback));
112         return *this;
113     }
114 
115     /**
116      * @brief Returns scene this node is attached into.
117      * @return Scene object this node is attached to.
118      */
119     IScene::Ptr GetScene() const
120     {
121         if (auto impl = META_API_CACHED_INTERFACE(Node)) {
122             return impl->GetScene();
123         }
124 
125         return {};
126     }
127 };
128 
129 SCENE_END_NAMESPACE()
130 
131 #endif // SCENEPLUGINAPI_NODE_H
132