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 #ifndef NODE_IMPL_H_
16 #define NODE_IMPL_H_
17 #include <algorithm>
18 #include <scene_plugin/api/node_uid.h>
19 #include <scene_plugin/interface/intf_environment.h>
20 
21 #include <meta/ext/object_container.h>
22 #include <meta/interface/intf_containable.h>
23 
24 #include "intf_node_private.h"
25 #include "PropertyHandlerArrayHolder.h"
26 
27 class NodeImpl : public META_NS::ObjectContainerFwd<NodeImpl, SCENE_NS::ClassId::Node, SCENE_NS::INode,
28                      META_NS::IContainable, META_NS::IMutableContainable, INodeEcsInterfacePrivate,
29                      SCENE_NS::IEcsObject, SCENE_NS::IProxyObject/*, UI_NS::Input::IInputFilter*/> {
30     using Super = META_NS::ObjectContainerFwd<NodeImpl, SCENE_NS::ClassId::Node, SCENE_NS::INode, META_NS::IContainable,
31         META_NS::IMutableContainable, INodeEcsInterfacePrivate, SCENE_NS::IEcsObject, SCENE_NS::IProxyObject/*,
32         UI_NS::Input::IInputFilter*/>;
33 
34 public:
35     META_IMPLEMENT_INTERFACE_PROPERTY(META_NS::INamed, BASE_NS::string, Name, {})
36     META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(SCENE_NS::INode, BASE_NS::string, Path, {}, META_NS::ObjectFlagBits::INTERNAL)
37     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, BASE_NS::Math::Vec3, Position,
38         BASE_NS::Math::Vec3(0.f, 0.f, 0.f))
39     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, BASE_NS::Math::Quat, Rotation,
40         BASE_NS::Math::Quat(0.f, 0.f, 0.f, 1.f))
41     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, BASE_NS::Math::Vec3, Scale, BASE_NS::Math::Vec3(1.f, 1.f, 1.f))
42     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, bool, Visible, true)
43     META_IMPLEMENT_INTERFACE_PROPERTY(
44         SCENE_NS::INode, uint64_t, LayerMask, (1ULL << 0U))
45     META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(SCENE_NS::INode, uint8_t, Status, SCENE_NS::INode::NODE_STATUS_UNINITIALIZED, META_NS::ObjectFlagBits::INTERNAL)
46     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, BASE_NS::Math::Mat4X4, LocalMatrix, BASE_NS::Math::IDENTITY_4X4,
47         META_NS::DEFAULT_PROPERTY_FLAGS_NO_SER)
48     META_IMPLEMENT_INTERFACE_READONLY_PROPERTY(SCENE_NS::INode, uint8_t, ConnectionStatus,
49         SCENE_NS::IEcsObject::ECS_OBJ_STATUS_DISCONNECTED, META_NS::ObjectFlagBits::INTERNAL)
50     META_IMPLEMENT_INTERFACE_PROPERTY(SCENE_NS::INode, SCENE_NS::IMesh::Ptr, Mesh, {})
51 
52     META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnLoaded)
53     META_IMPLEMENT_EVENT(META_NS::IOnChanged, OnBound)
54 
55 protected:
56     using Fwd = META_NS::ObjectContainerFwd<NodeImpl, SCENE_NS::ClassId::Node, SCENE_NS::INode, META_NS::IContainable,
57         META_NS::IMutableContainable, INodeEcsInterfacePrivate, SCENE_NS::IEcsObject, SCENE_NS::IProxyObject/*,
58         UI_NS::Input::IInputFilter*/>;
59 
60 /*public: // IInputFilter
61     META_IMPLEMENT_INTERFACE_PROPERTY(
62         UI_NS::Input::IInputFilter, UI_NS::Input::InputMode, InputMode, UI_NS::Input::InputMode::RECEIVE)*/
63 
64 protected:
65     static constexpr BASE_NS::string_view TRANSFORM_COMPONENT_NAME = "TransformComponent";
66     static constexpr size_t TRANSFORM_COMPONENT_NAME_LEN = TRANSFORM_COMPONENT_NAME.size() + 1;
67     static constexpr BASE_NS::string_view TRANSFORM_POSITION = "TransformComponent.position";
68     static constexpr BASE_NS::string_view TRANSFORM_SCALE = "TransformComponent.scale";
69     static constexpr BASE_NS::string_view TRANSFORM_ROTATION = "TransformComponent.rotation";
70     static constexpr BASE_NS::string_view NODE_COMPONENT_NAME = "NodeComponent";
71     static constexpr size_t NODE_COMPONENT_NAME_LEN = NODE_COMPONENT_NAME.size() + 1;
72     static constexpr BASE_NS::string_view NODE_ENABLED = "NodeComponent.enabled";
73     static constexpr BASE_NS::string_view LAYER_COMPONENT_NAME = "LayerComponent";
74     static constexpr size_t LAYER_COMPONENT_NAME_LEN = LAYER_COMPONENT_NAME.size() + 1;
75     static constexpr BASE_NS::string_view LAYER_MASK = "LayerComponent.layerMask";
76     static constexpr BASE_NS::string_view LMATRIX_COMPONENT_NAME = "LocalMatrixComponent";
77     static constexpr size_t LMATRIX_COMPONENT_NAME_LEN = LMATRIX_COMPONENT_NAME.size() + 1;
78     static constexpr BASE_NS::string_view LMATRIX_MATRIX = "LocalMatrixComponent.matrix";
79     static constexpr BASE_NS::string_view ENVIRONMENT_COMPONENT_NAME = "EnvironmentComponent";
80     static constexpr BASE_NS::string_view RM_COMPONENT_NAME = "RenderMeshComponent";
81     static constexpr size_t RM_COMPONENT_NAME_LEN = RM_COMPONENT_NAME.size() + 1;
82     static constexpr BASE_NS::string_view RM_HANDLE = "RenderMeshComponent.mesh";
83 
84     // implements CORE_NS::IInterface
85     const CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
86 
87     CORE_NS::IInterface* GetInterface(const BASE_NS::Uid& uid) override;
88 
89     SCENE_NS::NodeState GetAttachedState() const override;
90 
91     bool IsConnected();
92 
93     void DisableInputHandling();
94 
95     bool Connect(const INode::Ptr& parent);
96 
97     void Activate() override;
98 
99     void Deactivate() override;
100 
101     void AttachToHierarchy() override;
102 
103     void DetachFromHierarchy() override;
104 
105     void SubscribeToNameChanges();
106 
107     void UnsubscribeFromNameChanges();
108 
109     bool IsResourceClassType();
110 
111     //todo
112     /*class NameValidator final : public META_NS::NoneSerializableValueValidatorBase<BASE_NS::string> {
113     public:
114         NameValidator(NodeImpl* self) : self_(self) {};
115 
116         [[nodiscard]] ValidationResult Validate(const BASE_NS::string& value) override
117         {
118             ValidationResult result;
119             result.value = value;
120             result.isValueAccepted = true;
121 
122             // Do not allow to change names of scene nodes if they come from IPrefab.
123             if (!self_->IsResourceClassType()) {
124                 if (self_->IsConnected() && !self_->ownsEntity_) {
125                     result.isValueAccepted = false;
126                 }
127             }
128             return result;
129         }
130 
131         NodeImpl* self_ = { nullptr };
132     };*/
133 
134     bool Build(const IMetadata::Ptr& data) override;
135 
136     BASE_NS::string GetName() const override;
137 
138 public: // ISerialization
139     //todo
140  //   bool Import(
141 
142 public: // IEcsObject
143     CORE_NS::IEcs::Ptr GetEcs() const override;
144 
145     void SetEntity(CORE_NS::IEcs::Ptr ecs, CORE_NS::Entity entity) override;
146 
147     CORE_NS::Entity GetEntity() const override;
148 
149     void BindObject(CORE_NS::IEcs::Ptr ecsInstance, CORE_NS::Entity entity) override;
150 
151     void DefineTargetProperties(
152         BASE_NS::unordered_map<BASE_NS::string_view, BASE_NS::vector<BASE_NS::string_view>> names) override;
153 
154     BASE_NS::vector<CORE_NS::Entity> GetAttachments() override;
155 
156     void AddAttachment(CORE_NS::Entity entity) override;
157 
158     void RemoveAttachment(CORE_NS::Entity entity) override;
159 
160     void CloneEcs(const BASE_NS::string& name, META_NS::IObject::Ptr target) const;
161 
162 public: // INodeEcsInterfacePrivate
163     SCENE_NS::IEcsScene::Ptr EcsScene() const override;
164 
165     SCENE_NS::IEcsObject::Ptr EcsObject() const override;
166 
167     SceneHolder::Ptr SceneHolder() const override;
168 
169     void ClaimOwnershipOfEntity(bool ownsEntity) override;
170 
171     void RemoveIndex(size_t index) override;
172 
173     void SetIndex(size_t index) override;
174 
175 public: // INode
176     SCENE_NS::IScene::Ptr GetScene() const override;
177 
178     void RenameEntity(const BASE_NS::string& name);
179 
180     // Todo, this is assuming moderate size of hierarchy, may have to rethink the recursion if that is not the case
181     void RecursivelyEnableCache(bool isActive);
182 
183     // Todo, this is assuming moderate size of hierarchy, may have to rethink the recursion if that is not the case
184     void UpdateChildrenPath();
185 
186     bool Initialize(SCENE_NS::IEcsScene::Ptr& scene, SCENE_NS::IEcsObject::Ptr& ecsObject, SCENE_NS::INode::Ptr parent,
187         const BASE_NS::string& path, const BASE_NS::string& name, SceneHolder::WeakPtr sceneHolder,
188         CORE_NS::Entity entity) override;
189 
190     void BindObject(SCENE_NS::INode::Ptr node);
191 
192     bool CompleteInitialization(const BASE_NS::string& path) override;
193 
194     static void SetPathWithEcsNode(const BASE_NS::shared_ptr<NodeImpl>& self, const BASE_NS::string& name,
195         SceneHolder::Ptr sceneHolder, const CORE3D_NS::ISceneNode* ecsNode);
196 
197     static bool SetPathWithoutNode(const BASE_NS::shared_ptr<NodeImpl>& self, const BASE_NS::string& name,
198         const BASE_NS::string& fullPath, SceneHolder::Ptr sceneHolder);
199 
200     // It is turning out that the path is pretty much the only thing that we can rely when operating asynchronously
201     // from application thread to engine thread. Still this can go wrong if subsequent events are not recorded in
202     // order.
203     void SetPath(const BASE_NS::string& path, const BASE_NS::string& name, CORE_NS::Entity entity) override;
204 
205     static constexpr BASE_NS::string_view LIFECYCLE_PROPERTY_NAME = "NodeLifeCycle";
206 
207     bool HasLifecycleInfo();
208 
209     // Different scenarios currently to be considered
210     // 1) Create and bind a new prefab instance
211     // -> create and assign ecs node
212     // -> create new prefab instance
213     // -> bind (read data from prefab)
214     // prefab and its children need to know they were generated by prefab
215     //
216     // 2) Bind a new node to an existing entity:
217     // this can take place throud two different routes, either the node is explicitly requested from the scene or
218     // restored by de-serialization/import/clone
219     // -> just prepare and assign ecs object
220     // -> system will try find and sync the state later (potentially bidirectional sync)
221     // values that are modified should have set-bits on properties
222     //
223     // 3) Create new proxy with entity and component with default values:
224     // this is either through de-serialization or c++ api
225     // -> sync the proxy state to ecs
226     // information on entity creation needs to be preserved
227 
228     META_NS::IProperty::Ptr GetLifecycleInfo(bool create = true) override;
229 
230     void EnsureEcsBinding(SCENE_NS::IEcsScene::Ptr scene, bool force = false);
231 
232     BASE_NS::vector<PropertyPair> ListBoundProperties() const override;
233 
234     static void BuildChildrenIterateOver(const BASE_NS::shared_ptr<NodeImpl>& self, const SCENE_NS::IEcsScene::Ptr& ecs,
235         const BASE_NS::string& fullPath, BASE_NS::array_view<CORE3D_NS::ISceneNode* const> children);
236 
237     bool BuildChildren(SCENE_NS::INode::BuildBehavior options) override;
238 
239     void CheckChildrenStatus();
240 
241     BASE_NS::Math::Mat4X4 GetGlobalTransform() const override;
242 
243     void SetGlobalTransform(const BASE_NS::Math::Mat4X4& mat) override;
244 
245     struct NodeMonitor {
246         using Ptr = BASE_NS::shared_ptr<NodeMonitor>;
CreateNodeMonitor247         static Ptr Create(SCENE_NS::INode::Ptr& node, NodeImpl& observer)
248         {
249             return Ptr { new NodeMonitor(node, observer) };
250         }
NodeMonitorNodeMonitor251         NodeMonitor(SCENE_NS::INode::Ptr& node, NodeImpl& observer) : node_(node), observer_(observer)
252         {
253             if (node) {
254                 handle_ = node->OnBound()->AddHandler(META_NS::MakeCallback<META_NS::IOnChanged>([this]() {
255                     if (auto node = static_pointer_cast<NodeImpl>(node_.lock())) {
256                         node->META_ACCESS_PROPERTY(Status)->SetValue(SCENE_NS::INode::NODE_STATUS_FULLY_CONNECTED);
257                     }
258                     observer_.CheckChildrenStatus();
259                 }));
260             }
261         }
262 
~NodeMonitorNodeMonitor263         ~NodeMonitor()
264         {
265             if (auto node = node_.lock()) {
266                 node->OnBound()->RemoveHandler(handle_);
267             }
268         }
269 
ReadyNodeMonitor270         bool Ready() const
271         {
272             if (auto node = node_.lock()) {
273                 return node->Status()->GetValue() == SCENE_NS::INode::NODE_STATUS_FULLY_CONNECTED;
274             }
275             return true;
276         }
277 
ValidNodeMonitor278         bool Valid() const
279         {
280             if (auto node = node_.lock()) {
281                 // If nodes status is disconnected, we failed to find ecs entry for it
282                 // other statuses indicate that we keep trying or already succeeded
283                 return node->Status()->GetValue() != SCENE_NS::INode::NODE_STATUS_DISCONNECTED;
284             }
285             return false;
286         }
287 
288         bool operator==(const SCENE_NS::INode::Ptr& other) const
289         {
290             if (auto node = node_.lock()) {
291                 // If nodes status is disconnected, we failed to find ecs entry for it
292                 // other statuses indicate that we keep trying or already succeeded
293                 return other.get() == node.get();
294             }
295             return false;
296         }
297 
298         SCENE_NS::INode::WeakPtr node_;
299         NodeImpl& observer_;
300         META_NS::IEvent::Token handle_ {};
301     };
302     BASE_NS::vector<NodeMonitor::Ptr> monitored_;
303     bool bound_ { false };
304 
305     void MonitorChild(SCENE_NS::INode::Ptr node);
306 
307     void SetMeshToEngine();
308 
309     void SetMesh(SCENE_NS::IMesh::Ptr mesh) override;
310 
311     SCENE_NS::IMultiMeshProxy::Ptr CreateMeshProxy(size_t count, SCENE_NS::IMesh::Ptr mesh) override;
312 
313     void SetMultiMeshProxy(SCENE_NS::IMultiMeshProxy::Ptr multimesh) override;
314 
315     SCENE_NS::IMultiMeshProxy::Ptr GetMultiMeshProxy() const override;
316 
317     void ReleaseEntityOwnership();
318 
319     void Destroy() override;
320 
321     SCENE_NS::IPickingResult::Ptr GetWorldMatrixComponentAABB(bool isRecursive) const override;
322 
323     SCENE_NS::IPickingResult::Ptr GetTransformComponentAABB(bool isRecursive) const override;
324 
325 public: // This and that
326     void SetStatus(SCENE_NS::INode::NodeStatus status);
327 
328 public: // ISerialization
329     void SetSuperInstance(const IObject::Ptr& aggr, const IObject::Ptr& super) override;
330 
331     void SetParent(const IObject::Ptr& parent) override;
332 
333     IObject::Ptr GetParent() const override;
334 
335     SCENE_NS::IMesh::Ptr GetMesh() const override;
336 
337     static void InitializeMesh(const SCENE_NS::IMesh::Ptr& mesh, const BASE_NS::shared_ptr<NodeImpl>& node,
338         const BASE_NS::string_view entityName);
339 
340     static void InitializeMesh(const SCENE_NS::IMesh::Ptr& mesh, const BASE_NS::shared_ptr<SCENE_NS::IEcsObject>& self);
341 
342     SCENE_NS::IMesh::Ptr GetMeshFromEngine();
343 
344     using PropertyNameCriteria = BASE_NS::unordered_map<BASE_NS::string_view, BASE_NS::vector<BASE_NS::string_view>>;
345     PropertyNameCriteria& PropertyNameMask();
346 
347 public:
348     IObject::Ptr Resolve(const META_NS::RefUri& uri) const override;
349 
350 protected:
351     // Data for App thread.
352     PropertyHandlerArrayHolder propHandler_ {};
353     META_NS::IEvent::Token nameChangedToken_ { 0 };
354 
355     // META_NS::IContainer* container_{};
356     META_NS::IContainable* containable_ {};
357     META_NS::IMutableContainable* mutableContainable_ {};
358 
359     // These should be primarily accessed in Engine thread
360     SCENE_NS::IEcsScene::WeakPtr ecsScene_ {};
361     SCENE_NS::IEcsObject::Ptr ecsObject_ {};
362 
363     META_NS::ITaskQueue::Token initializeTaskToken_ {};
364 
365     bool ShouldExport() const override;
366 
367     SceneHolder::WeakPtr sceneHolder_ {};
368     META_NS::IObject::WeakPtr parent_;
369 
370     bool shouldRetry_ { true };
371 
372     SCENE_NS::IMesh::WeakPtr weakMesh_;
373 
374     PropertyNameCriteria ecs_property_names_;
375 
376     SCENE_NS::IEnvironment::Ptr environment_;
377 
378     // when enabled, asks scene to clean up an entity ref keeping the instance alive
379     bool ownsEntity_ { false };
380 
381     SCENE_NS::INode::BuildBehavior buildBehavior_ { NODE_BUILD_CHILDREN_GRADUAL };
382 
383     SCENE_NS::IMultiMeshProxy::Ptr multimesh_;
384 
385     size_t removeIndex_ { SIZE_MAX };
386 
387     SCENE_NS::NodeState attachedState_ { SCENE_NS::NodeState::DETACHED };
388 
389     META_NS::IObjectRegistry* objectRegistry_ { nullptr };
390 };
391 
392 SCENE_BEGIN_NAMESPACE()
393 void RegisterNodeImpl();
394 void UnregisterNodeImpl();
395 SCENE_END_NAMESPACE()
396 #endif
397