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 API_CORE_ECS_ICOMPONENT_MANAGER_H
17 #define API_CORE_ECS_ICOMPONENT_MANAGER_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include <base/containers/string_view.h>
23 #include <base/containers/vector.h>
24 #include <base/namespace.h>
25 #include <base/util/uid.h>
26 #include <core/ecs/entity.h>
27 #include <core/namespace.h>
28 
29 BASE_BEGIN_NAMESPACE()
30 template<class T>
31 class array_view;
32 BASE_END_NAMESPACE()
33 
34 CORE_BEGIN_NAMESPACE()
35 class IPropertyApi;
36 class IPropertyHandle;
37 class IEcs;
38 
39 /** \addtogroup group_ecs_icomponentmanager
40  *  @{
41  */
42 /** Component manager modified flag bits */
43 enum ComponentManagerModifiedFlagBits {
44     /** Component added bit */
45     CORE_COMPONENT_MANAGER_COMPONENT_ADDED_BIT = 0x00000001,
46     /** Component removed bit */
47     CORE_COMPONENT_MANAGER_COMPONENT_REMOVED_BIT = 0x00000002,
48     /** Component updated bit */
49     CORE_COMPONENT_MANAGER_COMPONENT_UPDATED_BIT = 0x00000004,
50     /** Modified flag bits max enumeration */
51     CORE_COMPONENT_MANAGER_MODIFIED_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
52 };
53 /** Container for component manager modified flag bits */
54 using ComponentManagerModifiedFlags = uint32_t;
55 
56 /**
57 Component Manager.
58 
59 */
60 class IComponentManager {
61 public:
62     using ComponentId = uint32_t;
63     static constexpr ComponentId INVALID_COMPONENT_ID = 0xFFFFFFFF;
64 
65     /** Returns the name of the component type.
66      */
67     virtual BASE_NS::string_view GetName() const = 0;
68 
69     /** Returns the UID of the component type.
70      */
71     virtual BASE_NS::Uid GetUid() const = 0;
72 
73     /** Returns the total number of components. Includes components that are being destroyed but are not yet garbage
74      *  collected.
75      */
76     virtual size_t GetComponentCount() const = 0;
77 
78     /** Access to metadata defining the contents of the component.
79      */
80     virtual const IPropertyApi& GetPropertyApi() const = 0;
81 
82     /** Returns entity for component index. May return invalid entity if the entity is being destroyed.
83      */
84     virtual Entity GetEntity(IComponentManager::ComponentId index) const = 0;
85 
86     /** Get component generation id, which is incremented every time the component data is changed.
87      */
88     virtual uint32_t GetComponentGeneration(IComponentManager::ComponentId index) const = 0;
89 
90     // Entity api.
91     /** Checks if Entity has component.
92      *  @param entity Entity to be checked.
93      */
94     virtual bool HasComponent(Entity entity) const = 0;
95 
96     /** Retrieves component id for a given entity.
97      *  @param entity Entity to be used as a search key.
98      */
99     virtual IComponentManager::ComponentId GetComponentId(Entity entity) const = 0;
100 
101     /** Creates a default component for entity.
102      *  @param entity Entity which for component is created.
103      */
104     virtual void Create(Entity entity) = 0;
105 
106     /** Removes component from entity.
107      *  @param entity Entity where component is removed.
108      */
109     virtual bool Destroy(Entity entity) = 0;
110 
111     /** Garbage collect components.
112      *  This is called automatically by the ECS, but can be called by the user too to force cleanup.
113      */
114     virtual void Gc() = 0;
115 
116     /** Remove components from entities.
117      *  @param gcList List of entities to have their components removed
118      */
119     virtual void Destroy(BASE_NS::array_view<const Entity> gcList) = 0;
120 
121     /** Get list of entities that have new components of this type (since last call).
122      */
123     virtual BASE_NS::vector<Entity> GetAddedComponents() = 0;
124 
125     /** Get list of entities that no longer have components of this type (since last call).
126      */
127     virtual BASE_NS::vector<Entity> GetRemovedComponents() = 0;
128 
129     /** Get list of entities that have been modified (since last call).
130      */
131     virtual BASE_NS::vector<Entity> GetUpdatedComponents() = 0;
132 
133     /** Returns flags if component is added, removed or updated.
134      */
135     virtual ComponentManagerModifiedFlags GetModifiedFlags() const = 0;
136 
137     /** Clears all flags of component (Application developer should not call this since its been automatically called
138      * after every frame).
139      */
140     virtual void ClearModifiedFlags() = 0;
141 
142     /** Number of changes occured in this component manager since start of its life.
143      */
144     virtual uint32_t GetGenerationCounter() const = 0;
145 
146     /** Set data for entity. Copies the data from "data" handle to the component for entity.
147      *  @param entity Entity which is set-up.
148      *  @param data property handle for entity.
149      */
150     virtual void SetData(Entity entity, const IPropertyHandle& data) = 0;
151 
152     /** Get data for entity. This handle can be used to directly read the component for entity.
153      *  @param entity Entity where we get our property handle.
154      */
155     virtual const IPropertyHandle* GetData(Entity entity) const = 0;
156 
157     /** Get data for entity. This handle can be used to directly modify the component for entity.
158      *  @param entity Entity where we get our property handle.
159      */
160     virtual IPropertyHandle* GetData(Entity entity) = 0;
161 
162     /** Set data for entity. Copies the data from "data" handle to the component.
163      *  @param index Index what is used to add or update the component if index is same as before.
164      *  @param data Data which is set to component.
165      */
166     virtual void SetData(ComponentId index, const IPropertyHandle& data) = 0;
167 
168     /** Get data for entity. This handle can be used to directly read the component for entity.
169      *  @param index Index to get data from
170      */
171     virtual const IPropertyHandle* GetData(ComponentId index) const = 0;
172 
173     /** Get data for entity. This handle can be used to directly modify the component for entity.
174      *  @param index Index to get data from
175      */
176     virtual IPropertyHandle* GetData(ComponentId index) = 0;
177 
178     /** Get the ECS instance using this manager.
179      * @return Reference to owning ECS instance.
180      */
181     virtual IEcs& GetEcs() const = 0;
182 
183 protected:
184     IComponentManager() = default;
185     IComponentManager(const IComponentManager&) = delete;
186     IComponentManager(IComponentManager&&) = delete;
187     IComponentManager& operator=(const IComponentManager&) = delete;
188     virtual ~IComponentManager() = default;
189 };
190 
191 /** Get name */
192 template<class T>
GetName()193 inline constexpr BASE_NS::string_view GetName()
194 {
195     return GetName((const T*)nullptr);
196 }
197 
198 /** Get UID */
199 template<class T>
GetUid()200 inline constexpr BASE_NS::Uid GetUid()
201 {
202     return GetUid((const T*)nullptr);
203 }
204 
205 /** Create component */
206 template<class T>
CreateComponent(T & componentManager,const Entity & entity)207 inline auto CreateComponent(T& componentManager, const Entity& entity)
208 {
209     componentManager.Create(entity);
210     return componentManager.Get(entity);
211 }
212 
213 /** @} */
214 CORE_END_NAMESPACE()
215 
216 #endif // API_CORE_ECS_ICOMPONENT_MANAGER_H
217