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