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_IECS_H
17 #define API_CORE_ECS_IECS_H
18
19 #include <base/containers/array_view.h>
20 #include <base/containers/refcnt_ptr.h>
21 #include <base/containers/vector.h>
22 #include <core/ecs/entity.h>
23 #include <core/ecs/intf_component_manager.h>
24 #include <core/ecs/intf_entity_manager.h>
25 #include <core/ecs/intf_system.h>
26 #include <core/namespace.h>
27 #include <core/threading/intf_thread_pool.h>
28
29 BASE_BEGIN_NAMESPACE()
30 struct Uid;
31 BASE_END_NAMESPACE()
32
33 CORE_BEGIN_NAMESPACE()
34 class IClassFactory;
35 class ISystem;
36 struct SystemTypeInfo;
37 struct ComponentManagerTypeInfo;
38 /** \addtogroup group_ecs_iecs
39 * @{
40 */
41 /** IEcs */
42 class IEcs {
43 public:
44 /**
45 * Mode that controls how the engine will be used to render a frame. This can be used to skip rendering altogether
46 * when the scene contents have not changed, lowering the GPU and CPU load and saving battery life.
47 */
48 enum RenderMode {
49 /**
50 * In addition to render requests also re-render when the scene is detected to be dirty. The scene is
51 * considered dirty if any component in an entity has been changed, added or removed or rendering is
52 * explicitly requestedthrough RequestRender().
53 */
54 RENDER_IF_DIRTY,
55
56 /**
57 * Render every frame regardless of calls to RequestRender(). This mode will still take v-sync count into
58 * account.
59 */
60 RENDER_ALWAYS,
61 };
62
63 /** Listener for ECS Entity events. */
64 class EntityListener {
65 public:
66 using EventType = IEntityManager::EventType;
67 /** Entities added to processing. */
68 virtual void OnEntityEvent(EventType type, BASE_NS::array_view<const Entity> entities) = 0;
69
70 protected:
71 virtual ~EntityListener() = default;
72 };
73
74 /** Listener for ECS Component events. */
75 class ComponentListener {
76 public:
77 enum class EventType : uint8_t {
78 /** Component created to entity
79 */
80 CREATED,
81 /** Component in entity modified
82 */
83 MODIFIED,
84 /** Component destroyed from entity
85 */
86 DESTROYED
87 };
88 /** Entities added to processing. */
89 virtual void OnComponentEvent(
90 EventType type, const IComponentManager& componentManager, BASE_NS::array_view<const Entity> entities) = 0;
91
92 protected:
93 virtual ~ComponentListener() = default;
94 };
95
96 /** Gets entity manager for ECS.
97 */
98 virtual IEntityManager& GetEntityManager() = 0;
99
100 /** Get components of entity.
101 @param entity Entity where we get components.
102 @param result List where entitys components are written in.
103 */
104 virtual void GetComponents(Entity entity, BASE_NS::vector<IComponentManager*>& result) = 0;
105
106 /** Get systems of this ECS.
107 */
108 virtual BASE_NS::vector<ISystem*> GetSystems() const = 0;
109
110 /** Get one particular system from systems list.
111 * @param uid UID of the system we want to get.
112 */
113 virtual ISystem* GetSystem(const BASE_NS::Uid& uid) const = 0;
114
115 /** Get component managers of this ECS.
116 */
117 virtual BASE_NS::vector<IComponentManager*> GetComponentManagers() const = 0;
118
119 /** Get one particular component manager from component managers list.
120 * @param uid UID of the component manager we want to get.
121 */
122 virtual IComponentManager* GetComponentManager(const BASE_NS::Uid& uid) const = 0;
123
124 /** Clone an entity. Creates a new entity with copies of all components of this entity.
125 * NOTE: Does not clone children of the entity. NodeSystem can be used to clone whole hierarchies
126 * @param entity Entity to be cloned.
127 */
128 virtual Entity CloneEntity(Entity entity) = 0;
129
130 /** Garbage collect entities.
131 */
132 virtual void ProcessEvents() = 0;
133
134 /** Starts all systems.
135 */
136 virtual void Initialize() = 0;
137
138 /** Updates all systems.
139 * @param time Current program time (in us).
140 * @param delta Time it took since last frame (in us).
141 * @return True if rendering is required.
142 */
143 virtual bool Update(uint64_t time, uint64_t delta) = 0;
144
145 /** Stops all systems and removes all entities and components.
146 */
147 virtual void Uninitialize() = 0;
148
149 /** Add an instance of "componentManagerTypeInfo" to "system.
150 @param componentManagerTypeInfo Component manager type that is added to manager list.
151 */
152 virtual IComponentManager* CreateComponentManager(const ComponentManagerTypeInfo& componentManagerTypeInfo) = 0;
153
154 /** Add an instance of "systemInfo" to "system".
155 * @param systemInfo System type that is instantiated to systems list.
156 */
157 virtual ISystem* CreateSystem(const SystemTypeInfo& systemInfo) = 0;
158
159 /** Add listener for Entity events.
160 */
161 virtual void AddListener(EntityListener& listener) = 0;
162
163 /** Remove Entity event listener.
164 */
165 virtual void RemoveListener(EntityListener& listener) = 0;
166
167 /** Add listener for global component events.
168 */
169 virtual void AddListener(ComponentListener& listener) = 0;
170
171 /** Remove global component event listener.
172 */
173 virtual void RemoveListener(ComponentListener& listener) = 0;
174
175 /** Add listener for specific component manager events.
176 */
177 virtual void AddListener(IComponentManager& manager, ComponentListener& listener) = 0;
178
179 /** Remove specific component manager event listener.
180 */
181 virtual void RemoveListener(IComponentManager& manager, ComponentListener& listener) = 0;
182
183 /** Mark ECS dirty and queue current frame for rendering.
184 */
185 virtual void RequestRender() = 0;
186
187 /** Set render mode, either render only when dirty or render always.
188 * @param renderMode Rendering mode.
189 */
190 virtual void SetRenderMode(RenderMode renderMode) = 0;
191
192 /** Retrieve current render mode.
193 */
194 virtual RenderMode GetRenderMode() = 0;
195
196 /** Check if scene requires rendering after Update() has been called.
197 */
198 virtual bool NeedRender() const = 0;
199
200 /** Get access to interface registry
201 */
202 virtual IClassFactory& GetClassFactory() const = 0;
203
204 /** Get access to a thread pool.
205 */
206 virtual const IThreadPool::Ptr& GetThreadPool() const = 0;
207
208 /** Get scaling factor used for the delta time passed to ISystem::Update.
209 */
210 virtual float GetTimeScale() const = 0;
211
212 /** Set scaling factor used for the delta time passed to ISystem::Update.
213 * @param scale Time scaling factor.
214 */
215 virtual void SetTimeScale(float scale) = 0;
216
217 using Ptr = BASE_NS::refcnt_ptr<IEcs>;
218
219 protected:
220 virtual void Ref() noexcept = 0;
221 virtual void Unref() noexcept = 0;
222
223 friend Ptr;
224
225 IEcs() = default;
226 IEcs(const IEcs&) = delete;
227 IEcs(IEcs&&) = delete;
228 IEcs& operator=(const IEcs&) = delete;
229 IEcs& operator=(IEcs&&) = delete;
230 virtual ~IEcs() = default;
231 };
232
233 // Helper method to fetch managers by name
234 /** Get manager */
235 template<class T>
GetManager(const CORE_NS::IEcs & ecs)236 T* GetManager(const CORE_NS::IEcs& ecs)
237 {
238 return reinterpret_cast<T*>(ecs.GetComponentManager(T::UID));
239 }
240
241 /** Get system */
242 template<class T>
GetSystem(const CORE_NS::IEcs & ecs)243 T* GetSystem(const CORE_NS::IEcs& ecs)
244 {
245 return reinterpret_cast<T*>(ecs.GetSystem(T::UID));
246 }
247 /** @} */
248 CORE_END_NAMESPACE()
249
250 #endif // API_CORE_ECS_IECS_H
251