#pragma once #include "ecsmemorypool_global.h" #include #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 ChunkRefer : protected MemoryChunk { public: ChunkRefer(ChunkControlBlock* data) : MemoryChunk(data) { referAdd(); } ChunkRefer(const ChunkRefer &other) :MemoryChunk(other.data_ptr) { referAdd(); } virtual ~ChunkRefer() { referSub(); } T* dataLock() { return (T*)(MemoryChunk::dataLock()); } void unlock() { MemoryChunk::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 ChunkRefer generate() { std::lock_guard lockx(_pool_protected_); auto type_code = T::typeCode(); ChunkControlBlock* refer_ptr = nullptr; // 获取指定类型关联的内存页 QList page_list = _storage_pages.values(type_code); // 迭代内存页集合 for (auto page_ptr : page_list) { auto max_chunk_cnt = page_ptr->maxCapacity(); auto active_cnt = page_ptr->getActiveCount(); // 初级校核可用数量 if (active_cnt < max_chunk_cnt) { // 逐个查找数据元素 for (auto eidx = 0; eidx < max_chunk_cnt; eidx++) { auto slice_ptr = page_ptr->getChunkPtr(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(MemoryChunk::rawSize(T::typeSize()), type_code); _storage_pages.insert(type_code, new_page); refer_ptr = new_page->getChunkPtr(0); refer_ptr->page_refer->getActiveCount(1); refer_ptr->refer_count++; } exists_reuse: ChunkRefer 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; } };