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