#pragma once #include "ecsmemorypool_global.h" #include #include #include #include template concept CompenentType = requires(T t, T other, const QJsonObject & in, QJsonObject & out) { { T::typeCode() } -> std::same_as; { T::typeSize() } -> std::same_as; { t.loadFrom(in) } -> std::same_as; { t.saveTo(out) } -> std::same_as; }; /// /// 组件引用符号 /// /// template class ComponentRefer : protected MemoryElement { public: ComponentRefer(ElementControlBlock* data) : MemoryElement(data) { referAdd(); } ComponentRefer(const ComponentRefer &other) :MemoryElement(other.data_ptr) { referAdd(); } virtual ~ComponentRefer() { referSub(); } T* dataLock() { return (T*)(MemoryElement::dataLock()); } void unlock() { MemoryElement::release(); } }; class ECSMEMORYPOOL_EXPORT ECSMemoryPool { private: std::mutex _pool_protected_; /// /// 携带默认参数数据元素组件内存实例 /// QHash> _basic_component_memory_example; /// /// map 内存页存储 /// QMultiHash _storage_pages; public: ECSMemoryPool(); /// /// 注册携带默认参数的数据组件 /// /// /// template void registerComponent(const T &one) { std::lock_guard lockx(_pool_protected_); auto ptr = new char[T::typeSize()]; memcpy(ptr, &one, T::typeSize()); // 注册组件数据类型 auto type_code = T::typeCode(); auto type_size = T::typeSize(); _basic_component_memory_example[type_code] = std::make_pair(type_size, (void*)ptr); } /// /// 创建一个新的数据组件 /// /// /// template ComponentRefer generate() { std::lock_guard lockx(_pool_protected_); auto type_code = T::typeCode(); ElementControlBlock* refer_ptr = nullptr; // 获取指定类型关联的内存页 QList page_list = _storage_pages.values(type_code); // 迭代内存页集合 for (auto page_ptr : page_list) { auto max_element_cnt = page_ptr->maxSliceCount(); auto active_cnt = page_ptr->getActiveCount(); // 初级校核可用数量 if (active_cnt < max_element_cnt) { // 逐个查找数据元素 for (auto eidx = 0; eidx < max_element_cnt; eidx++) { auto slice_ptr = page_ptr->getSlicePtr(eidx); // 访问排他 slice_ptr->page_refer->lock(); // 裁决元素可用性 if (!slice_ptr->refer_count) { // 元素可用,引用占用 slice_ptr->refer_count++; refer_ptr = slice_ptr; slice_ptr->page_refer->release(); refer_ptr->page_refer->getActiveCount(1); // 跳转到元素重用 goto exists_reuse; } else { slice_ptr->page_refer->release(); } } } } { // 生成新的内存页 auto new_page = new MemoryPage(MemoryElement::rawSize(T::typeSize()), type_code); _storage_pages.insert(type_code, new_page); refer_ptr = new_page->getSlicePtr(0); refer_ptr->page_refer->getActiveCount(1); refer_ptr->refer_count++; } exists_reuse: ComponentRefer temp_inst(refer_ptr); auto data_pointer = temp_inst.dataLock(); refer_ptr->refer_count--; auto dpair = _basic_component_memory_example[T::typeCode()]; memcpy(data_pointer, dpair.second, dpair.first); temp_inst.unlock(); return temp_inst; } };