diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang index 7cf3122..825d6b5 100644 --- a/res/shaders/MeshletBasePass.slang +++ b/res/shaders/MeshletBasePass.slang @@ -51,7 +51,7 @@ void taskMain( { uint m = mesh.meshletOffset + i; MeshletDescription meshlet = pScene.meshletInfos[m]; - if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) + //if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) { uint index; InterlockedAdd(head, 1, index); diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index c599217..847c428 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -20,8 +20,8 @@ struct MeshData uint32_t pad0[3]; }; -static const uint MAX_VERTICES = 256; -static const uint MAX_PRIMITIVES = 256; +static const uint MAX_VERTICES = 64; +static const uint MAX_PRIMITIVES = 126; static const uint TASK_GROUP_SIZE = 128; static const uint MESH_GROUP_SIZE = 32; static const uint MAX_MESHLETS_PER_MESH = 512; diff --git a/src/Engine/Component/Component.h b/src/Engine/Component/Component.h index 2e0fff2..8383928 100644 --- a/src/Engine/Component/Component.h +++ b/src/Engine/Component/Component.h @@ -10,6 +10,11 @@ template<> struct Dependencies<> { int x; + template + Dependencies operator|(const Dependencies& other) + { + return Dependencies(); + } }; template struct Dependencies : public Dependencies @@ -24,25 +29,31 @@ struct Dependencies : public Dependencies namespace Component { -template -static int accessComponent(Comp& comp); + template + Comp& getComponent(); } + template concept has_dependencies = requires(Comp) { Comp::dependencies; }; #define REQUIRE_COMPONENT(x) \ private: \ - x& get##x() { return *tl_##x; } \ - const x& get##x() const { return *tl_##x; }; \ + x& get##x() { return getComponent<##x>(); } \ + const x& get##x() const { return getComponent<##x>(); } \ public: \ constexpr static Dependencies dependencies = {}; #define DECLARE_COMPONENT(x) \ - thread_local extern x* tl_##x; \ + void accessComponent(x& val); \ template<> \ - int accessComponent(x& val) { tl_##x = &val; return 0; } + x& getComponent(); + #define DEFINE_COMPONENT(x) \ - thread_local x* Seele::Component::tl_##x; + thread_local x* tl_##x = nullptr; \ + void Seele::Component::accessComponent(x& ref) { tl_##x = &ref; } \ + template<> \ + x& Seele::Component::getComponent() { return *tl_##x; } + } // namespace Seele diff --git a/src/Engine/Component/Transform.cpp b/src/Engine/Component/Transform.cpp index 35476ed..71dc320 100644 --- a/src/Engine/Component/Transform.cpp +++ b/src/Engine/Component/Transform.cpp @@ -2,7 +2,7 @@ using namespace Seele::Component; -DEFINE_COMPONENT(Transform) +DEFINE_COMPONENT(Transform); void Transform::setPosition(Vector pos) { diff --git a/src/Engine/Containers/CMakeLists.txt b/src/Engine/Containers/CMakeLists.txt index fe109a1..75715e1 100644 --- a/src/Engine/Containers/CMakeLists.txt +++ b/src/Engine/Containers/CMakeLists.txt @@ -3,7 +3,9 @@ target_sources(Engine Array.h List.h Map.h - Pair.h) + Pair.h + Set.h + Tree.h) target_sources(Engine PUBLIC FILE_SET HEADERS @@ -11,4 +13,6 @@ target_sources(Engine Array.h List.h Map.h - Pair.h) \ No newline at end of file + Pair.h + Set.h + Tree.h) \ No newline at end of file diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 0035ae8..fec7562 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -2,416 +2,101 @@ #include #include "Array.h" #include "Pair.h" +#include "Tree.h" #include "Serialization/Serialization.h" namespace Seele { +template +struct _KeyFun +{ + const KeyType& operator()(const PairType& pair) const + { + return pair.key; + } +}; template , - typename Allocator = std::pmr::polymorphic_allocator>> -struct Map + typename Allocator = std::pmr::polymorphic_allocator>> +struct Map : public Tree, _KeyFun>, Compare, Allocator> { -private: - struct Node - { - Node* leftChild; - Node* rightChild; - Pair pair; - Node() - : leftChild(nullptr) - , rightChild(nullptr) - , pair() - { - } - Node(const Node& other) = default; - Node(Node&& other) = default; - Node& operator=(const Node& other) = default; - Node& operator=(Node&& other) = default; - Node(K key) - : leftChild(nullptr) - , rightChild(nullptr) - , pair(std::move(key)) - { - } - ~Node() - { - } - }; - using NodeAlloc = std::allocator_traits::template rebind_alloc; -public: - template - class IteratorBase - { - public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = PairType; - using difference_type = std::ptrdiff_t; - using reference = PairType&; - using pointer = PairType*; - - constexpr IteratorBase(Node* x = nullptr, Array &&beginIt = Array()) - : node(x), traversal(std::move(beginIt)) - { - } - constexpr IteratorBase(const IteratorBase &i) - : node(i.node), traversal(i.traversal) - { - } - constexpr IteratorBase(IteratorBase&& i) - : node(std::move(i.node)), traversal(std::move(i.traversal)) - { - } - constexpr IteratorBase& operator=(const IteratorBase& other) - { - if(this != &other) - { - node = other.node; - traversal = other.traversal; - } - return *this; - } - constexpr IteratorBase& operator=(IteratorBase&& other) - { - if(this != &other) - { - node = std::move(other.node); - traversal = std::move(other.traversal); - } - return *this; - } - constexpr reference operator*() const - { - return node->pair; - } - constexpr pointer operator->() const - { - return &(node->pair); - } - constexpr bool operator!=(const IteratorBase &other) - { - return node != other.node; - } - constexpr bool operator==(const IteratorBase &other) - { - return node == other.node; - } - constexpr IteratorBase &operator++() - { - node = node->rightChild; - while (node != nullptr - && node->leftChild != nullptr) - { - traversal.add(node); - node = node->leftChild; - } - if (node == nullptr - && traversal.size() > 0) - { - node = traversal.back(); - traversal.pop(); - } - return *this; - } - constexpr IteratorBase &operator--() - { - node = node->leftChild; - while (node != nullptr - && node->rightChild != nullptr) - { - traversal.add(node); - node = node->rightchild; - } - if (node == nullptr - && traversal.size() > 0) - { - node = traversal.back(); - traversal.pop(); - } - return *this; - } - constexpr IteratorBase operator--(int) - { - IteratorBase tmp(*this); - --*this; - return tmp; - } - constexpr IteratorBase operator++(int) - { - IteratorBase tmp(*this); - ++*this; - return tmp; - } - - private: - Node* node; - Array traversal; - }; - using Iterator = IteratorBase>; - using ConstIterator = IteratorBase>; - - using key_type = K; + using Super = Tree, _KeyFun>, Compare, Allocator>; + using key_type = Super::key_type; using mapped_type = V; - using value_type = Pair; - using allocator_type = Allocator; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = std::allocator_traits::pointer; - using const_pointer = std::allocator_traits::const_pointer; + using value_type = Super::value_type; + + using allocator_type = Super::allocator_type; + using size_type = Super::size_type; + using difference_type = Super::difference_type; + using reference = Super::reference; + using const_reference = Super::reference; + using pointer = Super::pointer; + using const_pointer = Super::const_pointer; + + using iterator = Super::iterator; + using const_iterator = Super::const_iterator; + using reverse_iterator = Super::reverse_iterator; + using const_reverse_iterator = Super::const_reverse_iterator; - using iterator = Iterator; - using const_iterator = ConstIterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - constexpr Map() noexcept - : root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) - , iteratorsDirty(true) - , _size(0) - , comp(Compare()) + : Super() { } constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator())) - : alloc(alloc) - , root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) - , iteratorsDirty(true) - , _size(0) - , comp(comp) + : Super(comp, alloc) { } constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare())) - : alloc(alloc) - , root(nullptr) - , beginIt(nullptr) - , endIt(nullptr) - , iteratorsDirty(true) - , _size(0) - , comp(Compare()) + : Super(alloc) { } - constexpr Map(const Map& other) - : alloc(other.alloc) - , root(nullptr) - , iteratorsDirty(true) - , _size(0) - , comp(other.comp) - { - for(const auto& [key, val] : other) - { - this->operator[](key) = val; - } - } - constexpr Map(Map&& other) noexcept - : alloc(std::move(other.alloc)) - , root(std::move(other.root)) - , iteratorsDirty(true) - , _size(std::move(other._size)) - , comp(std::move(other.comp)) - { - } - constexpr ~Map() noexcept - { - clear(); - } - constexpr Map& operator=(const Map& other) - { - if(this != &other) - { - alloc = other.alloc; - comp = other.comp; - root = nullptr; - _size = 0; - for(const auto& [key, val] : other) - { - this->operator[](key) = val; - } - markIteratorsDirty(); - } - return *this; - } - constexpr Map& operator=(Map&& other) - { - if(this != &other) - { - alloc = std::move(other.alloc); - root = std::move(other.root); - _size = std::move(other._size); - comp = std::move(other.comp); - markIteratorsDirty(); - } - return *this; - } constexpr mapped_type& operator[](const key_type& key) { - root = splay(root, key); - if (root == nullptr || !equal(root->pair.key, key)) - { - root = insert(root, key); - _size++; - } - markIteratorsDirty(); - return root->pair.value; + auto [it, inserted] = Super::insert(Pair(key, V())); + return it->value; } constexpr const mapped_type& operator[](const key_type& key) const { - Node* it = root; - while (!equal(it->pair.key, key)) - { - if (comp(key, it->pair.key)) - { - it = it->leftChild; - } - else - { - it = it->rightChild; - } - } - return it->pair.value; + return Super::find(key)->value; } constexpr mapped_type& at(const key_type& key) { - root = splay(root, key); - if (root == nullptr || !equal(root->pair.key, key)) + iterator elem = Super::find(key); + if (elem == Super::end()) { throw std::logic_error("Key not found"); } - markIteratorsDirty(); - return root->pair.value; + return elem->value; } - constexpr mapped_type& at(key_type&& key) - { - root = splay(root, std::move(key)); - if (root == nullptr || !equal(root->pair.key, key)) - { - throw std::logic_error("Key not found"); - } - markIteratorsDirty(); - return root->pair.value; - } - constexpr const mapped_type& at(const key_type& key) const { - Node* it = root; - while (!equal(it->pair.key, key)) - { - if (comp(key, it->pair.key)) - { - it = it->leftChild; - } - else - { - it = it->rightChild; - } - } - return it->pair.value; + return Super::find(key)->value; } constexpr iterator find(const key_type& key) { - root = splay(root, key); - refreshIterators(); - if (root == nullptr || !equal(root->pair.key, key)) - { - return endIt; - } - return iterator(root); - } - constexpr iterator find(key_type&& key) - { - root = splay(root, std::move(key)); - refreshIterators(); - if (root == nullptr || !equal(root->pair.key, key)) - { - return endIt; - } - return iterator(root); + return Super::find(key); } constexpr iterator erase(const key_type& key) { - root = remove(root, key); - refreshIterators(); - assert(root != nullptr || _size == 0); - return iterator(root); - } - constexpr iterator erase(key_type&& key) - { - root = remove(root, std::move(key)); - refreshIterators(); - return iterator(root); - } - constexpr void clear() - { - while(_size > 0) - { - root = remove(root, root->pair.key); - } - root = nullptr; - markIteratorsDirty(); + return Super::remove(key); } constexpr bool exists(const key_type& key) { - return find(key) != endIt; - } - constexpr bool exists(key_type&& key) - { - return find(std::move(key)) != endIt; + return Super::find(key) != Super::end(); } constexpr bool contains(const key_type& key) { return exists(key); } - constexpr bool contains(key_type&& key) + constexpr Pair insert(const value_type& val) { - return exists(key); - } - constexpr iterator begin() - { - if(iteratorsDirty) - { - refreshIterators(); - } - return beginIt; - } - constexpr iterator end() - { - if(iteratorsDirty) - { - refreshIterators(); - } - return endIt; - } - constexpr iterator begin() const - { - if(iteratorsDirty) - { - return calcBeginIterator(); - } - return beginIt; - } - constexpr iterator end() const - { - if(iteratorsDirty) - { - return calcEndIterator(); - } - return endIt; - } - constexpr bool empty() const - { - return _size == 0; - } - constexpr size_type size() const - { - return _size; + return Super::insert(val); } void save(ArchiveBuffer& buffer) const { - buffer.writeBytes(&_size, sizeof(uint64)); + size_t s = Super::size(); + buffer.writeBytes(&s, sizeof(uint64)); for(const auto& [k, v] : *this) { Serialization::save(buffer, k); @@ -431,189 +116,5 @@ public: this->operator[](std::move(k)) = std::move(v); } } -private: - void verifyTree() - { - size_t numElems = 0; - for (const auto& it : *this) - { - numElems++; - } - assert(numElems == _size); - } - void markIteratorsDirty() - { - iteratorsDirty = true; - } - void refreshIterators() - { - beginIt = calcBeginIterator(); - endIt = calcEndIterator(); - iteratorsDirty = false; - } - constexpr Iterator calcBeginIterator() const - { - Node* begin = root; - Array beginTraversal; - while (begin != nullptr) - { - beginTraversal.add(begin); - begin = begin->leftChild; - } - if(!beginTraversal.empty()) - { - begin = beginTraversal.back(); - beginTraversal.pop(); - } - return Iterator(begin, std::move(beginTraversal)); - } - constexpr Iterator calcEndIterator() const - { - Node* endIndex = root; - Array endTraversal; - while (endIndex != nullptr) - { - endTraversal.add(endIndex); - endIndex = endIndex->rightChild; - } - return Iterator(endIndex, std::move(endTraversal)); - } - NodeAlloc alloc; - Node* root; - Iterator beginIt; - Iterator endIt; - bool iteratorsDirty; - size_type _size; - Compare comp; - Node* rotateLeft(Node* x) - { - Node* y = x->rightChild; - x->rightChild = y->leftChild; - y->leftChild = x; - return y; - } - Node* rotateRight(Node* x) - { - Node* y = x->leftChild; - x->leftChild = y->rightChild; - y->rightChild = x; - return y; - } - template - Node* insert(Node* r, KeyType&& key) - { - if (r == nullptr) - { - root = alloc.allocate(1); - std::allocator_traits::construct(alloc, root, std::forward(key)); - return root; - } - r = splay(r, key); - - if (equal(r->pair.key, key)) - return r; - - Node *newNode = alloc.allocate(1); - std::allocator_traits::construct(alloc, newNode, std::forward(key)); - - if (comp(newNode->pair.key, r->pair.key)) - { - newNode->rightChild = r; - newNode->leftChild = r->leftChild; - r->leftChild = nullptr; - } - else - { - newNode->leftChild = r; - newNode->rightChild = r->rightChild; - r->rightChild = nullptr; - } - return newNode; - } - template - Node* remove(Node* r, KeyType&& key) - { - Node* temp; - if (r == nullptr) - return nullptr; - - r = splay(r, key); - - if (!equal(r->pair.key, key)) - return r; - - if (r->leftChild == nullptr) - { - temp = r; - r = r->rightChild; - } - else - { - temp = r; - - r = splay(r->leftChild, key); - r->rightChild = temp->rightChild; - } - std::allocator_traits::destroy(alloc, temp); - alloc.deallocate(temp, 1); - _size--; - return r; - } - template - Node* splay(Node* r, KeyType&& key) - { - if (r == nullptr || equal(r->pair.key, key)) - { - return r; - } - if (comp(key, r->pair.key)) - { - if (r->leftChild == nullptr) - return r; - - if (comp(key, r->leftChild->pair.key)) - { - r->leftChild->leftChild = splay(r->leftChild->leftChild, key); - - r = rotateRight(r); - } - else if (comp(r->leftChild->pair.key, key)) - { - r->leftChild->rightChild = splay(r->leftChild->rightChild, key); - - if (r->leftChild->rightChild != nullptr) - { - r->leftChild = rotateLeft(r->leftChild); - } - } - return (r->leftChild == nullptr) ? r : rotateRight(r); - } - else - { - if (r->rightChild == nullptr) - return r; - - if (comp(key, r->rightChild->pair.key)) - { - r->rightChild->leftChild = splay(r->rightChild->leftChild, key); - - if (r->rightChild->leftChild != nullptr) - { - r->rightChild = rotateRight(r->rightChild); - } - } - else if (comp(r->rightChild->pair.key, key)) - { - r->rightChild->rightChild = splay(r->rightChild->rightChild, key); - - r = rotateLeft(r); - } - return (r->rightChild == nullptr) ? r : rotateLeft(r); - } - } - bool equal(const key_type& a, const key_type& b) const - { - return !comp(a, b) && !comp(b, a); - } }; } // namespace Seele diff --git a/src/Engine/Containers/Pair.h b/src/Engine/Containers/Pair.h index 3eb555b..c804c11 100644 --- a/src/Engine/Containers/Pair.h +++ b/src/Engine/Containers/Pair.h @@ -6,20 +6,21 @@ template struct Pair { public: - Pair() + constexpr Pair() : key(K()), value(V()) {} + constexpr Pair(const K & key, const V & value) + : key(key), value(value) + {} + template + constexpr Pair(U1&& x, U2&& y) + : key(std::forward(x)) + , value(std::forward(y)) + { + } Pair(const Pair& other) = default; Pair(Pair&& other) = default; ~Pair(){} - template - explicit Pair(KeyType&& key) - : key(std::forward(key)), value(V()) - {} - template - explicit Pair(KeyType&& key, ValueType&& value) - : key(std::forward(key)), value(std::forward(value)) - {} Pair& operator=(const Pair& other) = default; Pair& operator=(Pair&& other) = default; constexpr friend bool operator<(const Pair& left, const Pair& right) diff --git a/src/Engine/Containers/Set.h b/src/Engine/Containers/Set.h new file mode 100644 index 0000000..7031b88 --- /dev/null +++ b/src/Engine/Containers/Set.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Array.h" +#include "Tree.h" + +namespace Seele +{ +template, class Allocator = std::pmr::polymorphic_allocator> +class Set : public Tree +{ +public: + using Super = Tree; + using key_type = Key; + using value_type = Key; + using node_type = Super::Node; + using allocator_type = Super::allocator_type; + using size_type = Super::size_type; + using difference_type = Super::difference_type; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = std::allocator_traits::pointer; + using const_pointer = std::allocator_traits::const_pointer; + + using iterator = Super::iterator; + using const_iterator = Super::const_iterator; + using reverse_iterator = Super::reverse_iterator; + using const_reverse_iterator = Super::const_reverse_iterator; + + Set() + : Set(Compare()) + { + } + explicit Set(const Compare& comp, const Allocator alloc = Allocator()) + : Super(comp, alloc) + { + } + explicit Set(const Allocator alloc) + : Super(alloc) + { + } + constexpr Pair insert(const value_type& value) + { + return Super::insert(value); + } +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Containers/Tree.h b/src/Engine/Containers/Tree.h new file mode 100644 index 0000000..53221d7 --- /dev/null +++ b/src/Engine/Containers/Tree.h @@ -0,0 +1,510 @@ +#pragma once +#include +#include "Pair.h" + +namespace Seele +{ +template < + typename KeyType, + typename NodeData, + typename KeyFun, + typename Compare, + typename Allocator> +struct Tree +{ +protected: + struct Node + { + Node* leftChild; + Node* rightChild; + NodeData data; + }; + using NodeAlloc = std::allocator_traits::template rebind_alloc; +public: + template + class IteratorBase + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = IterType; + using difference_type = std::ptrdiff_t; + using reference = IterType&; + using pointer = IterType*; + + constexpr IteratorBase(Node* x = nullptr, Array&& beginIt = Array()) + : node(x), traversal(std::move(beginIt)) + { + } + constexpr IteratorBase(const IteratorBase& i) + : node(i.node), traversal(i.traversal) + { + } + constexpr IteratorBase(IteratorBase&& i) + : node(std::move(i.node)), traversal(std::move(i.traversal)) + { + } + constexpr IteratorBase& operator=(const IteratorBase& other) + { + if (this != &other) + { + node = other.node; + traversal = other.traversal; + } + return *this; + } + constexpr IteratorBase& operator=(IteratorBase&& other) + { + if (this != &other) + { + node = std::move(other.node); + traversal = std::move(other.traversal); + } + return *this; + } + constexpr reference operator*() const + { + return node->data; + } + constexpr pointer operator->() const + { + return &(node->data); + } + constexpr bool operator!=(const IteratorBase& other) + { + return node != other.node; + } + constexpr bool operator==(const IteratorBase& other) + { + return node == other.node; + } + constexpr IteratorBase& operator++() + { + node = node->rightChild; + while (node != nullptr + && node->leftChild != nullptr) + { + traversal.add(node); + node = node->leftChild; + } + if (node == nullptr + && traversal.size() > 0) + { + node = traversal.back(); + traversal.pop(); + } + return *this; + } + constexpr IteratorBase& operator--() + { + node = node->leftChild; + while (node != nullptr + && node->rightChild != nullptr) + { + traversal.add(node); + node = node->rightchild; + } + if (node == nullptr + && traversal.size() > 0) + { + node = traversal.back(); + traversal.pop(); + } + return *this; + } + constexpr IteratorBase operator--(int) + { + IteratorBase tmp(*this); + --*this; + return tmp; + } + constexpr IteratorBase operator++(int) + { + IteratorBase tmp(*this); + ++*this; + return tmp; + } + Node* getNode() + { + return node; + } + private: + Node* node; + Array traversal; + }; + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; + + using key_type = KeyType; + using value_type = NodeData; + using allocator_type = Allocator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = std::allocator_traits::pointer; + using const_pointer = std::allocator_traits::const_pointer; + + using iterator = Iterator; + using const_iterator = ConstIterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + constexpr Tree() noexcept + : root(nullptr) + , beginIt(nullptr) + , endIt(nullptr) + , iteratorsDirty(true) + , _size(0) + , comp(Compare()) + { + } + constexpr explicit Tree(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator())) + : alloc(alloc) + , root(nullptr) + , beginIt(nullptr) + , endIt(nullptr) + , iteratorsDirty(true) + , _size(0) + , comp(comp) + { + } + constexpr explicit Tree(const Allocator& alloc) noexcept(noexcept(Compare())) + : alloc(alloc) + , root(nullptr) + , beginIt(nullptr) + , endIt(nullptr) + , iteratorsDirty(true) + , _size(0) + , comp(Compare()) + { + } + constexpr Tree(const Tree& other) + : alloc(other.alloc) + , root(nullptr) + , iteratorsDirty(true) + , _size() + , comp(other.comp) + { + std::copy(other.begin(), other.end(), begin()); + } + constexpr Tree(Tree&& other) noexcept + : alloc(std::move(other.alloc)) + , root(std::move(other.root)) + , iteratorsDirty(true) + , _size(std::move(other._size)) + , comp(std::move(other.comp)) + { + } + constexpr ~Tree() noexcept + { + clear(); + } + constexpr Tree& operator=(const Tree& other) + { + if (this != &other) + { + clear(); + alloc = other.alloc; + comp = other.comp; + root = nullptr; + _size = 0; + std::copy(other.begin(), other.end(), begin()); + markIteratorsDirty(); + } + return *this; + } + constexpr Tree& operator=(Tree&& other) + { + if (this != &other) + { + clear(); + alloc = std::move(other.alloc); + root = std::move(other.root); + _size = std::move(other._size); + comp = std::move(other.comp); + markIteratorsDirty(); + } + return *this; + } + constexpr void clear() + { + while (_size > 0) + { + root = _remove(root, keyFun(root->data)); + } + root = nullptr; + markIteratorsDirty(); + } + constexpr iterator begin() + { + if (iteratorsDirty) + { + refreshIterators(); + } + return beginIt; + } + constexpr iterator end() + { + if (iteratorsDirty) + { + refreshIterators(); + } + return endIt; + } + constexpr iterator begin() const + { + if (iteratorsDirty) + { + return calcBeginIterator(); + } + return beginIt; + } + constexpr iterator end() const + { + if (iteratorsDirty) + { + return calcEndIterator(); + } + return endIt; + } + constexpr bool empty() const + { + return _size == 0; + } + constexpr size_type size() const + { + return _size; + } +protected: + constexpr iterator find(const key_type& key) + { + root = _splay(root, key); + if (root == nullptr || !equal(root->data, key)) + { + return end(); + } + return iterator(root); + } + constexpr iterator find(const key_type& key) const + { + Node* it = root; + while (!equal(it->data, key)) + { + if (comp(key, keyFun(it->data))) + { + it = it->leftChild; + } + else + { + it = it->rightChild; + } + } + return iterator(it); + } + constexpr Pair insert(const NodeData& data) + { + auto [r, inserted] = _insert(root, data); + root = r; + return Pair(iterator(root), inserted); + } + constexpr Pair insert(NodeData&& data) + { + auto [r, inserted] = _insert(root, std::move(data)); + root = r; + return Pair(iterator(root), inserted); + } + constexpr iterator remove(const key_type& key) + { + root = _remove(root, key); + return iterator(root); + } +private: + void verifyTree() + { + size_t numElems = 0; + for (const auto& it : *this) + { + numElems++; + } + assert(numElems == _size); + } + void markIteratorsDirty() + { + iteratorsDirty = true; + } + void refreshIterators() + { + beginIt = calcBeginIterator(); + endIt = calcEndIterator(); + iteratorsDirty = false; + } + constexpr Iterator calcBeginIterator() const + { + Node* begin = root; + Array beginTraversal; + while (begin != nullptr) + { + beginTraversal.add(begin); + begin = begin->leftChild; + } + if (!beginTraversal.empty()) + { + begin = beginTraversal.back(); + beginTraversal.pop(); + } + return Iterator(begin, std::move(beginTraversal)); + } + constexpr Iterator calcEndIterator() const + { + Node* endIndex = root; + Array endTraversal; + while (endIndex != nullptr) + { + endTraversal.add(endIndex); + endIndex = endIndex->rightChild; + } + return Iterator(endIndex, std::move(endTraversal)); + } + NodeAlloc alloc; + Node* root; + Iterator beginIt; + Iterator endIt; + bool iteratorsDirty; + size_type _size; + Compare comp; + KeyFun keyFun = KeyFun(); + Node* rotateLeft(Node* x) + { + Node* y = x->rightChild; + x->rightChild = y->leftChild; + y->leftChild = x; + return y; + } + Node* rotateRight(Node* x) + { + Node* y = x->leftChild; + x->leftChild = y->rightChild; + y->rightChild = x; + return y; + } + template + Pair _insert(Node* r, NodeDataType&& data) + { + if (r == nullptr) + { + root = alloc.allocate(1); + std::allocator_traits::construct(alloc, root, nullptr, nullptr, std::forward(data)); + _size++; + return Pair(root, true); + } + r = _splay(r, keyFun(data)); + + if (equal(r->data, keyFun(data))) + return Pair(r, false); + + Node* newNode = alloc.allocate(1); + std::allocator_traits::construct(alloc, newNode, nullptr, nullptr, std::forward(data)); + + if (comp(keyFun(r->data), keyFun(newNode->data))) + { + newNode->rightChild = r; + newNode->leftChild = r->leftChild; + r->leftChild = nullptr; + } + else + { + newNode->leftChild = r; + newNode->rightChild = r->rightChild; + r->rightChild = nullptr; + } + _size++; + return Pair(newNode, true); + } + template + Node* _remove(Node* r, KeyType&& key) + { + Node* temp; + if (r == nullptr) + return nullptr; + + r = _splay(r, key); + + if (!equal(r->data, key)) + return r; + + if (r->leftChild == nullptr) + { + temp = r; + r = r->rightChild; + } + else + { + temp = r; + + r = _splay(r->leftChild, key); + r->rightChild = temp->rightChild; + } + std::allocator_traits::destroy(alloc, temp); + alloc.deallocate(temp, 1); + _size--; + return r; + } + template + Node* _splay(Node* r, KeyType&& key) + { + if (r == nullptr || equal(r->data, key)) + { + return r; + } + if (comp(keyFun(r->data), key)) + { + if (r->leftChild == nullptr) + return r; + + if (comp(keyFun(r->leftChild->data), key)) + { + r->leftChild->leftChild = _splay(r->leftChild->leftChild, key); + + r = rotateRight(r); + } + else if (comp(keyFun(r->leftChild->data), key)) + { + r->leftChild->rightChild = _splay(r->leftChild->rightChild, key); + + if (r->leftChild->rightChild != nullptr) + { + r->leftChild = rotateLeft(r->leftChild); + } + } + return (r->leftChild == nullptr) ? r : rotateRight(r); + } + else + { + if (r->rightChild == nullptr) + return r; + + if (comp(keyFun(r->rightChild->data), key)) + { + r->rightChild->leftChild = _splay(r->rightChild->leftChild, key); + + if (r->rightChild->leftChild != nullptr) + { + r->rightChild = rotateRight(r->rightChild); + } + } + else if (comp(keyFun(r->rightChild->data), key)) + { + r->rightChild->rightChild = _splay(r->rightChild->rightChild, key); + + r = rotateLeft(r); + } + return (r->rightChild == nullptr) ? r : rotateLeft(r); + } + } + template + bool equal(const NodeData& a, KeyType&& b) const + { + return !comp(keyFun(a), b) && !comp(b, keyFun(a)); + } +}; +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index a2ea5cf..9aaaa5e 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -157,7 +157,6 @@ void BasePass::render() command->bindDescriptor(descriptorSets); if (graphics->supportMeshShading()) { - std::cout << "Num Meshes: " << instance.meshes.size() << std::endl; command->dispatch(instance.meshes.size(), 1, 1); } else diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 1941ed2..2883293 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -113,10 +113,10 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) loadColors(id, col); } -void StaticMeshVertexData::init(Gfx::PGraphics graphics) +void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { - VertexData::init(graphics); - descriptorLayout = graphics->createDescriptorLayout("StaticMeshDescriptorLayout"); + VertexData::init(_graphics); + descriptorLayout = _graphics->createDescriptorLayout("StaticMeshDescriptorLayout"); descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 3a6e7e5..977f2fa 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -6,7 +6,7 @@ #include "Graphics/Descriptor.h" #include "Component/Mesh.h" #include "Graphics/Shader.h" -#include +#include "Containers/Set.h" using namespace Seele; @@ -248,6 +248,12 @@ VertexData::VertexData() void Meshlet::build(const Array& indices, Array& meshlets) { + Map> connectivity; + for (uint32 i = 0; i < indices.size(); i+=3) + { + connectivity[indices[i]].insert(indices[i + 1]); + connectivity[indices[i]].insert(indices[i + 2]); + } Meshlet current = { .numVertices = 0, .numPrimitives = 0, diff --git a/src/Engine/System/ComponentSystem.h b/src/Engine/System/ComponentSystem.h index 86bcebc..2d514b5 100644 --- a/src/Engine/System/ComponentSystem.h +++ b/src/Engine/System/ComponentSystem.h @@ -23,29 +23,14 @@ public: { return Dependencies<>(); } - template - auto mergeDependencies(Dep... deps) - { - return (deps | ...); - } - void setupView(Dependencies<>, ThreadPool& pool) - { - List> work; - registry.view().each([&](Components&... comp){ - work.add([&](){ - update(comp...); - }); - }); - pool.runAndWait(std::move(work)); - } template void setupView(Dependencies, ThreadPool& pool) { List> work; registry.view().each([&](Components&... comp, Deps&... deps){ work.add([&]() { - (accessComponent(deps) + ...); - update((comp,...)); + (accessComponent(deps), ...); + update(comp...); }); }); pool.runAndWait(std::move(work)); @@ -53,7 +38,7 @@ public: virtual void run(ThreadPool& pool, double delta) override { SystemBase::run(pool, delta); - setupView(mergeDependencies((getDependencies(),...)), pool); + setupView((getDependencies() | ...), pool); } virtual void update() {} virtual void update(Components&... components) = 0; diff --git a/src/Engine/System/SystemBase.h b/src/Engine/System/SystemBase.h index 9b7880b..afd08ad 100644 --- a/src/Engine/System/SystemBase.h +++ b/src/Engine/System/SystemBase.h @@ -12,7 +12,7 @@ class SystemBase public: SystemBase(PScene scene) : registry(scene->registry), scene(scene) {} virtual ~SystemBase() {} - virtual void run(ThreadPool& pool, double delta) + virtual void run(ThreadPool&, double delta) { deltaTime = delta; update(); diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index ee1f121..6ff691d 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -25,16 +25,14 @@ ThreadPool::~ThreadPool() void ThreadPool::runAndWait(List> functions) { - { - std::unique_lock l(taskLock); - currentTask.numRemaining = functions.size(); - currentTask.functions = std::move(functions); - taskCV.notify_all(); - } + std::unique_lock l(taskLock); + currentTask.numRemaining = functions.size(); + currentTask.functions = std::move(functions); + taskCV.notify_all(); + while (currentTask.numRemaining > 0) { - std::unique_lock l2(completedLock); - completedCV.wait(l2); + completedCV.wait(l); } } @@ -59,7 +57,6 @@ void ThreadPool::work() currentTask.numRemaining--; if (currentTask.numRemaining == 0) { - std::unique_lock l2(completedLock); completedCV.notify_one(); } } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 0a0d786..afa27d8 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -21,7 +21,6 @@ private: Array workers; std::mutex taskLock; std::condition_variable taskCV; - std::mutex completedLock; std::condition_variable completedCV; Task currentTask; bool running = true; diff --git a/tests/Engine/CMakeLists.txt b/tests/Engine/CMakeLists.txt index 5639dba..e2d0111 100644 --- a/tests/Engine/CMakeLists.txt +++ b/tests/Engine/CMakeLists.txt @@ -7,4 +7,5 @@ target_include_directories(SeeleUnitTests PUBLIC ./) add_subdirectory(Containers/) add_subdirectory(Graphics/) add_subdirectory(Math/) -add_subdirectory(Serialization/) \ No newline at end of file +add_subdirectory(Serialization/) +add_subdirectory(System/) \ No newline at end of file diff --git a/tests/Engine/System/CMakeLists.txt b/tests/Engine/System/CMakeLists.txt new file mode 100644 index 0000000..e625970 --- /dev/null +++ b/tests/Engine/System/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(SeeleUnitTests + PRIVATE + ComponentSystem.cpp) \ No newline at end of file diff --git a/tests/Engine/System/ComponentSystem.cpp b/tests/Engine/System/ComponentSystem.cpp new file mode 100644 index 0000000..d9bdf98 --- /dev/null +++ b/tests/Engine/System/ComponentSystem.cpp @@ -0,0 +1,9 @@ +#include "EngineTest.h" +#include "Component/Component.h" +#include "Component/Transform.h" +#include "Component/Camera.h" +#include "Component/DirectionalLight.h" +#include "System/ComponentSystem.h" + +using namespace Seele; +using namespace Seele::System; diff --git a/tests/Engine/ThreadPool.cpp b/tests/Engine/ThreadPool.cpp index d61f90f..956b93b 100644 --- a/tests/Engine/ThreadPool.cpp +++ b/tests/Engine/ThreadPool.cpp @@ -8,14 +8,13 @@ TEST(ThreadPool, RunBatch) uint32 test = 20; std::mutex m; List> work; - for (uint32 i = 0; i < 400; ++i) + for (uint32 i = 0; i < 40000; ++i) { work.add([&]() { std::unique_lock l(m); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); test++; }); } t.runAndWait(std::move(work)); - ASSERT_EQ(test, 420); + ASSERT_EQ(test, 40020); } \ No newline at end of file