1 /* 2 * Copyright (C) 2023 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 API_CORE_ECS_ENTITY_REFERENCE_H 17 #define API_CORE_ECS_ENTITY_REFERENCE_H 18 19 #include <base/containers/refcnt_ptr.h> 20 #include <base/containers/type_traits.h> 21 #include <core/ecs/entity.h> 22 #include <core/namespace.h> 23 24 CORE_BEGIN_NAMESPACE() 25 class EntityReference; 26 27 /** Entity reference counter counter. */ 28 class IEntityReferenceCounter { 29 public: 30 using Ptr = BASE_NS::refcnt_ptr<IEntityReferenceCounter>; 31 virtual int32_t GetRefCount() const noexcept = 0; 32 33 protected: 34 virtual void Ref() noexcept = 0; 35 virtual void Unref() noexcept = 0; 36 37 friend Ptr; 38 friend EntityReference; 39 40 IEntityReferenceCounter() = default; 41 virtual ~IEntityReferenceCounter() = default; 42 IEntityReferenceCounter(const IEntityReferenceCounter&) = delete; 43 IEntityReferenceCounter& operator=(const IEntityReferenceCounter&) = delete; 44 IEntityReferenceCounter(IEntityReferenceCounter&&) = delete; 45 IEntityReferenceCounter& operator=(IEntityReferenceCounter&&) = delete; 46 }; 47 48 /** 49 * Helper for updating reference counts of shared entities. 50 */ 51 class EntityReference { 52 public: 53 /** Destructor releases the reference from the owning entity manager. 54 */ 55 ~EntityReference() = default; 56 57 /** Construct an empty reference. */ 58 EntityReference() = default; 59 60 /** Construct a reference for tracking the given entity. 61 * @param entity referenced entity 62 * @param counter Reference counter instance. 63 */ EntityReference(Entity entity,const IEntityReferenceCounter::Ptr & counter)64 EntityReference(Entity entity, const IEntityReferenceCounter::Ptr& counter) noexcept 65 : entity_(entity), counter_(counter) 66 {} 67 68 /** Copy a reference. Reference count will be increased. */ EntityReference(const EntityReference & other)69 EntityReference(const EntityReference& other) noexcept : entity_(other.entity_), counter_(other.counter_) {} 70 71 /** Move a reference. Moved from reference will be empty and reusable. */ EntityReference(EntityReference && other)72 EntityReference(EntityReference&& other) noexcept 73 : entity_(BASE_NS::exchange(other.entity_, Entity {})), counter_(BASE_NS::exchange(other.counter_, nullptr)) 74 {} 75 76 /** Copy a reference. Previous reference will be released and the one aquired. */ 77 EntityReference& operator=(const EntityReference& other) noexcept 78 { 79 if (&other != this) { 80 entity_ = other.entity_; 81 counter_ = other.counter_; 82 } 83 return *this; 84 } 85 86 /** Move a reference. Previous reference will be released and and the moved from reference will be empty and 87 * reusable. */ 88 EntityReference& operator=(EntityReference&& other) noexcept 89 { 90 if (&other != this) { 91 entity_ = BASE_NS::exchange(other.entity_, Entity {}); 92 counter_ = BASE_NS::exchange(other.counter_, nullptr); 93 } 94 return *this; 95 } 96 97 /** Get the referenced entity. */ Entity()98 operator Entity() const noexcept 99 { 100 return entity_; 101 } 102 103 /** Check validity of the reference. 104 * @return true if the reference is valid. 105 */ 106 explicit operator bool() const noexcept 107 { 108 return EntityUtil::IsValid(entity_) && (counter_); 109 } 110 111 /** Get ref count. Return 0, if invalid. 112 * @return Get reference count of render handle reference. 113 */ GetRefCount()114 int32_t GetRefCount() const noexcept 115 { 116 if (counter_) { 117 return counter_->GetRefCount(); 118 } 119 return 0; 120 } 121 122 private: 123 Entity entity_; 124 IEntityReferenceCounter::Ptr counter_; 125 }; 126 CORE_END_NAMESPACE() 127 128 #endif // API_CORE_ECS_ENTITY_REFERENCE_H 129