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#ifndef CORE__ECS_HELPER__COMPONENT_TOOLS__BASE_MANAGER_H
16#define CORE__ECS_HELPER__COMPONENT_TOOLS__BASE_MANAGER_H
17
18#include <atomic>
19#include <cstddef>
20#include <cstdint>
21
22#include <base/containers/array_view.h>
23#include <base/containers/string_view.h>
24#include <base/containers/unordered_map.h>
25#include <base/containers/vector.h>
26#include <base/namespace.h>
27#include <base/util/uid.h>
28#include <core/ecs/entity.h>
29#include <core/ecs/intf_component_manager.h>
30#include <core/namespace.h>
31#include <core/property/intf_property_api.h>
32#include <core/property/intf_property_handle.h>
33#include <core/property/scoped_handle.h>
34
35CORE_BEGIN_NAMESPACE()
36class IEcs;
37struct Property;
38
39// BaseClass should inherit IComponentManager AND should follow the basic form of component managers
40// (this will be enforced later)
41template<typename ComponentType, typename BaseClass>
42class BaseManager : public BaseClass, public IPropertyApi {
43    using ComponentId = IComponentManager::ComponentId;
44
45public:
46    // IPropertyApi
47    size_t PropertyCount() const override = 0;
48    const Property* MetaData(size_t index) const override = 0;
49    BASE_NS::array_view<const Property> MetaData() const override = 0;
50    IPropertyHandle* Create() const override;
51    IPropertyHandle* Clone(const IPropertyHandle*) const override;
52    void Release(IPropertyHandle*) const override;
53    uint64_t Type() const override;
54
55    // IComponentManager
56    BASE_NS::string_view GetName() const override;
57    BASE_NS::Uid GetUid() const override;
58    size_t GetComponentCount() const override;
59    const IPropertyApi& GetPropertyApi() const override;
60    Entity GetEntity(ComponentId index) const override;
61    uint32_t GetComponentGeneration(ComponentId index) const override;
62    bool HasComponent(Entity entity) const override;
63    IComponentManager::ComponentId GetComponentId(Entity entity) const override;
64    void Create(Entity entity) override;
65    bool Destroy(Entity entity) override;
66    void Gc() override;
67    void Destroy(BASE_NS::array_view<const Entity> gcList) override;
68    BASE_NS::vector<Entity> GetAddedComponents() override;
69    BASE_NS::vector<Entity> GetRemovedComponents() override;
70    BASE_NS::vector<Entity> GetUpdatedComponents() override;
71    CORE_NS::ComponentManagerModifiedFlags GetModifiedFlags() const override;
72    void ClearModifiedFlags() override;
73    uint32_t GetGenerationCounter() const override;
74    void SetData(Entity entity, const IPropertyHandle& dataHandle) override;
75    const IPropertyHandle* GetData(Entity entity) const override;
76    IPropertyHandle* GetData(Entity entity) override;
77    void SetData(ComponentId index, const IPropertyHandle& dataHandle) override;
78    const IPropertyHandle* GetData(ComponentId index) const override;
79    IPropertyHandle* GetData(ComponentId index) override;
80    IEcs& GetEcs() const override;
81
82    // "base class"
83    ComponentType Get(ComponentId index) const override;
84    ComponentType Get(Entity entity) const override;
85    void Set(ComponentId index, const ComponentType& aData) override;
86    void Set(Entity entity, const ComponentType& aData) override;
87    ScopedHandle<const ComponentType> Read(ComponentId index) const override;
88    ScopedHandle<const ComponentType> Read(Entity entity) const override;
89    ScopedHandle<ComponentType> Write(ComponentId index) override;
90    ScopedHandle<ComponentType> Write(Entity entity) override;
91
92    // internal, non-public
93    void Updated(Entity entity);
94
95    BaseManager(const BaseManager&) = delete;
96    BaseManager(BaseManager&&) = delete;
97    BaseManager& operator=(const BaseManager&) = delete;
98    BaseManager& operator=(BaseManager&&) = delete;
99
100protected:
101    BaseManager(IEcs& ecs, BASE_NS::string_view) noexcept;
102    virtual ~BaseManager();
103    IEcs& ecs_;
104    BASE_NS::string_view name_;
105
106    bool IsMatchingHandle(const IPropertyHandle& handle);
107
108    class BaseComponentHandle : public IPropertyHandle {
109    public:
110        BaseComponentHandle() = delete;
111        BaseComponentHandle(BaseManager* owner, Entity entity) noexcept;
112        BaseComponentHandle(BaseManager* owner, Entity entity, const ComponentType& data) noexcept;
113        ~BaseComponentHandle() override = default;
114        BaseComponentHandle(const BaseComponentHandle& other) = delete;
115        BaseComponentHandle(BaseComponentHandle&& other) noexcept;
116        BaseComponentHandle& operator=(const BaseComponentHandle& other) = delete;
117        BaseComponentHandle& operator=(BaseComponentHandle&& other) noexcept;
118        const IPropertyApi* Owner() const override;
119        size_t Size() const override;
120        const void* RLock() const override;
121        void RUnlock() const override;
122        void* WLock() override;
123        void WUnlock() override;
124
125        mutable std::atomic_uint32_t rLocked_ { 0 };
126        mutable bool wLocked_ { false };
127        bool dirty_ { false };
128        BaseManager* manager_ { nullptr };
129        uint32_t generation_ { 0 };
130        Entity entity_;
131        ComponentType data_;
132    };
133    uint32_t generationCounter_ { 0 };
134    uint32_t modifiedFlags_ { 0 };
135    BASE_NS::unordered_map<Entity, ComponentId> entityComponent_;
136    BASE_NS::vector<BaseComponentHandle> components_;
137    BASE_NS::vector<Entity> added_;
138    BASE_NS::vector<Entity> removed_;
139    BASE_NS::vector<Entity> updated_;
140    uint64_t typeHash_;
141};
142CORE_END_NAMESPACE()
143#endif
144