• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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