From ca8070ef71b8f047b91174d318f626887a342569 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 2 Nov 2021 19:42:00 +0100 Subject: [PATCH] Map changes --- .vscode/c_cpp_properties.json | 20 ++++ .vscode/launch.json | 11 ++ .vscode/settings.json | 9 +- CMakeLists.txt | 2 + compile_commands.json | 1 + src/Engine/Containers/Array.h | 2 +- src/Engine/Containers/Map.h | 46 +++++--- src/Engine/Graphics/Vulkan/VulkanBuffer.cpp | 3 +- src/Engine/MinimalEngine.h | 47 +++++---- test/Engine/Containers/Array.cpp | 1 - test/Engine/Containers/Map.cpp | 110 +++++++++++--------- test/Engine/EngineTest.cpp | 13 +++ 12 files changed, 168 insertions(+), 97 deletions(-) create mode 120000 compile_commands.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 5cffc62..dbec570 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -19,6 +19,26 @@ ] }, "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe" + }, + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/src/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools", + "cppStandard": "c++20", + "browse": { + "path": [ + "external/**" + ] + }, + "compilerPath": "/usr/bin/g++" } ], "version": 4 diff --git a/.vscode/launch.json b/.vscode/launch.json index fd0efbb..cba0aba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -62,6 +62,17 @@ "traceResponse": true } }, + { + "name": "Test (Linux)", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceRoot}/bin/Debug/Seele_unit_tests", + "args": [], + "stopAtEntry": false, + "console": "internalConsole", + "cwd": "${workspaceRoot}/bin/Debug", + "environment": [], + }, { "name": "Test", "type": "cppvsdbg", diff --git a/.vscode/settings.json b/.vscode/settings.json index 63892bb..86c9ad4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -124,15 +124,10 @@ "-Wno-dev" ], "C_Cpp.default.cppStandard": "c++20", - "C_Cpp.default.intelliSenseMode": "msvc-x64", - "C_Cpp.files.exclude": { - "**/.vscode": true, - "external/**": true - }, "files.watcherExclude": { "**/target": true }, - "C_Cpp.errorSquiggles": "Disabled", "git.ignoreSubmodules": true, - "cmake.configureOnOpen": true + "cmake.configureOnOpen": true, + "C_Cpp.intelliSenseEngineFallback": "Enabled" } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0618813..e6c62ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ set(CMAKE_CXX_STANDARD 20) # Handle superbuild first option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine) set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external) set(ASSIMP_ROOT ${EXTERNAL_ROOT}/assimp) diff --git a/compile_commands.json b/compile_commands.json new file mode 120000 index 0000000..f2b5938 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1 @@ +bin/Debug/compile_commands.json \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index d23c113..2c844dc 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -401,7 +401,7 @@ namespace Seele } void pop() { - arraySize--; + _data[arraySize--].~T(); markIteratorDirty(); } constexpr inline reference operator[](size_type index) diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index c7808f1..14c24b8 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -189,7 +189,7 @@ public: : root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(Compare()) { @@ -200,7 +200,7 @@ public: , root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(comp) { @@ -210,7 +210,7 @@ public: , root(nullptr) , beginIt(nullptr) , endIt(nullptr) - , iteratorsDirty(false) + , iteratorsDirty(true) , _size(0) , comp(Compare()) { @@ -221,7 +221,7 @@ public: , comp(other.comp) { root = &nodeContainer[nodeContainer.indexOf(other.root)]; - refreshIterators(); + markIteratorDirty(); } Map(Map&& other) : nodeContainer(other.nodeContainer) @@ -229,7 +229,7 @@ public: , comp(std::move(other.comp)) { root = &nodeContainer[nodeContainer.indexOf(other.root)]; - refreshIterators(); + markIteratorDirty(); } ~Map() { @@ -242,7 +242,7 @@ public: root = &nodeContainer[nodeContainer.indexOf(other.root)]; _size = other._size; comp = other.comp; - refreshIterators(); + markIteratorDirty(); } return *this; } @@ -254,14 +254,14 @@ public: root = &nodeContainer[nodeContainer.indexOf(other.root)]; _size = std::move(other._size); comp = std::move(other.comp); - refreshIterators(); + markIteratorDirty(); } return *this; } inline mapped_type& operator[](const key_type& key) { root = splay(root, key); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { root = insert(root, key); @@ -272,7 +272,7 @@ public: inline mapped_type& operator[](key_type&& key) { root = splay(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { root = insert(root, std::move(key)); @@ -283,7 +283,7 @@ public: iterator find(const key_type& key) { root = splay(root, key); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -293,7 +293,7 @@ public: iterator find(key_type&& key) { root = splay(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); if (root == nullptr || comp(root->pair.key, key) || comp(key, root->pair.key)) { return endIt; @@ -303,13 +303,13 @@ public: iterator erase(const key_type& key) { root = remove(root, key); - refreshIterators(); + markIteratorDirty(); return iterator(root); } iterator erase(K&& key) { root = remove(root, std::move(key)); - refreshIterators(); + markIteratorDirty(); return iterator(root); } void clear() @@ -317,7 +317,7 @@ public: nodeContainer.clear(); root = nullptr; _size = 0; - refreshIterators(); + markIteratorDirty(); } bool exists(key_type&& key) { @@ -486,10 +486,22 @@ private: r = splay(r->leftChild, key); r->rightChild = temp->rightChild; } - temp->leftChild = nullptr; - temp->rightChild = nullptr; + Node& lastNode = nodeContainer.back(); + size_t removedIndex = nodeContainer.indexOf(temp); + nodeContainer[removedIndex] = std::move(lastNode); + for(auto it : nodeContainer) + { + if(it.leftChild == &lastNode) + { + it.leftChild = &nodeContainer[removedIndex]; + } + if(it.rightChild == &lastNode) + { + it.rightChild = &nodeContainer[removedIndex]; + } + } + nodeContainer.pop(); _size--; - delete temp; return r; } template diff --git a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp index 614666f..f80bf5d 100644 --- a/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanBuffer.cpp @@ -54,7 +54,8 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer); bufferReqInfo.buffer = buffers[i].buffer; vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements); - buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); + auto temp = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer); + buffers[i].allocation = temp; vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset()); } } diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index dbc81a4..e1fd69c 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -29,14 +29,16 @@ extern Seele::Map registeredObjects; extern std::mutex registeredObjectsLock; namespace Seele { -template +template class RefPtr; -template +template class RefObject { public: - RefObject(T *ptr) - : handle(ptr), refCount(1) + RefObject(T *ptr, Deleter&& deleter) + : handle(ptr) + , deleter(std::move(deleter)) + , refCount(1) { registeredObjects[ptr] = this; } @@ -55,7 +57,7 @@ public: registeredObjects.erase(handle); } // #pragma warning( disable: 4150) - delete handle; + //deleter(handle); // #pragma warning( default: 4150) } RefObject &operator=(const RefObject &rhs) @@ -108,11 +110,12 @@ public: } private: T *handle; + Deleter deleter; std::atomic_uint64_t refCount; - friend class RefPtr; + friend class RefPtr; }; -template +template > class RefPtr { public: @@ -124,7 +127,7 @@ public: { object = nullptr; } - RefPtr(T *ptr) + RefPtr(T *ptr, Deleter deleter = Deleter()) { std::unique_lock l(registeredObjectsLock); auto registeredObj = registeredObjects.find(ptr); @@ -132,17 +135,17 @@ public: auto registeredEnd = registeredObjects.end(); if (registeredObj == registeredEnd) { - object = new RefObject(ptr); + object = new RefObject(ptr, std::move(deleter)); l.unlock(); } else { l.unlock(); - object = (RefObject *)registeredObj->value; + object = (RefObject *)registeredObj->value; object->addRef(); } } - explicit RefPtr(RefObject *other) + explicit RefPtr(RefObject *other) : object(other) { object->addRef(); @@ -166,12 +169,12 @@ public: { F *f = other.getObject()->getHandle(); assert(static_cast(f)); - object = (RefObject *)other.getObject(); + object = (RefObject *)other.getObject(); object->addRef(); } - template - RefPtr cast() + template > + RefPtr cast() { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -179,12 +182,12 @@ public: { return nullptr; } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); } - template - const RefPtr cast() const + template > + const RefPtr cast() const { T *t = object->getHandle(); F *f = dynamic_cast(t); @@ -192,8 +195,8 @@ public: { return nullptr; } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); } RefPtr &operator=(const RefPtr &other) @@ -254,7 +257,7 @@ public: assert(object != nullptr); return object->handle; } - RefObject *getObject() const + RefObject *getObject() const { return object; } @@ -268,7 +271,7 @@ public: } private: - RefObject *object; + RefObject *object; friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int) diff --git a/test/Engine/Containers/Array.cpp b/test/Engine/Containers/Array.cpp index 8def8d1..00c13ec 100644 --- a/test/Engine/Containers/Array.cpp +++ b/test/Engine/Containers/Array.cpp @@ -3,7 +3,6 @@ #include "MinimalEngine.h" #include #include -#define BOOST_TEST_MODULE SeeleEngine #include using namespace Seele; diff --git a/test/Engine/Containers/Map.cpp b/test/Engine/Containers/Map.cpp index 2ea2c79..894f26e 100644 --- a/test/Engine/Containers/Map.cpp +++ b/test/Engine/Containers/Map.cpp @@ -8,71 +8,85 @@ BOOST_AUTO_TEST_SUITE(CachedMap) BOOST_AUTO_TEST_CASE(insert_find_basic) { - Map map; - map[2] = 3; - map[1] = 5; - map[6] = 4; - map[4] = 7; - BOOST_REQUIRE_EQUAL(map[2], 3); - BOOST_REQUIRE_EQUAL(map[1], 5); - BOOST_REQUIRE_EQUAL(map[6], 4); - BOOST_REQUIRE_EQUAL(map[4], 7); - map[2] = 5; - map[4] = 4; - BOOST_REQUIRE_EQUAL(map[2], 5); - BOOST_REQUIRE_EQUAL(map[4], 4); + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + BOOST_REQUIRE_EQUAL(map[2], 3); + BOOST_REQUIRE_EQUAL(map[1], 5); + BOOST_REQUIRE_EQUAL(map[6], 4); + BOOST_REQUIRE_EQUAL(map[4], 7); + map[2] = 5; + map[4] = 4; + BOOST_REQUIRE_EQUAL(map[2], 5); + BOOST_REQUIRE_EQUAL(map[4], 4); } BOOST_AUTO_TEST_CASE(for_each) { - Map map; - map[2] = 3; - map[1] = 5; - map[6] = 4; - map[4] = 7; - int count = 0; - for(auto it : map) - { - count++; - } - BOOST_REQUIRE_EQUAL(count, 4); + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + int count = 0; + for(auto it : map) + { + count++; + } + BOOST_REQUIRE_EQUAL(count, 4); +} + +BOOST_AUTO_TEST_CASE(remove_entry) +{ + Map map; + map[1] = 5; + map[4] = 1; + map[2] = 6; + map[3] = 4; + map.erase(2); + BOOST_REQUIRE_EQUAL(map.size(), 3); + BOOST_REQUIRE_EQUAL(map[1], 5); + BOOST_REQUIRE_EQUAL(map[4], 1); + BOOST_REQUIRE_EQUAL(map[3], 4); } BOOST_AUTO_TEST_CASE(key_exists) { - Map map; - map[2] = 3; - BOOST_REQUIRE_EQUAL(map.exists(2), true); - BOOST_REQUIRE_EQUAL(map.exists(4), false); - map.erase(2); - BOOST_REQUIRE_EQUAL(map.exists(2), false); + Map map; + map[2] = 3; + BOOST_REQUIRE_EQUAL(map.exists(2), true); + BOOST_REQUIRE_EQUAL(map.exists(4), false); + map.erase(2); + BOOST_REQUIRE_EQUAL(map.exists(2), false); } BOOST_AUTO_TEST_CASE(custom_key) { - struct Key - { - int id; - bool operator<(const Key& other) const - { - return id < other.id; - } - }; - Map map; - map[Key{ 2 }] = 3; - map[Key{ 3 }] = 4; - BOOST_REQUIRE_EQUAL(map[Key{ 2 }], 3); - BOOST_REQUIRE_EQUAL(map[Key{ 3 }], 4); + struct Key + { + int id; + bool operator<(const Key& other) const + { + return id < other.id; + } + }; + Map map; + map[Key{ 2 }] = 3; + map[Key{ 3 }] = 4; + BOOST_REQUIRE_EQUAL(map[Key{ 2 }], 3); + BOOST_REQUIRE_EQUAL(map[Key{ 3 }], 4); } BOOST_AUTO_TEST_CASE(string_key) { - std::map map; - map["Test"] = 2; - map["Test2"] = 3; - BOOST_REQUIRE_EQUAL(map["Test"], 2); - BOOST_REQUIRE_EQUAL(map["Test2"], 3); + std::map map; + map["Test"] = 2; + map["Test2"] = 3; + BOOST_REQUIRE_EQUAL(map["Test"], 2); + BOOST_REQUIRE_EQUAL(map["Test2"], 3); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/Engine/EngineTest.cpp b/test/Engine/EngineTest.cpp index fefd4c6..ffc0742 100644 --- a/test/Engine/EngineTest.cpp +++ b/test/Engine/EngineTest.cpp @@ -1,5 +1,7 @@ #include "EngineTest.h" #include "MinimalEngine.h" +#define BOOST_TEST_MODULE SeeleEngine +#define BOOST_TEST_DYN_LINK #include using namespace Seele; @@ -18,6 +20,8 @@ struct TestStruct } uint32 data; }; + +struct DeclStruct; BOOST_AUTO_TEST_CASE(basic_refcount) { { @@ -30,7 +34,16 @@ BOOST_AUTO_TEST_CASE(basic_refcount) } BOOST_REQUIRE_EQUAL(ptr->data, 10); } + std::shared_ptr test; } +struct DeclStruct +{ + ~DeclStruct() + { + data = 10; + } + uint32 data = 20; +}; struct DerivedStruct : public TestStruct {