commit e83cf9b7cebd767951906318baaf3dfd865d6bf8
Author: codeboss <2422523675@qq.com>
Date: Thu Sep 11 18:36:49 2025 +0800
update
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c77d85e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+x64/
+.vs/
\ No newline at end of file
diff --git a/ECSMemoryPool.sln b/ECSMemoryPool.sln
new file mode 100644
index 0000000..b3fa658
--- /dev/null
+++ b/ECSMemoryPool.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35825.156 d17.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ECSMemoryPool", "ECSMemoryPool\ECSMemoryPool.vcxproj", "{666EC5D6-70A6-40DA-B92A-364116921A07}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {666EC5D6-70A6-40DA-B92A-364116921A07}.Debug|x64.ActiveCfg = Debug|x64
+ {666EC5D6-70A6-40DA-B92A-364116921A07}.Debug|x64.Build.0 = Debug|x64
+ {666EC5D6-70A6-40DA-B92A-364116921A07}.Release|x64.ActiveCfg = Release|x64
+ {666EC5D6-70A6-40DA-B92A-364116921A07}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A821C833-A8F8-4557-AAEC-84F9281C171F}
+ EndGlobalSection
+EndGlobal
diff --git a/ECSMemoryPool/ECSMemoryPool.vcxproj b/ECSMemoryPool/ECSMemoryPool.vcxproj
new file mode 100644
index 0000000..4c64a7c
--- /dev/null
+++ b/ECSMemoryPool/ECSMemoryPool.vcxproj
@@ -0,0 +1,114 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {666EC5D6-70A6-40DA-B92A-364116921A07}
+ QtVS_v304
+ 10.0
+ 10.0
+ $(MSBuildProjectDirectory)\QtMsBuild
+
+
+
+ DynamicLibrary
+ v143
+ true
+ Unicode
+
+
+ DynamicLibrary
+ v143
+ false
+ true
+ Unicode
+
+
+
+
+
+
+ 5.12.11_msvc2017_64
+ core
+ debug
+
+
+ 5.12.11_msvc2017_64
+ core
+ release
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stdcpp20
+
+
+
+
+ true
+ ECSMEMORYPOOL_LIB;%(PreprocessorDefinitions)
+ Level3
+ true
+ true
+
+
+ Windows
+ true
+
+
+
+
+ true
+ ECSMEMORYPOOL_LIB;%(PreprocessorDefinitions)
+ Level3
+ true
+ true
+ true
+ true
+
+
+ Windows
+ false
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ECSMemoryPool/ECSMemoryPool.vcxproj.filters b/ECSMemoryPool/ECSMemoryPool.vcxproj.filters
new file mode 100644
index 0000000..f97f06b
--- /dev/null
+++ b/ECSMemoryPool/ECSMemoryPool.vcxproj.filters
@@ -0,0 +1,44 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {99349809-55BA-4b9d-BF79-8FDBB0286EB3}
+ ui
+
+
+ {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}
+ ts
+
+
+
+
+ Header Files
+
+
+ Source Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/ECSMemoryPool/ECSMemoryPool.vcxproj.user b/ECSMemoryPool/ECSMemoryPool.vcxproj.user
new file mode 100644
index 0000000..41a709a
--- /dev/null
+++ b/ECSMemoryPool/ECSMemoryPool.vcxproj.user
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ECSMemoryPool/ecs_memorypool.cpp b/ECSMemoryPool/ecs_memorypool.cpp
new file mode 100644
index 0000000..be14c36
--- /dev/null
+++ b/ECSMemoryPool/ecs_memorypool.cpp
@@ -0,0 +1,5 @@
+#include "ecs_memorypool.h"
+
+ECSMemoryPool::ECSMemoryPool()
+{
+}
diff --git a/ECSMemoryPool/ecs_memorypool.h b/ECSMemoryPool/ecs_memorypool.h
new file mode 100644
index 0000000..d32181c
--- /dev/null
+++ b/ECSMemoryPool/ecs_memorypool.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "ecsmemorypool_global.h"
+#include
+#include
+#include
+#include
+
+template
+concept CompenentType = requires(T t, 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;
+};
+
+
+class ECSMEMORYPOOL_EXPORT ECSMemoryPool{
+private:
+ QList> _storage_pages;
+
+public:
+ ECSMemoryPool();
+
+ template void registerComponent() {
+
+ }
+};
diff --git a/ECSMemoryPool/ecsmemorypool_global.h b/ECSMemoryPool/ecsmemorypool_global.h
new file mode 100644
index 0000000..5615e5a
--- /dev/null
+++ b/ECSMemoryPool/ecsmemorypool_global.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include
+
+#ifndef BUILD_STATIC
+# if defined(ECSMEMORYPOOL_LIB)
+# define ECSMEMORYPOOL_EXPORT Q_DECL_EXPORT
+# else
+# define ECSMEMORYPOOL_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define ECSMEMORYPOOL_EXPORT
+#endif
diff --git a/ECSMemoryPool/memory_pages.cpp b/ECSMemoryPool/memory_pages.cpp
new file mode 100644
index 0000000..dcff6d5
--- /dev/null
+++ b/ECSMemoryPool/memory_pages.cpp
@@ -0,0 +1,130 @@
+#include "memory_pages.h"
+
+MemoryPage::MemoryPage(uint16_t element_size, uint64_t typecode)
+{
+ pcb.byte_count_per_element = element_size;
+ pcb.total_buffer_size = sizeof(data_buffer);
+ pcb.typecode_of_element = typecode;
+}
+
+void MemoryPage::accessRecord(uint64_t timepoint_usec) {
+ std::lock_guard g(pcb.access_protected);
+ pcb.curr_access_usec = timepoint_usec;
+ pcb.acc_count_per_cycle++;
+}
+
+uint32_t MemoryPage::timesClear() {
+ std::lock_guard g(pcb.access_protected);
+ auto value = pcb.acc_count_per_cycle;
+ pcb.acc_count_per_cycle = 0;
+ return value;
+}
+
+std::pair MemoryPage::getRecords() const {
+ auto data_ptr = const_cast(this);
+ std::lock_guard g(data_ptr->pcb.access_protected);
+ return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle);
+}
+
+char* MemoryPage::getElementPtr(int index) {
+ auto member_cnt = elementCount();
+ auto element_size = elementSize();
+
+ char* element_ptr = nullptr;
+ if (index >= 0 && index < member_cnt) {
+ element_ptr = data_buffer + index * element_size;
+ }
+ else if (index < 0 && index >= -member_cnt) {
+ element_ptr = data_buffer + (member_cnt + index) * element_size;
+ }
+
+ lock();
+ if (element_ptr) {
+ auto data_ptr = (ElementControlBlock*)element_ptr;
+ data_ptr->page_refer = this;
+ data_ptr->element_index = index;
+ }
+ release();
+ return element_ptr;
+}
+
+void MemoryPage::lock()
+{
+ pcb.access_protected.lock();
+}
+
+void MemoryPage::release() {
+#pragma warning(push)
+#pragma warning(disable : 26110)
+ pcb.access_protected.unlock();
+#pragma warning(pop)
+}
+
+uint64_t MemoryPage::elementTypeCode() const
+{
+ auto data_ptr = const_cast(this);
+ std::lock_guard g(data_ptr->pcb.access_protected);
+ return pcb.typecode_of_element;
+}
+
+uint16_t MemoryPage::elementSize() const {
+ auto data_ptr = const_cast(this);
+ std::lock_guard g(data_ptr->pcb.access_protected);
+ return pcb.byte_count_per_element;
+}
+
+uint16_t MemoryPage::elementCount() const {
+ uint16_t cnt = sizeof(data_buffer);
+ return cnt / this->elementSize();
+}
+
+uint32_t MemoryElement::validOffset()
+{
+ uint32_t remains = sizeof(ElementControlBlock) % 8;
+ uint32_t times = sizeof(ElementControlBlock) / 8;
+ return (remains ? times + 1 : times) * 8;
+}
+
+uint32_t MemoryElement::rawSize(uint32_t data_type_size)
+{
+ uint32_t minimal_size = validOffset() + data_type_size;
+ auto remains = minimal_size % 16;
+ auto times = minimal_size / 16;
+ return (remains ? times + 1 : times) * 16;
+}
+
+MemoryElement::MemoryElement(char* access_bind)
+ : data_ptr((ElementControlBlock*)access_bind) {
+ buffer_offset = validOffset();
+}
+
+void MemoryElement::accessRecUpdate(uint64_t time_usec)
+{
+ data_ptr->page_refer->accessRecord(time_usec);
+}
+
+uint8_t MemoryElement::isActived() const
+{
+ data_ptr->page_refer->lock();
+ auto mark = data_ptr->active_mark;
+ data_ptr->page_refer->release();
+ return mark;
+}
+
+void MemoryElement::setActive(uint8_t ste)
+{
+ data_ptr->page_refer->lock();
+ data_ptr->active_mark = ste;
+ data_ptr->page_refer->release();
+}
+
+char* MemoryElement::dataLock()
+{
+ data_ptr->page_refer->lock();
+ return ((char*)data_ptr) + buffer_offset;
+}
+
+void MemoryElement::release()
+{
+ data_ptr->page_refer->release();
+}
diff --git a/ECSMemoryPool/memory_pages.h b/ECSMemoryPool/memory_pages.h
new file mode 100644
index 0000000..5868268
--- /dev/null
+++ b/ECSMemoryPool/memory_pages.h
@@ -0,0 +1,145 @@
+#pragma once
+#include
+
+class MemoryPage;
+
+///
+/// ÄÚ´æÒ³·ÃÎÊ¿ØÖÆ¿é
+///
+struct PageControlBlock {
+ uint16_t active_entities_count = 0; // »îÔ¾elementÊýÁ¿£¬¾ö¶¨ÊÇ·ñÐèÒªÐ¶ÔØ
+
+ uint16_t byte_count_per_element = 32; // µ¥¸öelement´óС£¬16µÄ±¶Êý
+ uint32_t total_buffer_size = 0; // ¿ÉÓÃÊý¾Ý»º³åÇø´óС
+ uint64_t typecode_of_element = 0; // ÔªËØÀàÐͱêʶÂë
+
+ uint64_t curr_access_usec = 0; // ×î½ü·ÃÎÊʱ¼äµã£¬lsb£ºus
+ uint32_t acc_count_per_cycle = 0; // µ¥ÖÜÆÚÄÚÀÛ»ý·ÃÎÊ´ÎÊý
+ uint32_t un_used = 0;
+
+ std::mutex access_protected; // ÄÚ´æÊý¾Ý·ÃÎʱ£»¤Ëø
+};
+///
+/// ÄÚ´æÒ³Ãæ16K´óС
+///
+class MemoryPage {
+private:
+ PageControlBlock pcb;
+ char data_buffer[16 * 1024 - (sizeof(PageControlBlock) / 8 + 1) * 8] = {};
+
+public:
+ ///
+ /// ¹¹½¨ÄÚ´æÒ³
+ ///
+ /// Ôʼelement³ß´ç
+ explicit MemoryPage(uint16_t raw_element_size_16B, uint64_t typecode);
+
+ ///
+ /// ¼Ç¼µ¥´Î·ÃÎÊʱ¼ä
+ ///
+ ///
+ void accessRecord(uint64_t timepoint_usec);
+ ///
+ /// Çå³ý·ÃÎÊ´ÎÊý¼Ç¼
+ ///
+ /// ÉÏÒ»ÖÜÆÚÀÛ»ý´ÎÊý
+ uint32_t timesClear();
+ ///
+ /// »ñÈ¡·ÃÎʼǼ
+ ///
+ /// {×î½ü·ÃÎÊʱ¼ä,ÀÛ»ý´ÎÊý}
+ std::pair getRecords() const;
+
+ ///
+ /// ¼ÓËø£¬ÔÚrelease֮ǰ²»ÄÜ·ÃÎʱ¾ÀàÐÍÈκνӿڣ¬·ñÔò»áÔì³ÉËÀËø
+ ///
+ void lock();
+ ///
+ /// ½âËø
+ ///
+ void release();
+
+ ///
+ /// »ñÈ¡elementÔªËØÊý¾Ý·ÃÎÊÖ¸Õë
+ ///
+ /// ÔªËØË÷Òý
+ /// ÊÇ·ñÉèÖÃ
+ /// Êý¾ÝÖ¸Õë
+ char* getElementPtr(int index);
+ ///
+ /// ÔªËØÀàÐÍÂë
+ ///
+ ///
+ uint64_t elementTypeCode() const;
+ ///
+ /// »ñÈ¡µ¥¸öÔªËØ³ß´ç
+ ///
+ /// ×Ö½ÚÊýÁ¿
+ uint16_t elementSize() const;
+ ///
+ /// »ñÈ¡ÔªËØÊýÁ¿
+ ///
+ ///
+ uint16_t elementCount() const;
+};
+
+
+///
+/// ÔªËØ·ÃÎÊ¿ØÖÆ¿é
+///
+struct ElementControlBlock {
+ uint8_t active_mark = 0; // »îÔ¾±êÖ¾
+ uint8_t backup_1 = 0;
+ uint16_t byte_count = 16; // ¸ÃÔªËØ×Ö½Ú³¤¶È£¬16µÄ±¶Êý
+ uint16_t element_index = 0; // ±¾ÔªËØÔÚPageÖеÄË÷Òý
+ uint16_t backup_2 = 0;
+ MemoryPage* page_refer = nullptr; // Ò³Ãæ¹ØÁªÖ¸Õë
+ void* extend_bind = nullptr; // °ó¶¨¿ØÖÆ¿éÄÚ´æÖ¸Õë
+};
+
+
+///
+/// ÄÚ´æÔªËØ·ÃÎʽӿÚ
+///
+class MemoryElement {
+private:
+ ElementControlBlock* const data_ptr;
+ uint32_t buffer_offset = 0;
+
+public:
+ static uint32_t validOffset();
+ static uint32_t rawSize(uint32_t data_type_size);
+
+ ///
+ /// ¹¹½¨ÄÚ´æÔªËØ·ÃÎʽӿÚ
+ ///
+ ///
+ MemoryElement(char* access_bind);
+
+ ///
+ /// ¸üÐÂ×îÖÕ·ÃÎÊʱ¼ä
+ ///
+ ///
+ void accessRecUpdate(uint64_t time_usec);
+
+ ///
+ /// Êý¾Ý»îԾ״̬
+ ///
+ ///
+ uint8_t isActived() const;
+ ///
+ /// ÉèÖÃÊý¾Ý»îԾ״̬
+ ///
+ ///
+ void setActive(uint8_t ste);
+
+ ///
+ /// Ëø¶¨Êý¾Ý£¬·µ»ØÊý¾Ý´æ´¢ÄÚ´æÖ¸Õë
+ ///
+ ///
+ char* dataLock();
+ ///
+ /// ½âËøÊý¾Ý
+ ///
+ void release();
+};
\ No newline at end of file