18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include <core/log.h>
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE()
198bf80f4bSopenharmony_cinamespace {
208bf80f4bSopenharmony_ciconstexpr uint32_t MODIFIED = 0x80000000;
218bf80f4bSopenharmony_ci} // namespace
228bf80f4bSopenharmony_ci
238bf80f4bSopenharmony_ci// IPropertyApi
248bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
258bf80f4bSopenharmony_ciIPropertyHandle* BaseManager<ComponentType, BaseClass>::Create() const
268bf80f4bSopenharmony_ci{
278bf80f4bSopenharmony_ci    return new BaseComponentHandle(const_cast<BaseManager<ComponentType, BaseClass>*>(this), {}, {});
288bf80f4bSopenharmony_ci}
298bf80f4bSopenharmony_ci
308bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
318bf80f4bSopenharmony_ciIPropertyHandle* BaseManager<ComponentType, BaseClass>::Clone(const IPropertyHandle* src) const
328bf80f4bSopenharmony_ci{
338bf80f4bSopenharmony_ci    if (src->Owner() == this) {
348bf80f4bSopenharmony_ci        auto* h = static_cast<const BaseComponentHandle*>(src);
358bf80f4bSopenharmony_ci        return new BaseComponentHandle(const_cast<BaseManager<ComponentType, BaseClass>*>(this), {}, h->data_);
368bf80f4bSopenharmony_ci    }
378bf80f4bSopenharmony_ci    return nullptr;
388bf80f4bSopenharmony_ci}
398bf80f4bSopenharmony_ci
408bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
418bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Release(IPropertyHandle* dst) const
428bf80f4bSopenharmony_ci{
438bf80f4bSopenharmony_ci    if (dst && (dst->Owner() == this)) {
448bf80f4bSopenharmony_ci        // we can only destroy things we "own" (know)
458bf80f4bSopenharmony_ci        auto* handle = static_cast<BaseComponentHandle*>(dst);
468bf80f4bSopenharmony_ci        if (auto id = GetComponentId(handle->entity_); id != IComponentManager::INVALID_COMPONENT_ID) {
478bf80f4bSopenharmony_ci            if (&components_[id] == handle) {
488bf80f4bSopenharmony_ci                // This is one of the components (bound to an entity) so do nothing
498bf80f4bSopenharmony_ci                return;
508bf80f4bSopenharmony_ci            }
518bf80f4bSopenharmony_ci        }
528bf80f4bSopenharmony_ci        delete handle;
538bf80f4bSopenharmony_ci    }
548bf80f4bSopenharmony_ci}
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
578bf80f4bSopenharmony_ciuint64_t BaseManager<ComponentType, BaseClass>::Type() const
588bf80f4bSopenharmony_ci{
598bf80f4bSopenharmony_ci    return typeHash_;
608bf80f4bSopenharmony_ci}
618bf80f4bSopenharmony_ci
628bf80f4bSopenharmony_ci// IComponentManager
638bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
648bf80f4bSopenharmony_ciBASE_NS::string_view BaseManager<ComponentType, BaseClass>::GetName() const
658bf80f4bSopenharmony_ci{
668bf80f4bSopenharmony_ci    return name_;
678bf80f4bSopenharmony_ci}
688bf80f4bSopenharmony_ci
698bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
708bf80f4bSopenharmony_ciBASE_NS::Uid BaseManager<ComponentType, BaseClass>::GetUid() const
718bf80f4bSopenharmony_ci{
728bf80f4bSopenharmony_ci    return BaseClass::UID;
738bf80f4bSopenharmony_ci}
748bf80f4bSopenharmony_ci
758bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
768bf80f4bSopenharmony_cisize_t BaseManager<ComponentType, BaseClass>::GetComponentCount() const
778bf80f4bSopenharmony_ci{
788bf80f4bSopenharmony_ci    return components_.size();
798bf80f4bSopenharmony_ci}
808bf80f4bSopenharmony_ci
818bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
828bf80f4bSopenharmony_ciconst IPropertyApi& BaseManager<ComponentType, BaseClass>::GetPropertyApi() const
838bf80f4bSopenharmony_ci{
848bf80f4bSopenharmony_ci    return *this;
858bf80f4bSopenharmony_ci}
868bf80f4bSopenharmony_ci
878bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
888bf80f4bSopenharmony_ciCORE_NS::Entity BaseManager<ComponentType, BaseClass>::GetEntity(ComponentId index) const
898bf80f4bSopenharmony_ci{
908bf80f4bSopenharmony_ci    if (index < components_.size()) {
918bf80f4bSopenharmony_ci        return components_[index].entity_;
928bf80f4bSopenharmony_ci    }
938bf80f4bSopenharmony_ci    return CORE_NS::Entity();
948bf80f4bSopenharmony_ci}
958bf80f4bSopenharmony_ci
968bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
978bf80f4bSopenharmony_ciuint32_t BaseManager<ComponentType, BaseClass>::GetComponentGeneration(ComponentId index) const
988bf80f4bSopenharmony_ci{
998bf80f4bSopenharmony_ci    if (index < components_.size()) {
1008bf80f4bSopenharmony_ci        return components_[index].generation_;
1018bf80f4bSopenharmony_ci    }
1028bf80f4bSopenharmony_ci    return 0;
1038bf80f4bSopenharmony_ci}
1048bf80f4bSopenharmony_ci
1058bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1068bf80f4bSopenharmony_cibool BaseManager<ComponentType, BaseClass>::HasComponent(CORE_NS::Entity entity) const
1078bf80f4bSopenharmony_ci{
1088bf80f4bSopenharmony_ci    return GetComponentId(entity) != IComponentManager::INVALID_COMPONENT_ID;
1098bf80f4bSopenharmony_ci}
1108bf80f4bSopenharmony_ci
1118bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1128bf80f4bSopenharmony_ciIComponentManager::ComponentId BaseManager<ComponentType, BaseClass>::GetComponentId(CORE_NS::Entity entity) const
1138bf80f4bSopenharmony_ci{
1148bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
1158bf80f4bSopenharmony_ci        if (auto it = entityComponent_.find(entity); it != entityComponent_.end()) {
1168bf80f4bSopenharmony_ci            return it->second;
1178bf80f4bSopenharmony_ci        }
1188bf80f4bSopenharmony_ci    }
1198bf80f4bSopenharmony_ci    return IComponentManager::INVALID_COMPONENT_ID;
1208bf80f4bSopenharmony_ci}
1218bf80f4bSopenharmony_ci
1228bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1238bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Create(CORE_NS::Entity entity)
1248bf80f4bSopenharmony_ci{
1258bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
1268bf80f4bSopenharmony_ci        if (auto it = entityComponent_.find(entity); it == entityComponent_.end()) {
1278bf80f4bSopenharmony_ci            entityComponent_.insert({ entity, static_cast<ComponentId>(components_.size()) });
1288bf80f4bSopenharmony_ci            components_.emplace_back(this, entity);
1298bf80f4bSopenharmony_ci            added_.push_back(entity);
1308bf80f4bSopenharmony_ci            modifiedFlags_ |= CORE_COMPONENT_MANAGER_COMPONENT_ADDED_BIT;
1318bf80f4bSopenharmony_ci            ++generationCounter_;
1328bf80f4bSopenharmony_ci        } else {
1338bf80f4bSopenharmony_ci            if (auto dst = ScopedHandle<ComponentType>(&components_[it->second]); dst) {
1348bf80f4bSopenharmony_ci                *dst = {};
1358bf80f4bSopenharmony_ci            }
1368bf80f4bSopenharmony_ci        }
1378bf80f4bSopenharmony_ci    }
1388bf80f4bSopenharmony_ci}
1398bf80f4bSopenharmony_ci
1408bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1418bf80f4bSopenharmony_cibool BaseManager<ComponentType, BaseClass>::Destroy(CORE_NS::Entity entity)
1428bf80f4bSopenharmony_ci{
1438bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
1448bf80f4bSopenharmony_ci        if (auto it = entityComponent_.find(entity); it != entityComponent_.end()) {
1458bf80f4bSopenharmony_ci            components_[it->second].entity_ = {}; // invalid entity. (marks it as ready for re-use)
1468bf80f4bSopenharmony_ci            entityComponent_.erase(it);
1478bf80f4bSopenharmony_ci            removed_.push_back(entity);
1488bf80f4bSopenharmony_ci            modifiedFlags_ |= CORE_COMPONENT_MANAGER_COMPONENT_REMOVED_BIT;
1498bf80f4bSopenharmony_ci            ++generationCounter_;
1508bf80f4bSopenharmony_ci            return true;
1518bf80f4bSopenharmony_ci        }
1528bf80f4bSopenharmony_ci    }
1538bf80f4bSopenharmony_ci    return false;
1548bf80f4bSopenharmony_ci}
1558bf80f4bSopenharmony_ci
1568bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1578bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Gc()
1588bf80f4bSopenharmony_ci{
1598bf80f4bSopenharmony_ci    const bool hasRemovedComponents = modifiedFlags_ & CORE_COMPONENT_MANAGER_COMPONENT_REMOVED_BIT;
1608bf80f4bSopenharmony_ci    if (!hasRemovedComponents) {
1618bf80f4bSopenharmony_ci        return;
1628bf80f4bSopenharmony_ci    }
1638bf80f4bSopenharmony_ci    ComponentId componentCount = static_cast<ComponentId>(components_.size());
1648bf80f4bSopenharmony_ci    for (ComponentId id = 0; id < componentCount;) {
1658bf80f4bSopenharmony_ci        auto* it = &components_[id];
1668bf80f4bSopenharmony_ci        // invalid entity.. if so clean garbage
1678bf80f4bSopenharmony_ci        if (!EntityUtil::IsValid(it->entity_)) {
1688bf80f4bSopenharmony_ci            // find last valid and swap with it
1698bf80f4bSopenharmony_ci            for (ComponentId rid = componentCount - 1; rid > id; rid--) {
1708bf80f4bSopenharmony_ci                auto* rit = &components_[rid];
1718bf80f4bSopenharmony_ci                // valid entity? if so swap the components.
1728bf80f4bSopenharmony_ci                if (EntityUtil::IsValid(rit->entity_)) {
1738bf80f4bSopenharmony_ci                    // fix the entityComponent_ map (update the component id for the entity)
1748bf80f4bSopenharmony_ci                    entityComponent_[rit->entity_] = id;
1758bf80f4bSopenharmony_ci                    *it = BASE_NS::move(*rit);
1768bf80f4bSopenharmony_ci                    break;
1778bf80f4bSopenharmony_ci                }
1788bf80f4bSopenharmony_ci            }
1798bf80f4bSopenharmony_ci            --componentCount;
1808bf80f4bSopenharmony_ci            continue;
1818bf80f4bSopenharmony_ci        }
1828bf80f4bSopenharmony_ci        ++id;
1838bf80f4bSopenharmony_ci    }
1848bf80f4bSopenharmony_ci    if (components_.size() > componentCount) {
1858bf80f4bSopenharmony_ci        auto diff = static_cast<typename decltype(components_)::difference_type>(componentCount);
1868bf80f4bSopenharmony_ci        components_.erase(components_.cbegin() + diff, components_.cend());
1878bf80f4bSopenharmony_ci    }
1888bf80f4bSopenharmony_ci}
1898bf80f4bSopenharmony_ci
1908bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1918bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Destroy(BASE_NS::array_view<const CORE_NS::Entity> gcList)
1928bf80f4bSopenharmony_ci{
1938bf80f4bSopenharmony_ci    for (const CORE_NS::Entity e : gcList) {
1948bf80f4bSopenharmony_ci        Destroy(e);
1958bf80f4bSopenharmony_ci    }
1968bf80f4bSopenharmony_ci}
1978bf80f4bSopenharmony_ci
1988bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
1998bf80f4bSopenharmony_ciBASE_NS::vector<CORE_NS::Entity> BaseManager<ComponentType, BaseClass>::GetAddedComponents()
2008bf80f4bSopenharmony_ci{
2018bf80f4bSopenharmony_ci    return BASE_NS::move(added_);
2028bf80f4bSopenharmony_ci}
2038bf80f4bSopenharmony_ci
2048bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2058bf80f4bSopenharmony_ciBASE_NS::vector<CORE_NS::Entity> BaseManager<ComponentType, BaseClass>::GetRemovedComponents()
2068bf80f4bSopenharmony_ci{
2078bf80f4bSopenharmony_ci    return BASE_NS::move(removed_);
2088bf80f4bSopenharmony_ci}
2098bf80f4bSopenharmony_ci
2108bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2118bf80f4bSopenharmony_ciBASE_NS::vector<CORE_NS::Entity> BaseManager<ComponentType, BaseClass>::GetUpdatedComponents()
2128bf80f4bSopenharmony_ci{
2138bf80f4bSopenharmony_ci    BASE_NS::vector<CORE_NS::Entity> updated;
2148bf80f4bSopenharmony_ci    if (modifiedFlags_ & MODIFIED) {
2158bf80f4bSopenharmony_ci        modifiedFlags_ &= ~MODIFIED;
2168bf80f4bSopenharmony_ci        updated.reserve(components_.size() / 2); // 2: aproximation for vector reserve size
2178bf80f4bSopenharmony_ci        for (auto& handle : components_) {
2188bf80f4bSopenharmony_ci            if (handle.dirty_) {
2198bf80f4bSopenharmony_ci                handle.dirty_ = false;
2208bf80f4bSopenharmony_ci                updated.push_back(handle.entity_);
2218bf80f4bSopenharmony_ci            }
2228bf80f4bSopenharmony_ci        }
2238bf80f4bSopenharmony_ci    }
2248bf80f4bSopenharmony_ci    return updated;
2258bf80f4bSopenharmony_ci}
2268bf80f4bSopenharmony_ci
2278bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2288bf80f4bSopenharmony_ciCORE_NS::ComponentManagerModifiedFlags BaseManager<ComponentType, BaseClass>::GetModifiedFlags() const
2298bf80f4bSopenharmony_ci{
2308bf80f4bSopenharmony_ci    return modifiedFlags_ & ~MODIFIED;
2318bf80f4bSopenharmony_ci}
2328bf80f4bSopenharmony_ci
2338bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2348bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::ClearModifiedFlags()
2358bf80f4bSopenharmony_ci{
2368bf80f4bSopenharmony_ci    modifiedFlags_ &= MODIFIED;
2378bf80f4bSopenharmony_ci}
2388bf80f4bSopenharmony_ci
2398bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2408bf80f4bSopenharmony_ciuint32_t BaseManager<ComponentType, BaseClass>::GetGenerationCounter() const
2418bf80f4bSopenharmony_ci{
2428bf80f4bSopenharmony_ci    return generationCounter_;
2438bf80f4bSopenharmony_ci}
2448bf80f4bSopenharmony_ci
2458bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2468bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::SetData(CORE_NS::Entity entity, const IPropertyHandle& dataHandle)
2478bf80f4bSopenharmony_ci{
2488bf80f4bSopenharmony_ci    if (!IsMatchingHandle(dataHandle)) {
2498bf80f4bSopenharmony_ci        return;
2508bf80f4bSopenharmony_ci    }
2518bf80f4bSopenharmony_ci    if (const auto src = ScopedHandle<const ComponentType>(&dataHandle); src) {
2528bf80f4bSopenharmony_ci        if (const auto it = entityComponent_.find(entity); it != entityComponent_.end()) {
2538bf80f4bSopenharmony_ci            if (auto dst = ScopedHandle<ComponentType>(&components_[it->second]); dst) {
2548bf80f4bSopenharmony_ci                *dst = *src;
2558bf80f4bSopenharmony_ci            }
2568bf80f4bSopenharmony_ci        }
2578bf80f4bSopenharmony_ci    }
2588bf80f4bSopenharmony_ci}
2598bf80f4bSopenharmony_ci
2608bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2618bf80f4bSopenharmony_ciconst IPropertyHandle* BaseManager<ComponentType, BaseClass>::GetData(CORE_NS::Entity entity) const
2628bf80f4bSopenharmony_ci{
2638bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
2648bf80f4bSopenharmony_ci        if (const auto it = entityComponent_.find(entity); it != entityComponent_.end()) {
2658bf80f4bSopenharmony_ci            if (it->second < components_.size()) {
2668bf80f4bSopenharmony_ci                return &components_[it->second];
2678bf80f4bSopenharmony_ci            }
2688bf80f4bSopenharmony_ci        }
2698bf80f4bSopenharmony_ci    }
2708bf80f4bSopenharmony_ci    return nullptr;
2718bf80f4bSopenharmony_ci}
2728bf80f4bSopenharmony_ci
2738bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2748bf80f4bSopenharmony_ciIPropertyHandle* BaseManager<ComponentType, BaseClass>::GetData(CORE_NS::Entity entity)
2758bf80f4bSopenharmony_ci{
2768bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
2778bf80f4bSopenharmony_ci        if (const auto it = entityComponent_.find(entity); it != entityComponent_.end()) {
2788bf80f4bSopenharmony_ci            if (it->second < components_.size()) {
2798bf80f4bSopenharmony_ci                return &components_[it->second];
2808bf80f4bSopenharmony_ci            }
2818bf80f4bSopenharmony_ci        }
2828bf80f4bSopenharmony_ci    }
2838bf80f4bSopenharmony_ci    return nullptr;
2848bf80f4bSopenharmony_ci}
2858bf80f4bSopenharmony_ci
2868bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
2878bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::SetData(ComponentId index, const IPropertyHandle& dataHandle)
2888bf80f4bSopenharmony_ci{
2898bf80f4bSopenharmony_ci    if (!IsMatchingHandle(dataHandle)) {
2908bf80f4bSopenharmony_ci        // We could verify the metadata here.
2918bf80f4bSopenharmony_ci        // And in copy only the matching properties one-by-one also.
2928bf80f4bSopenharmony_ci        return;
2938bf80f4bSopenharmony_ci    }
2948bf80f4bSopenharmony_ci    if (index < components_.size()) {
2958bf80f4bSopenharmony_ci        if (const auto src = ScopedHandle<const ComponentType>(&dataHandle); src) {
2968bf80f4bSopenharmony_ci            if (auto dst = ScopedHandle<ComponentType>(&components_[index]); dst) {
2978bf80f4bSopenharmony_ci                *dst = *src;
2988bf80f4bSopenharmony_ci            }
2998bf80f4bSopenharmony_ci        }
3008bf80f4bSopenharmony_ci    }
3018bf80f4bSopenharmony_ci}
3028bf80f4bSopenharmony_ci
3038bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3048bf80f4bSopenharmony_ciconst IPropertyHandle* BaseManager<ComponentType, BaseClass>::GetData(ComponentId index) const
3058bf80f4bSopenharmony_ci{
3068bf80f4bSopenharmony_ci    if (index < components_.size()) {
3078bf80f4bSopenharmony_ci        return &components_[index];
3088bf80f4bSopenharmony_ci    }
3098bf80f4bSopenharmony_ci    return nullptr;
3108bf80f4bSopenharmony_ci}
3118bf80f4bSopenharmony_ci
3128bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3138bf80f4bSopenharmony_ciIPropertyHandle* BaseManager<ComponentType, BaseClass>::GetData(ComponentId index)
3148bf80f4bSopenharmony_ci{
3158bf80f4bSopenharmony_ci    if (index < components_.size()) {
3168bf80f4bSopenharmony_ci        return &components_[index];
3178bf80f4bSopenharmony_ci    }
3188bf80f4bSopenharmony_ci    return nullptr;
3198bf80f4bSopenharmony_ci}
3208bf80f4bSopenharmony_ci
3218bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3228bf80f4bSopenharmony_ciIEcs& BaseManager<ComponentType, BaseClass>::GetEcs() const
3238bf80f4bSopenharmony_ci{
3248bf80f4bSopenharmony_ci    return ecs_;
3258bf80f4bSopenharmony_ci}
3268bf80f4bSopenharmony_ci
3278bf80f4bSopenharmony_ci// "base class"
3288bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3298bf80f4bSopenharmony_ciComponentType BaseManager<ComponentType, BaseClass>::Get(ComponentId index) const
3308bf80f4bSopenharmony_ci{
3318bf80f4bSopenharmony_ci    CORE_ASSERT_MSG(index < components_.size(), "Invalid ComponentId");
3328bf80f4bSopenharmony_ci    if (auto handle = ScopedHandle<const ComponentType>(GetData(index)); handle) {
3338bf80f4bSopenharmony_ci        return *handle;
3348bf80f4bSopenharmony_ci    }
3358bf80f4bSopenharmony_ci    return ComponentType {};
3368bf80f4bSopenharmony_ci}
3378bf80f4bSopenharmony_ci
3388bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3398bf80f4bSopenharmony_ciComponentType BaseManager<ComponentType, BaseClass>::Get(CORE_NS::Entity entity) const
3408bf80f4bSopenharmony_ci{
3418bf80f4bSopenharmony_ci    if (auto handle = ScopedHandle<const ComponentType>(GetData(entity)); handle) {
3428bf80f4bSopenharmony_ci        return *handle;
3438bf80f4bSopenharmony_ci    }
3448bf80f4bSopenharmony_ci    return ComponentType {};
3458bf80f4bSopenharmony_ci}
3468bf80f4bSopenharmony_ci
3478bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3488bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Set(ComponentId index, const ComponentType& data)
3498bf80f4bSopenharmony_ci{
3508bf80f4bSopenharmony_ci    if (auto handle = ScopedHandle<ComponentType>(GetData(index)); handle) {
3518bf80f4bSopenharmony_ci        *handle = data;
3528bf80f4bSopenharmony_ci    }
3538bf80f4bSopenharmony_ci}
3548bf80f4bSopenharmony_ci
3558bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3568bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Set(CORE_NS::Entity entity, const ComponentType& data)
3578bf80f4bSopenharmony_ci{
3588bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity)) {
3598bf80f4bSopenharmony_ci        if (const auto it = entityComponent_.find(entity); it == entityComponent_.end()) {
3608bf80f4bSopenharmony_ci            entityComponent_.insert({ entity, static_cast<ComponentId>(components_.size()) });
3618bf80f4bSopenharmony_ci            components_.emplace_back(this, entity, data).generation_ = 1;
3628bf80f4bSopenharmony_ci            added_.push_back(entity);
3638bf80f4bSopenharmony_ci            modifiedFlags_ |= CORE_COMPONENT_MANAGER_COMPONENT_ADDED_BIT;
3648bf80f4bSopenharmony_ci            ++generationCounter_;
3658bf80f4bSopenharmony_ci        } else {
3668bf80f4bSopenharmony_ci            if (auto handle = ScopedHandle<ComponentType>(&components_[it->second]); handle) {
3678bf80f4bSopenharmony_ci                *handle = data;
3688bf80f4bSopenharmony_ci            }
3698bf80f4bSopenharmony_ci        }
3708bf80f4bSopenharmony_ci    }
3718bf80f4bSopenharmony_ci}
3728bf80f4bSopenharmony_ci
3738bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3748bf80f4bSopenharmony_ciScopedHandle<const ComponentType> BaseManager<ComponentType, BaseClass>::Read(ComponentId index) const
3758bf80f4bSopenharmony_ci{
3768bf80f4bSopenharmony_ci    return ScopedHandle<const ComponentType> { GetData(index) };
3778bf80f4bSopenharmony_ci}
3788bf80f4bSopenharmony_ci
3798bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3808bf80f4bSopenharmony_ciScopedHandle<const ComponentType> BaseManager<ComponentType, BaseClass>::Read(CORE_NS::Entity entity) const
3818bf80f4bSopenharmony_ci{
3828bf80f4bSopenharmony_ci    return ScopedHandle<const ComponentType> { GetData(entity) };
3838bf80f4bSopenharmony_ci}
3848bf80f4bSopenharmony_ci
3858bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3868bf80f4bSopenharmony_ciScopedHandle<ComponentType> BaseManager<ComponentType, BaseClass>::Write(ComponentId index)
3878bf80f4bSopenharmony_ci{
3888bf80f4bSopenharmony_ci    return ScopedHandle<ComponentType> { GetData(index) };
3898bf80f4bSopenharmony_ci}
3908bf80f4bSopenharmony_ci
3918bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3928bf80f4bSopenharmony_ciScopedHandle<ComponentType> BaseManager<ComponentType, BaseClass>::Write(CORE_NS::Entity entity)
3938bf80f4bSopenharmony_ci{
3948bf80f4bSopenharmony_ci    return ScopedHandle<ComponentType> { GetData(entity) };
3958bf80f4bSopenharmony_ci}
3968bf80f4bSopenharmony_ci
3978bf80f4bSopenharmony_ci// internal
3988bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
3998bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::Updated(CORE_NS::Entity entity)
4008bf80f4bSopenharmony_ci{
4018bf80f4bSopenharmony_ci    CORE_ASSERT_MSG(EntityUtil::IsValid(entity), "Invalid ComponentId, bound to INVALID_ENTITY");
4028bf80f4bSopenharmony_ci    modifiedFlags_ |= CORE_COMPONENT_MANAGER_COMPONENT_UPDATED_BIT | MODIFIED;
4038bf80f4bSopenharmony_ci    ++generationCounter_;
4048bf80f4bSopenharmony_ci}
4058bf80f4bSopenharmony_ci
4068bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4078bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::BaseManager(IEcs& ecs, const BASE_NS::string_view name) noexcept
4088bf80f4bSopenharmony_ci    : ecs_(ecs), name_(name)
4098bf80f4bSopenharmony_ci{
4108bf80f4bSopenharmony_ci    // Initial reservation for 64 components/entities.
4118bf80f4bSopenharmony_ci    // Will resize as needed.
4128bf80f4bSopenharmony_ci    constexpr size_t INITIAL_COMPONENT_RESERVE_SIZE = 64;
4138bf80f4bSopenharmony_ci    components_.reserve(INITIAL_COMPONENT_RESERVE_SIZE);
4148bf80f4bSopenharmony_ci    entityComponent_.reserve(INITIAL_COMPONENT_RESERVE_SIZE);
4158bf80f4bSopenharmony_ci    typeHash_ = BASE_NS::FNV1aHash(name_.data(), name_.size());
4168bf80f4bSopenharmony_ci}
4178bf80f4bSopenharmony_ci
4188bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4198bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::~BaseManager()
4208bf80f4bSopenharmony_ci{
4218bf80f4bSopenharmony_ci    CORE_ASSERT(GetComponentCount() == 0);
4228bf80f4bSopenharmony_ci}
4238bf80f4bSopenharmony_ci
4248bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4258bf80f4bSopenharmony_cibool BaseManager<ComponentType, BaseClass>::IsMatchingHandle(const IPropertyHandle& dataHandle)
4268bf80f4bSopenharmony_ci{
4278bf80f4bSopenharmony_ci    if (dataHandle.Owner() == this) {
4288bf80f4bSopenharmony_ci        return true;
4298bf80f4bSopenharmony_ci    }
4308bf80f4bSopenharmony_ci    if (dataHandle.Owner() && (dataHandle.Owner()->Type() == typeHash_)) {
4318bf80f4bSopenharmony_ci        return true;
4328bf80f4bSopenharmony_ci    }
4338bf80f4bSopenharmony_ci    return false;
4348bf80f4bSopenharmony_ci}
4358bf80f4bSopenharmony_ci
4368bf80f4bSopenharmony_ci// handle implementation
4378bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4388bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::BaseComponentHandle::BaseComponentHandle(
4398bf80f4bSopenharmony_ci    BaseManager* owner, CORE_NS::Entity entity) noexcept
4408bf80f4bSopenharmony_ci    : manager_(owner), entity_(entity)
4418bf80f4bSopenharmony_ci{}
4428bf80f4bSopenharmony_ci
4438bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4448bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::BaseComponentHandle::BaseComponentHandle(
4458bf80f4bSopenharmony_ci    BaseManager* owner, CORE_NS::Entity entity, const ComponentType& data) noexcept
4468bf80f4bSopenharmony_ci    : manager_(owner), entity_(entity), data_(data)
4478bf80f4bSopenharmony_ci{}
4488bf80f4bSopenharmony_ci
4498bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4508bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::BaseComponentHandle::BaseComponentHandle(BaseComponentHandle&& other) noexcept
4518bf80f4bSopenharmony_ci    : rLocked_(other.rLocked_.exchange(0U)), wLocked_(BASE_NS::exchange(other.wLocked_, false)),
4528bf80f4bSopenharmony_ci      manager_(other.manager_), generation_(BASE_NS::exchange(other.generation_, 0U)),
4538bf80f4bSopenharmony_ci      entity_(BASE_NS::exchange(other.entity_, {})), data_(BASE_NS::exchange(other.data_, {}))
4548bf80f4bSopenharmony_ci{
4558bf80f4bSopenharmony_ci    CORE_ASSERT((rLocked_ == 0U) && !wLocked_);
4568bf80f4bSopenharmony_ci}
4578bf80f4bSopenharmony_ci
4588bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4598bf80f4bSopenharmony_citypename BaseManager<ComponentType, BaseClass>::BaseComponentHandle&
4608bf80f4bSopenharmony_ciBaseManager<ComponentType, BaseClass>::BaseComponentHandle::operator=(BaseComponentHandle&& other) noexcept
4618bf80f4bSopenharmony_ci{
4628bf80f4bSopenharmony_ci    if (this != &other) {
4638bf80f4bSopenharmony_ci        CORE_ASSERT(manager_ == other.manager_);
4648bf80f4bSopenharmony_ci        CORE_ASSERT((other.rLocked_ == 0U) && !other.wLocked_);
4658bf80f4bSopenharmony_ci        rLocked_ = other.rLocked_.exchange(0U);
4668bf80f4bSopenharmony_ci        wLocked_ = BASE_NS::exchange(other.wLocked_, false);
4678bf80f4bSopenharmony_ci        generation_ = BASE_NS::exchange(other.generation_, 0U);
4688bf80f4bSopenharmony_ci        entity_ = BASE_NS::exchange(other.entity_, {});
4698bf80f4bSopenharmony_ci        data_ = BASE_NS::exchange(other.data_, {});
4708bf80f4bSopenharmony_ci    }
4718bf80f4bSopenharmony_ci    return *this;
4728bf80f4bSopenharmony_ci}
4738bf80f4bSopenharmony_ci
4748bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4758bf80f4bSopenharmony_ciconst IPropertyApi* BaseManager<ComponentType, BaseClass>::BaseComponentHandle::Owner() const
4768bf80f4bSopenharmony_ci{
4778bf80f4bSopenharmony_ci    return manager_;
4788bf80f4bSopenharmony_ci}
4798bf80f4bSopenharmony_ci
4808bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4818bf80f4bSopenharmony_cisize_t BaseManager<ComponentType, BaseClass>::BaseComponentHandle::Size() const
4828bf80f4bSopenharmony_ci{
4838bf80f4bSopenharmony_ci    return sizeof(ComponentType);
4848bf80f4bSopenharmony_ci}
4858bf80f4bSopenharmony_ci
4868bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4878bf80f4bSopenharmony_ciconst void* BaseManager<ComponentType, BaseClass>::BaseComponentHandle::RLock() const
4888bf80f4bSopenharmony_ci{
4898bf80f4bSopenharmony_ci    CORE_ASSERT(manager_);
4908bf80f4bSopenharmony_ci    CORE_ASSERT(!wLocked_);
4918bf80f4bSopenharmony_ci    ++rLocked_;
4928bf80f4bSopenharmony_ci    return &data_;
4938bf80f4bSopenharmony_ci}
4948bf80f4bSopenharmony_ci
4958bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
4968bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::BaseComponentHandle::RUnlock() const
4978bf80f4bSopenharmony_ci{
4988bf80f4bSopenharmony_ci    CORE_ASSERT(manager_);
4998bf80f4bSopenharmony_ci    CORE_ASSERT(rLocked_ > 0U);
5008bf80f4bSopenharmony_ci    --rLocked_;
5018bf80f4bSopenharmony_ci}
5028bf80f4bSopenharmony_ci
5038bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
5048bf80f4bSopenharmony_civoid* BaseManager<ComponentType, BaseClass>::BaseComponentHandle::WLock()
5058bf80f4bSopenharmony_ci{
5068bf80f4bSopenharmony_ci    CORE_ASSERT(manager_);
5078bf80f4bSopenharmony_ci    CORE_ASSERT(rLocked_ <= 1U && !wLocked_);
5088bf80f4bSopenharmony_ci    wLocked_ = true;
5098bf80f4bSopenharmony_ci    return &data_;
5108bf80f4bSopenharmony_ci}
5118bf80f4bSopenharmony_ci
5128bf80f4bSopenharmony_citemplate<typename ComponentType, typename BaseClass>
5138bf80f4bSopenharmony_civoid BaseManager<ComponentType, BaseClass>::BaseComponentHandle::WUnlock()
5148bf80f4bSopenharmony_ci{
5158bf80f4bSopenharmony_ci    CORE_ASSERT(manager_);
5168bf80f4bSopenharmony_ci    CORE_ASSERT(wLocked_);
5178bf80f4bSopenharmony_ci    wLocked_ = false;
5188bf80f4bSopenharmony_ci    // update generation etc..
5198bf80f4bSopenharmony_ci    ++generation_;
5208bf80f4bSopenharmony_ci    if (EntityUtil::IsValid(entity_)) {
5218bf80f4bSopenharmony_ci        dirty_ = true;
5228bf80f4bSopenharmony_ci        manager_->Updated(entity_);
5238bf80f4bSopenharmony_ci    }
5248bf80f4bSopenharmony_ci}
5258bf80f4bSopenharmony_ciCORE_END_NAMESPACE()
526