2025-09-11 10:36:49 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include "ecsmemorypool_global.h"
|
|
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
|
#include <QList>
|
|
|
|
|
|
#include <QHash>
|
|
|
|
|
|
#include <memory_pages.h>
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2025-09-11 14:01:42 +00:00
|
|
|
|
concept CompenentType = requires(T t, T other, const QJsonObject & in, QJsonObject & out) {
|
|
|
|
|
|
{ T::typeCode() } -> std::same_as<uint64_t>;
|
|
|
|
|
|
{ T::typeSize() } -> std::same_as<uint16_t>;
|
2025-09-11 10:36:49 +00:00
|
|
|
|
{ t.loadFrom(in) } -> std::same_as<void>;
|
|
|
|
|
|
{ t.saveTo(out) } -> std::same_as<void>;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-11 14:01:42 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
template<typename T> class ComponentRefer : protected MemoryElement {
|
|
|
|
|
|
public:
|
|
|
|
|
|
ComponentRefer(ElementControlBlock* data) : MemoryElement(data) { referAdd(); }
|
2025-09-11 22:36:56 +00:00
|
|
|
|
ComponentRefer(const ComponentRefer<T> &other) :MemoryElement(other.data_ptr) { referAdd(); }
|
2025-09-11 14:01:42 +00:00
|
|
|
|
virtual ~ComponentRefer() { referSub(); }
|
|
|
|
|
|
|
|
|
|
|
|
T* dataLock() {
|
|
|
|
|
|
return (T*)(MemoryElement::dataLock());
|
|
|
|
|
|
}
|
|
|
|
|
|
void unlock() {
|
|
|
|
|
|
MemoryElement::release();
|
|
|
|
|
|
}
|
2025-09-11 22:36:56 +00:00
|
|
|
|
|
2025-09-11 14:01:42 +00:00
|
|
|
|
};
|
2025-09-11 10:36:49 +00:00
|
|
|
|
|
2025-09-11 14:01:42 +00:00
|
|
|
|
|
|
|
|
|
|
class ECSMEMORYPOOL_EXPORT ECSMemoryPool {
|
2025-09-11 10:36:49 +00:00
|
|
|
|
private:
|
2025-09-11 14:01:42 +00:00
|
|
|
|
std::mutex _pool_protected_;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Я<><D0AF>Ĭ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ʵ<EFBFBD><CAB5>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
QHash<uint64_t, std::pair<uint16_t, void*>> _basic_component_memory_example;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// map<type_code<64><65>page_ptr> <20>ڴ<EFBFBD>ҳ<EFBFBD>洢
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
QMultiHash<uint64_t, MemoryPage*> _storage_pages;
|
2025-09-11 10:36:49 +00:00
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
ECSMemoryPool();
|
|
|
|
|
|
|
2025-09-11 14:01:42 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// ע<><D7A2>Я<EFBFBD><D0AF>Ĭ<EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
/// <param name="one"></param>
|
2025-09-11 22:36:56 +00:00
|
|
|
|
template<CompenentType T> void registerComponent(const T &one) {
|
2025-09-11 14:01:42 +00:00
|
|
|
|
std::lock_guard<std::mutex> lockx(_pool_protected_);
|
|
|
|
|
|
|
|
|
|
|
|
auto ptr = new char[T::typeSize()];
|
|
|
|
|
|
memcpy(ptr, &one, T::typeSize());
|
|
|
|
|
|
|
|
|
|
|
|
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
auto type_code = T::typeCode();
|
|
|
|
|
|
auto type_size = T::typeSize();
|
2025-09-11 22:36:56 +00:00
|
|
|
|
_basic_component_memory_example[type_code] = std::make_pair(type_size, (void*)ptr);
|
2025-09-11 14:01:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
template<CompenentType T> ComponentRefer<T> generate() {
|
|
|
|
|
|
std::lock_guard<std::mutex> lockx(_pool_protected_);
|
|
|
|
|
|
|
|
|
|
|
|
auto type_code = T::typeCode();
|
|
|
|
|
|
ElementControlBlock* refer_ptr = nullptr;
|
|
|
|
|
|
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ҳ
|
|
|
|
|
|
QList<MemoryPage*> page_list = _storage_pages.values(type_code);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD>
|
|
|
|
|
|
for (auto page_ptr : page_list) {
|
|
|
|
|
|
auto max_element_cnt = page_ptr->maxSliceCount();
|
|
|
|
|
|
auto active_cnt = page_ptr->getActiveCount();
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>У<EFBFBD>˿<EFBFBD><CBBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (active_cnt < max_element_cnt) {
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
|
|
|
|
|
|
for (auto eidx = 0; eidx < max_element_cnt; eidx++) {
|
|
|
|
|
|
auto slice_ptr = page_ptr->getSlicePtr(eidx);
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
slice_ptr->page_refer->lock();
|
|
|
|
|
|
// <20>þ<EFBFBD>Ԫ<EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (!slice_ptr->refer_count) {
|
2025-09-11 22:36:56 +00:00
|
|
|
|
// Ԫ<>ؿ<EFBFBD><D8BF>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC>
|
2025-09-11 14:01:42 +00:00
|
|
|
|
slice_ptr->refer_count++;
|
|
|
|
|
|
refer_ptr = slice_ptr;
|
|
|
|
|
|
slice_ptr->page_refer->release();
|
2025-09-11 22:36:56 +00:00
|
|
|
|
refer_ptr->page_refer->getActiveCount(1);
|
2025-09-11 14:01:42 +00:00
|
|
|
|
// <20><>ת<EFBFBD><D7AA>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
goto exists_reuse;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
slice_ptr->page_refer->release();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-11 22:36:56 +00:00
|
|
|
|
{
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5>ڴ<EFBFBD>ҳ
|
|
|
|
|
|
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++;
|
|
|
|
|
|
}
|
2025-09-11 10:36:49 +00:00
|
|
|
|
|
2025-09-11 14:01:42 +00:00
|
|
|
|
exists_reuse:
|
2025-09-11 22:36:56 +00:00
|
|
|
|
ComponentRefer<T> 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;
|
2025-09-11 14:01:42 +00:00
|
|
|
|
}
|
2025-09-11 10:36:49 +00:00
|
|
|
|
};
|