From 9c48c48f8c811088bf81479d23e386416f441e18 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Sat, 23 Oct 2021 00:22:35 +0200 Subject: [PATCH] Allocator Aware Array and List --- res/shaders/DepthPrepass.slang | 2 +- res/shaders/ForwardPlus.slang | 1 + src/Engine/CMakeLists.txt | 2 + src/Engine/Containers/Array.h | 1204 +++++++++++---------- src/Engine/Containers/List.h | 678 ++++++------ src/Engine/Containers/Map.h | 2 +- src/Engine/Graphics/GraphicsResources.cpp | 10 +- src/Engine/MinimalEngine.h | 627 +++++------ src/Engine/Scene/SceneUpdater.h | 1 + src/Engine/ThreadPool.cpp | 19 +- src/Engine/ThreadPool.h | 42 +- src/Engine/Window/Window.cpp | 16 +- src/Engine/Window/Window.h | 2 + src/Engine/Window/WindowManager.cpp | 9 - src/Engine/Window/WindowManager.h | 1 - src/Engine/main.cpp | 4 +- 16 files changed, 1390 insertions(+), 1230 deletions(-) diff --git a/res/shaders/DepthPrepass.slang b/res/shaders/DepthPrepass.slang index 2c64826..bb2d47b 100644 --- a/res/shaders/DepthPrepass.slang +++ b/res/shaders/DepthPrepass.slang @@ -22,4 +22,4 @@ VertexStageOutput vertexMain(PositionOnlyVertexShaderInput input) clipSpacePosition = mul(gViewParams.projectionMatrix, viewSpacePosition); output.position = clipSpacePosition; return output; -} \ No newline at end of file +} diff --git a/res/shaders/ForwardPlus.slang b/res/shaders/ForwardPlus.slang index c26f31a..d9d9de6 100644 --- a/res/shaders/ForwardPlus.slang +++ b/res/shaders/ForwardPlus.slang @@ -74,3 +74,4 @@ float4 fragmentMain( } return float4(result, 1); } + diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 8407242..e13933a 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -3,6 +3,8 @@ target_sources(SeeleEngine EngineTypes.h MinimalEngine.h MinimalEngine.cpp + ThreadPool.h + ThreadPool.cpp main.cpp) add_subdirectory(Asset/) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 4ddb32c..462b5b4 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -12,571 +12,671 @@ namespace Seele { - enum class Init_t { - NO_INIT - }; - template - struct Array - { - public: - - Array() - : arraySize(0) - , allocated(DEFAULT_ALLOC_SIZE) - { - _data = new T[DEFAULT_ALLOC_SIZE]; - assert(_data != nullptr); - //std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE); - markIteratorDirty(); - } - Array(Init_t) - : arraySize(0) - , allocated(0) - , beginIt(Iterator(nullptr)) - , endIt(Iterator(nullptr)) - , _data(nullptr) - { - } - Array(size_t size, T value = T()) - : arraySize(size) - , allocated(size) - { - _data = new T[size]; - assert(_data != nullptr); - for (size_t i = 0; i < size; ++i) - { - assert(i < size); - _data[i] = value; - } - markIteratorDirty(); - } - Array(std::initializer_list init) - : arraySize(init.size()) - , allocated(init.size()) - { - _data = new T[init.size()]; - auto it = init.begin(); - for (size_t i = 0; it != init.end(); i++, it++) - { - assert(i < init.size()); - _data[i] = *it; - } - markIteratorDirty(); - } - Array(const Array &other) - : arraySize(other.arraySize) - , allocated(other.allocated) - { - _data = new T[other.allocated]; - assert(_data != nullptr); - markIteratorDirty(); - std::copy(other.begin(), other.end(), begin()); - } - Array(Array &&other) noexcept - : arraySize(std::move(other.arraySize)) - , allocated(std::move(other.allocated)) - { - _data = other._data; - other._data = nullptr; - other.allocated = 0; - other.arraySize = 0; - markIteratorDirty(); - } - Array &operator=(const Array &other) noexcept - { - if (this != &other) - { - if (_data != nullptr) - { - if(other.arraySize > allocated) - { - delete[] _data; - _data = new T[other.allocated]; - allocated = other.allocated; - } - } - arraySize = other.arraySize; - markIteratorDirty(); - std::copy(other.begin(), other.end(), begin()); - } - return *this; - } - Array &operator=(Array &&other) noexcept - { - if (this != &other) - { - if (_data != nullptr) - { - delete[] _data; - _data = nullptr; - } - allocated = std::move(other.allocated); - arraySize = std::move(other.arraySize); - _data = other._data; - other._data = nullptr; - markIteratorDirty(); - } - return *this; - } - ~Array() - { - if (_data) - { - delete[] _data; - _data = nullptr; - } - } - template - class IteratorBase - { - public: - using iterator_category = std::random_access_iterator_tag; - using value_type = X; - using difference_type = std::ptrdiff_t; - using reference = X&; - using pointer = X*; + template > + struct Array + { + public: + template + class IteratorBase + { + public: + using iterator_category = std::random_access_iterator_tag; + using value_type = X; + using difference_type = std::ptrdiff_t; + using reference = X&; + using pointer = X*; - IteratorBase(X *x = nullptr) - : p(x) - { - } - reference operator*() const - { - return *p; - } - pointer operator->() const - { - return p; - } - inline bool operator!=(const IteratorBase &other) const - { - return p != other.p; - } - inline bool operator==(const IteratorBase &other) const - { - return p == other.p; - } - inline int operator-(const IteratorBase &other) const - { - return (int)(p - other.p); - } - IteratorBase &operator++() - { - p++; - return *this; - } - IteratorBase &operator--() - { - p--; - return *this; - } - IteratorBase operator++(int) - { - IteratorBase tmp(*this); - ++*this; - return tmp; - } - IteratorBase operator--(int) - { - IteratorBase tmp(*this); - --*this; - return tmp; - } + IteratorBase(X *x = nullptr) + : p(x) + { + } + reference operator*() const + { + return *p; + } + pointer operator->() const + { + return p; + } + inline bool operator!=(const IteratorBase &other) const + { + return p != other.p; + } + inline bool operator==(const IteratorBase &other) const + { + return p == other.p; + } + inline int operator-(const IteratorBase &other) const + { + return (int)(p - other.p); + } + IteratorBase &operator++() + { + p++; + return *this; + } + IteratorBase &operator--() + { + p--; + return *this; + } + IteratorBase operator++(int) + { + IteratorBase tmp(*this); + ++*this; + return tmp; + } + IteratorBase operator--(int) + { + IteratorBase tmp(*this); + --*this; + return tmp; + } - private: - X *p; - }; - typedef IteratorBase Iterator; - typedef IteratorBase ConstIterator; + private: + X *p; + }; + + using value_type = T; + using allocator_type = Allocator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using pointer = T*; + using const_pointer = const T*; + using reference = value_type&; + using const_reference = const value_type&; - bool operator==(const Array &other) - { - return _data == other._data; - } + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; + using iterator = Iterator; + using const_iterator = ConstIterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; - bool operator!=(const Array &other) - { - return !(*this == other); - } + constexpr Array() noexcept(noexcept(Allocator())) + : arraySize(0) + , allocated(DEFAULT_ALLOC_SIZE) + , allocator(Allocator()) + { + _data = allocateArray(DEFAULT_ALLOC_SIZE); + assert(_data != nullptr); + markIteratorDirty(); + } - Iterator find(const T &item) - { - for (uint32 i = 0; i < arraySize; ++i) - { - if (_data[i] == item) - { - return Iterator(&_data[i]); - } - } - return endIt; - } - Iterator find(T&& item) - { - for (uint32 i = 0; i < arraySize; ++i) - { - if (_data[i] == item) - { - return Iterator(&_data[i]); - } - } - return endIt; - } - Iterator begin() const - { - return beginIt; - } - Iterator end() const - { - return endIt; - } - ConstIterator cbegin() const - { - return beginIt; - } - ConstIterator cend() const - { - return endIt; - } - T &add(const T &item = T()) - { - return addInternal(item); - } - T &add(T&& item) - { - return addInternal(std::forward(item)); - } - T &addUnique(const T &item = T()) - { - Iterator it; - if((it = std::move(find(item))) != endIt) - { - return *it; - } - return addInternal(item); - } - template - T &emplace(args... arguments) - { - if (arraySize == allocated) - { - size_t newSize = arraySize + 1; - allocated = calculateGrowth(newSize); - T *tempArray = new T[allocated]; - assert(tempArray != nullptr); - for (size_t i = 0; i < arraySize; ++i) - { - tempArray[i] = _data[i]; - } - delete[] _data; - _data = tempArray; - } - _data[arraySize++] = T(arguments...); - markIteratorDirty(); - return _data[arraySize - 1]; - } - void remove(Iterator it, bool keepOrder = true) - { - remove(it - beginIt, keepOrder); - } - void remove(int index, bool keepOrder = true) - { - if (keepOrder) - { - for(uint32 i = index; i < arraySize-1; ++i) - { - _data[i] = std::move(_data[i+1]); - } - } - else - { - _data[index] = std::move(_data[arraySize - 1]); - } - arraySize--; - markIteratorDirty(); - } - void clear() - { - delete[] _data; - _data = nullptr; - arraySize = 0; - allocated = 0; - markIteratorDirty(); - } - void resize(size_t newSize) - { - if (newSize <= allocated) - { - arraySize = newSize; - } - else - { - T *newData = new T[newSize]; - assert(newData != nullptr); - allocated = newSize; - for(uint32 i = 0; i < arraySize; ++i) - { - newData[i] = std::move(_data[i]); - } - arraySize = newSize; - delete _data; - _data = newData; - } - markIteratorDirty(); - } - inline size_t indexOf(Iterator iterator) - { - return iterator - beginIt; - } - inline size_t indexOf(ConstIterator iterator) const - { - return iterator.p - beginIt.p; - } - inline size_t indexOf(T& t) - { - return indexOf(find(t)); - } - inline size_t indexOf(const T& t) const - { - return indexOf(find(t)); - } - inline size_t size() const - { - return arraySize; - } - inline size_t empty() const - { - return arraySize == 0; - } - inline size_t capacity() const - { - return allocated; - } - inline T *data() const - { - return _data; - } - inline T &back() const - { - return _data[arraySize - 1]; - } - void pop() - { - arraySize--; - markIteratorDirty(); - } - constexpr inline T &operator[](size_t index) - { - assert(index < arraySize); - return _data[index]; - } - constexpr inline const T &operator[](size_t index) const - { - assert(index < arraySize); - return _data[index]; - } - private: - size_t calculateGrowth(size_t newSize) const - { - const size_t oldCapacity = capacity(); + constexpr explicit Array(const allocator_type& alloc) + : arraySize(0) + , allocated(DEFAULT_ALLOC_SIZE) + , allocator(alloc) + { + _data = allocateArray(DEFAULT_ALLOC_SIZE); + assert(_data != nullptr); + markIteratorDirty(); + } + constexpr Array(size_type size, const T& value, const allocator_type& alloc = allocator_type()) + : arraySize(size) + , allocated(size) + , allocator(alloc) + { + _data = allocateArray(size); + for (size_type i = 0; i < size; ++i) + { + _data[i] = value; + } + markIteratorDirty(); + } + constexpr explicit Array(size_type size, const allocator_type& alloc = allocator_type()) + : arraySize(size) + , allocated(size) + , allocator(alloc) + { + _data = allocateArray(size); + for (size_type i = 0; i < size; ++i) + { + std::allocator_traits::construct(allocator, &_data[i]); + } + markIteratorDirty(); + } + constexpr Array(std::initializer_list init, const allocator_type& alloc = allocator_type()) + : arraySize(init.size()) + , allocated(init.size()) + , allocator(alloc) + { + _data = allocateArray(init.size()); + markIteratorDirty(); + std::uninitialized_copy(init.begin(), init.end(), begin()); + } + Array(const Array &other) + : arraySize(other.arraySize) + , allocated(other.allocated) + , allocator(std::allocator_traits::select_on_container_copy_construction(other.allocator)) + { + _data = allocateArray(other.allocated); + markIteratorDirty(); + std::uninitialized_copy(other.begin(), other.end(), begin()); + } + Array(Array &&other) noexcept + : arraySize(std::move(other.arraySize)) + , allocated(std::move(other.allocated)) + , allocator(std::move(other.allocator)) + { + _data = other._data; + other._data = nullptr; + other.allocated = 0; + other.arraySize = 0; + markIteratorDirty(); + } + Array &operator=(const Array &other) noexcept + { + if (this != &other) + { + if constexpr (std::allocator_traits::propagate_on_container_copy_assignment::value + && !std::allocator_traits::is_always_equal::value) + { + if(allocator != other.allocator) + { + deallocateArray(_data, allocated); + _data = nullptr; + } + } + if constexpr (std::allocator_traits::propagate_on_container_copy_assignment::value) + { + allocator = other.allocator; + } + else + {} + if(other.arraySize > allocated) + { + if(_data != nullptr) + { + deallocateArray(_data, allocated); + } + _data = allocateArray(other.allocated); + allocated = other.allocated; + } + arraySize = other.arraySize; + markIteratorDirty(); + std::uninitialized_copy(other.begin(), other.end(), begin()); + } + return *this; + } + Array &operator=(Array &&other) noexcept + { + if (this != &other) + { + if constexpr (std::allocator_traits::propagate_on_container_move_assignment::value + && !std::allocator_traits::is_always_equal::value) + { + if(allocator != other.allocator) + { + deallocateArray(_data, allocated); + _data = nullptr; + } + } + if constexpr (std::allocator_traits::propagate_on_container_move_assignment::value) + { + allocator = std::move(other.allocator); + } + if (_data != nullptr) + { + deallocateArray(_data, allocated); + _data = nullptr; + } + allocated = std::move(other.allocated); + arraySize = std::move(other.arraySize); + _data = other._data; + other._data = nullptr; + markIteratorDirty(); + } + return *this; + } + ~Array() + { + if (_data) + { + deallocateArray(_data, allocated); + _data = nullptr; + } + } - if (oldCapacity > SIZE_MAX - oldCapacity / 2) - { - return newSize; // geometric growth would overflow - } + constexpr bool operator==(const Array &other) + { + return _data == other._data; + } - const size_t geometric = oldCapacity + oldCapacity / 2; + constexpr bool operator!=(const Array &other) + { + return !(*this == other); + } - if (geometric < newSize) - { - return newSize; // geometric growth would be insufficient - } + constexpr Iterator find(const T &item) + { + for (uint32 i = 0; i < arraySize; ++i) + { + if (_data[i] == item) + { + return Iterator(&_data[i]); + } + } + return endIt; + } + constexpr Iterator find(T&& item) + { + for (uint32 i = 0; i < arraySize; ++i) + { + if (_data[i] == item) + { + return Iterator(&_data[i]); + } + } + return endIt; + } + constexpr Allocator get_allocator() const + { + return allocator; + } + constexpr Iterator begin() const + { + return beginIt; + } + constexpr Iterator end() const + { + return endIt; + } + constexpr ConstIterator cbegin() const + { + return beginIt; + } + constexpr ConstIterator cend() const + { + return endIt; + } + constexpr T &add(const T &item = T()) + { + return addInternal(item); + } + constexpr T &add(T&& item) + { + return addInternal(std::forward(item)); + } + constexpr T &addUnique(const T &item = T()) + { + Iterator it; + if((it = std::move(find(item))) != endIt) + { + return *it; + } + return addInternal(item); + } + template + constexpr T &emplace(args... arguments) + { + if (arraySize == allocated) + { + size_type newSize = arraySize + 1; + allocated = calculateGrowth(newSize); + T *tempArray = allocateArray(allocated); + assert(tempArray != nullptr); + for (size_type i = 0; i < arraySize; ++i) + { + tempArray[i] = std::move(_data[i]); + } + deallocateArray(_data, arraySize); + _data = tempArray; + } + std::allocator_traits::construct(allocator, &_data[arraySize++], arguments...); + markIteratorDirty(); + return _data[arraySize - 1]; + } + constexpr void remove(Iterator it, bool keepOrder = true) + { + remove(it - beginIt, keepOrder); + } + constexpr void remove(int index, bool keepOrder = true) + { + if (keepOrder) + { + for(uint32 i = index; i < arraySize-1; ++i) + { + _data[i] = std::move(_data[i+1]); + } + } + else + { + _data[index] = std::move(_data[arraySize - 1]); + } + arraySize--; + markIteratorDirty(); + } + constexpr void resize(size_type newSize) + { + resizeInternal(newSize, std::move(T())); + } + constexpr void resize(size_type newSize, const T& value) + { + resizeInternal(newSize, value); + } + constexpr void clear() + { + for(size_type i = 0; i < arraySize; ++i) + { + _data[i].~T(); + } + deallocateArray(_data, allocated); + _data = nullptr; + arraySize = 0; + allocated = 0; + markIteratorDirty(); + } + inline size_type indexOf(Iterator iterator) + { + return iterator - beginIt; + } + inline size_type indexOf(ConstIterator iterator) const + { + return iterator.p - beginIt.p; + } + inline size_type indexOf(T& t) + { + return indexOf(find(t)); + } + inline size_type indexOf(const T& t) const + { + return indexOf(find(t)); + } + inline size_type size() const + { + return arraySize; + } + inline size_type empty() const + { + return arraySize == 0; + } + inline size_type capacity() const + { + return allocated; + } + inline T *data() const + { + return _data; + } + inline T &back() const + { + return _data[arraySize - 1]; + } + void pop() + { + arraySize--; + markIteratorDirty(); + } + constexpr inline T &operator[](size_type index) + { + assert(index < arraySize); + return _data[index]; + } + constexpr inline const T &operator[](size_type index) const + { + assert(index < arraySize); + return _data[index]; + } + private: + size_type calculateGrowth(size_type newSize) const + { + const size_type oldCapacity = capacity(); - return geometric; // geometric growth is sufficient - } - void markIteratorDirty() - { - beginIt = Iterator(_data); - endIt = Iterator(_data + arraySize); - } - template - T& addInternal(Type&& t) - { - if (arraySize == allocated) - { - size_t newSize = arraySize + 1; - allocated = calculateGrowth(newSize); - T *tempArray = new T[allocated]; - assert(tempArray != nullptr); - for (size_t i = 0; i < arraySize; ++i) - { - tempArray[i] = std::forward(_data[i]); - } - delete[] _data; - _data = tempArray; - } - _data[arraySize++] = std::forward(t); - markIteratorDirty(); - return _data[arraySize - 1]; - } - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int) - { - ar & arraySize; - resize(arraySize); - for(size_t i = 0; i < arraySize; ++i) - ar & _data[i]; - markIteratorDirty(); - } - size_t arraySize = 0; - size_t allocated = 0; - Iterator beginIt; - Iterator endIt; - T *_data = nullptr; - }; + if (oldCapacity > SIZE_MAX - oldCapacity / 2) + { + return newSize; // geometric growth would overflow + } - template - struct StaticArray - { - public: - template - class IteratorBase - { - public: - using iterator_category = std::random_access_iterator_tag; - using value_type = X; - using difference_type = std::ptrdiff_t; - using reference = X&; - using pointer = X*; + const size_type geometric = oldCapacity + oldCapacity / 2; - IteratorBase(X *x = nullptr) - : p(x) - { - } - reference operator*() const - { - return *p; - } - pointer operator->() const - { - return p; - } - inline bool operator!=(const IteratorBase &other) - { - return p != other.p; - } - inline bool operator==(const IteratorBase &other) - { - return p == other.p; - } - IteratorBase &operator++() - { - p++; - return *this; - } - IteratorBase operator++(int) - { - IteratorBase tmp(*this); - ++*this; - return tmp; - } - IteratorBase &operator--() - { - p--; - return *this; - } - IteratorBase operator--(int) - { - IteratorBase tmp(*this); - --*this; - return tmp; - } - + if (geometric < newSize) + { + return newSize; // geometric growth would be insufficient + } - private: - X *p; - }; - using value_type = T; - using size_type = size_t; - using difference_type = std::ptrdiff_t; - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; + return geometric; // geometric growth is sufficient + } + void markIteratorDirty() + { + beginIt = Iterator(_data); + endIt = Iterator(_data + arraySize); + } + T* allocateArray(size_type size) + { + T* result = allocator.allocate(size); + assert(result != nullptr); + return result; + } + void deallocateArray(T* ptr, size_type size) + { + allocator.deallocate(ptr, size); + } + template + T& addInternal(Type&& t) + { + if (arraySize == allocated) + { + size_type newSize = arraySize + 1; + allocated = calculateGrowth(newSize); + T *tempArray = allocateArray(allocated); + for (size_type i = 0; i < arraySize; ++i) + { + std::allocator_traits::construct(allocator, &tempArray[i], std::forward(_data[i])); + } + deallocateArray(_data, arraySize); + _data = tempArray; + } + std::allocator_traits::construct(allocator, &_data[arraySize++], std::forward(t)); + markIteratorDirty(); + return _data[arraySize - 1]; + } + template + void resizeInternal(size_type newSize, Type&& value) + { + if (newSize <= allocated) + { + // The array is already big enough + if(newSize < arraySize) + { + // But since we are sizing down we destruct some of them + for(size_type i = newSize; i < arraySize; ++i) + { + std::allocator_traits::destroy(allocator, &_data[i]); + } + } + else + { + // Or construct the new elements by default + for(size_type i = arraySize; i < newSize; ++i) + { + std::allocator_traits::construct(allocator, &_data[i], std::move(value)); + } + } + arraySize = newSize; + } + else + { + // The array is not big enough, so we make a new one + T *newData = allocateArray(newSize); - using iterator = IteratorBase; - using const_iterator = IteratorBase; + // And move the current elements into that one + for(size_type i = 0; i < arraySize; ++i) + { + newData[i] = std::forward(_data[i]); + } + // As well as default initialize the others + for(size_type i = arraySize; i < newSize; ++i) + { + std::allocator_traits::construct(allocator, &_data[i], std::move(value)); + } + deallocateArray(_data, allocated); + arraySize = newSize; + allocated = newSize; + _data = newData; + } + markIteratorDirty(); + } + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int) + { + ar & arraySize; + resize(arraySize); + for(size_type i = 0; i < arraySize; ++i) + ar & _data[i]; + markIteratorDirty(); + } + size_type arraySize = 0; + size_type allocated = 0; + Iterator beginIt; + Iterator endIt; + T *_data = nullptr; + allocator_type allocator; + }; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; + template + struct StaticArray + { + public: + template + class IteratorBase + { + public: + using iterator_category = std::random_access_iterator_tag; + using value_type = X; + using difference_type = std::ptrdiff_t; + using reference = X&; + using pointer = X*; - StaticArray() - { - beginIt = iterator(_data); - endIt = iterator(_data + N); - } - StaticArray(T value) - { - for (int i = 0; i < N; ++i) - { - _data[i] = value; - } - beginIt = iterator(_data); - endIt = iterator(_data + N); - } - ~StaticArray() - { - } - - inline size_type size() const - { - return N; - } - inline pointer data() - { - return _data; - } - inline const_pointer data() const - { - return _data; - } - constexpr reference operator[](size_type index) noexcept - { - assert(index < N); - return _data[index]; - } - constexpr const_reference operator[](size_type index) const noexcept - { - assert(index < N); - return _data[index]; - } - iterator begin() - { - return beginIt; - } - iterator end() - { - return endIt; - } - const_iterator begin() const - { - return beginIt; - } - const_iterator end() const - { - return beginIt; - } - private: - T _data[N]; - iterator beginIt; - iterator endIt; - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & version; - ar & N; - ar & _data; - } - }; + IteratorBase(X *x = nullptr) + : p(x) + { + } + reference operator*() const + { + return *p; + } + pointer operator->() const + { + return p; + } + inline bool operator!=(const IteratorBase &other) + { + return p != other.p; + } + inline bool operator==(const IteratorBase &other) + { + return p == other.p; + } + IteratorBase &operator++() + { + p++; + return *this; + } + IteratorBase operator++(int) + { + IteratorBase tmp(*this); + ++*this; + return tmp; + } + IteratorBase &operator--() + { + p--; + return *this; + } + IteratorBase operator--(int) + { + IteratorBase tmp(*this); + --*this; + return tmp; + } + + + private: + X *p; + }; + using value_type = T; + using size_type = size_t; + using difference_type = std::ptrdiff_t; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + + using iterator = IteratorBase; + using const_iterator = IteratorBase; + + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + StaticArray() + { + beginIt = iterator(_data); + endIt = iterator(_data + N); + } + StaticArray(T value) + { + for (int i = 0; i < N; ++i) + { + _data[i] = value; + } + beginIt = iterator(_data); + endIt = iterator(_data + N); + } + ~StaticArray() + { + } + + inline size_type size() const + { + return N; + } + inline pointer data() + { + return _data; + } + inline const_pointer data() const + { + return _data; + } + constexpr reference operator[](size_type index) noexcept + { + assert(index < N); + return _data[index]; + } + constexpr const_reference operator[](size_type index) const noexcept + { + assert(index < N); + return _data[index]; + } + iterator begin() + { + return beginIt; + } + iterator end() + { + return endIt; + } + const_iterator begin() const + { + return beginIt; + } + const_iterator end() const + { + return beginIt; + } + private: + T _data[N]; + iterator beginIt; + iterator endIt; + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) + { + ar & version; + ar & N; + ar & _data; + } + }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Containers/List.h b/src/Engine/Containers/List.h index 30db0ae..354268b 100644 --- a/src/Engine/Containers/List.h +++ b/src/Engine/Containers/List.h @@ -1,337 +1,373 @@ #pragma once #include "MinimalEngine.h" +#include + namespace Seele { -template +template > class List { private: - struct Node - { - Node *prev; - Node *next; - T data; - }; + struct Node + { + Node *prev; + Node *next; + T data; + }; + using NodeAllocator = std::allocator_traits::template rebind_alloc; public: - List() - { - root = nullptr; - tail = nullptr; - beginIt = Iterator(root); - endIt = Iterator(tail); - _size = 0; - } - List(const List& other) - { - //TODO: improve - for(const auto& it : other) - { - add(it); - } - } - List(List&& other) - : root(std::move(other.root)) - , tail(std::move(other.tail)) - , beginIt(std::move(other.beginIt)) - , endIt(std::move(other.endIt)) - , _size(std::move(other._size)) - { - other._size = 0; - } - ~List() - { - clear(); - } - List& operator=(const List& other) - { - if(this != &other) - { - if(root != nullptr) - { - delete root; - } - if(tail != nullptr) - { - delete tail; - } - _size = 0; - for(const auto& it : other) - { - add(it); - } - } - return *this; - } - List& operator=(List&& other) - { - if(this != &other) - { - if(root != nullptr) - { - clear(); - } - root = other.root; - tail = other.tail; - beginIt = other.beginIt; - endIt = other.endIt; - _size = other._size; - other._size = 0; - } - return *this; - } - template - class IteratorBase - { - public: - typedef std::forward_iterator_tag iterator_category; - typedef X value_type; - typedef std::ptrdiff_t difference_type; - typedef X &reference; - typedef X *pointer; + template + class IteratorBase + { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = X; + using difference_type = std::ptrdiff_t; + using reference = X&; + using pointer = X*; - IteratorBase(Node *x = nullptr) - : node(x) - { - } - IteratorBase(const IteratorBase &i) - : node(i.node) - { - } - IteratorBase(IteratorBase&& i) - : node(std::move(i.node)) - { - } - ~IteratorBase() - { - } - IteratorBase& operator=(const IteratorBase& other) - { - if(this != &other) - { - node = other.node; - } - return *this; - } - IteratorBase& operator=(IteratorBase&& other) - { - if(this != &other) - { - node = std::move(other.node); - } - return *this; - } - reference operator*() const - { - return node->data; - } - pointer operator->() const - { - return &node->data; - } - inline bool operator!=(const IteratorBase &other) - { - return node != other.node; - } - inline bool operator==(const IteratorBase &other) - { - return node == other.node; - } - IteratorBase &operator--() - { - node = node->prev; - return *this; - } - IteratorBase operator--(int) - { - IteratorBase tmp(*this); - --*this; - return tmp; - } - IteratorBase &operator++() - { - node = node->next; - return *this; - } - IteratorBase operator++(int) - { - IteratorBase tmp(*this); - ++*this; - return tmp; - } + IteratorBase(Node *x = nullptr) + : node(x) + { + } + IteratorBase(const IteratorBase &i) + : node(i.node) + { + } + IteratorBase(IteratorBase&& i) + : node(std::move(i.node)) + { + } + ~IteratorBase() + { + } + IteratorBase& operator=(const IteratorBase& other) + { + if(this != &other) + { + node = other.node; + } + return *this; + } + IteratorBase& operator=(IteratorBase&& other) + { + if(this != &other) + { + node = std::move(other.node); + } + return *this; + } + reference operator*() const + { + return node->data; + } + pointer operator->() const + { + return &node->data; + } + inline bool operator!=(const IteratorBase &other) + { + return node != other.node; + } + inline bool operator==(const IteratorBase &other) + { + return node == other.node; + } + IteratorBase &operator--() + { + node = node->prev; + return *this; + } + IteratorBase operator--(int) + { + IteratorBase tmp(*this); + --*this; + return tmp; + } + IteratorBase &operator++() + { + node = node->next; + return *this; + } + IteratorBase operator++(int) + { + IteratorBase tmp(*this); + ++*this; + return tmp; + } - private: - Node *node; - friend class List; - }; - typedef IteratorBase Iterator; - typedef IteratorBase ConstIterator; + private: + Node *node; + friend class List; + }; + + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; + + using value_type = T; + 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 = T*; + using const_pointer = const T*; - T &front() - { - return root->data; - } - T &back() - { - return tail->prev->data; - } - void clear() - { - if (empty()) - { - return; - } - for (Node *tmp = root; tmp != tail;) - { - tmp = tmp->next; - delete tmp->prev; - } - delete tail; - tail = nullptr; - root = nullptr; - } - //Insert at the end - Iterator add(const T &value) - { - if (root == nullptr) - { - root = new Node(); - tail = root; - } - tail->data = value; - Node *newTail = new Node(); - newTail->prev = tail; - newTail->next = nullptr; - tail->next = newTail; - Iterator insertedElement(tail); - tail = newTail; - markIteratorDirty(); - _size++; - return insertedElement; - } - Iterator add(T&& value) - { - if (root == nullptr) - { - root = new Node(); - tail = root; - } - tail->data = std::move(value); - Node *newTail = new Node(); - newTail->prev = tail; - newTail->next = nullptr; - tail->next = newTail; - Iterator insertedElement(tail); - tail = newTail; - markIteratorDirty(); - _size++; - return insertedElement; - } - Iterator remove(Iterator pos) - { - _size--; - Node *prev = pos.node->prev; - Node *next = pos.node->next; - if (prev == nullptr) - { - root = next; - } - else - { - prev->next = next; - } - if(next == nullptr) - { - root = prev; - } - else - { - next->prev = prev; - } - delete pos.node; - markIteratorDirty(); - return Iterator(next); - } - void popBack() - { - assert(_size > 0); - remove(Iterator(tail->prev)); - } - void popFront() - { - assert(_size > 0); - remove(Iterator(root)); - } - Iterator insert(Iterator pos, const T &value) - { - _size++; - if (root == nullptr) - { - root = new Node(); - root->data = value; - tail = new Node(); - root->next = tail; - root->prev = nullptr; - tail->prev = root; - tail->next = nullptr; - markIteratorDirty(); - return beginIt; - } - Node *tmp = pos.node->prev; - Node *newNode = new Node(); - newNode->data = value; - tmp->next = newNode; - newNode->prev = tmp; - newNode->next = pos.node; - pos.node->prev = newNode; - return Iterator(newNode); - } - Iterator find(const T &value) - { - for (Node *i = root; i != tail; i = i->next) - { - if (!(i->data < value) && !(value < i->data)) - { - return Iterator(i); - } - } - return endIt; - } - bool empty() - { - return _size == 0; - } - uint32 size() - { - return _size; - } - Iterator begin() - { - return beginIt; - } - const Iterator begin() const - { - return beginIt; - } - Iterator end() - { - return endIt; - } - const Iterator end() const - { - return endIt; - } + using iterator = Iterator; + using const_iterator = ConstIterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + List() + : root(nullptr) + , tail(nullptr) + , beginIt(Iterator(root)) + , endIt(Iterator(tail)) + , _size(0) + , allocator(NodeAllocator()) + { + } + List(const List& other) + { + //TODO: improve + for(const auto& it : other) + { + add(it); + } + } + List(List&& other) + : root(std::move(other.root)) + , tail(std::move(other.tail)) + , beginIt(std::move(other.beginIt)) + , endIt(std::move(other.endIt)) + , _size(std::move(other._size)) + { + other._size = 0; + } + ~List() + { + clear(); + } + List& operator=(const List& other) + { + if(this != &other) + { + if(root != nullptr) + { + delete root; + } + if(tail != nullptr) + { + delete tail; + } + _size = 0; + for(const auto& it : other) + { + add(it); + } + } + return *this; + } + List& operator=(List&& other) + { + if(this != &other) + { + if(root != nullptr) + { + clear(); + } + root = other.root; + tail = other.tail; + beginIt = other.beginIt; + endIt = other.endIt; + _size = other._size; + other._size = 0; + } + return *this; + } + + T &front() + { + return root->data; + } + T &back() + { + return tail->prev->data; + } + void clear() + { + if (empty()) + { + return; + } + for (Node *tmp = root; tmp != tail;) + { + tmp = tmp->next; + deallocateNode(tmp->prev); + } + deallocateNode(tail); + tail = nullptr; + root = nullptr; + } + //Insert at the end + iterator add(const T &value) + { + if (root == nullptr) + { + root = allocateNode(); + tail = root; + } + tail->data = value; + Node *newTail = allocateNode(); + newTail->prev = tail; + newTail->next = nullptr; + tail->next = newTail; + iterator insertedElement(tail); + tail = newTail; + markIteratorDirty(); + _size++; + return insertedElement; + } + iterator add(T&& value) + { + if (root == nullptr) + { + root = allocateNode(); + tail = root; + } + tail->data = std::move(value); + Node *newTail = allocateNode(); + newTail->prev = tail; + newTail->next = nullptr; + tail->next = newTail; + Iterator insertedElement(tail); + tail = newTail; + markIteratorDirty(); + _size++; + return insertedElement; + } + iterator remove(iterator pos) + { + _size--; + Node *prev = pos.node->prev; + Node *next = pos.node->next; + if (prev == nullptr) + { + root = next; + } + else + { + prev->next = next; + } + if(next == nullptr) + { + root = prev; + } + else + { + next->prev = prev; + } + delete pos.node; + markIteratorDirty(); + return Iterator(next); + } + void popBack() + { + assert(_size > 0); + remove(Iterator(tail->prev)); + } + void popFront() + { + assert(_size > 0); + remove(Iterator(root)); + } + iterator insert(iterator pos, const T &value) + { + _size++; + if (root == nullptr) + { + root = allocateNode(); + root->data = value; + tail = allocateNode(); + root->next = tail; + root->prev = nullptr; + tail->prev = root; + tail->next = nullptr; + markIteratorDirty(); + return beginIt; + } + Node *tmp = pos.node->prev; + Node *newNode = allocateNode(); + newNode->data = value; + tmp->next = newNode; + newNode->prev = tmp; + newNode->next = pos.node; + pos.node->prev = newNode; + return Iterator(newNode); + } + iterator find(const T &value) + { + for (Node *i = root; i != tail; i = i->next) + { + if (!(i->data < value) && !(value < i->data)) + { + return iterator(i); + } + } + return endIt; + } + bool empty() + { + return _size == 0; + } + size_type size() + { + return _size; + } + iterator begin() + { + return beginIt; + } + const_iterator begin() const + { + return cbeginIt; + } + iterator end() + { + return endIt; + } + const_iterator end() const + { + return cendIt; + } private: - void markIteratorDirty() - { - beginIt = Iterator(root); - endIt = Iterator(tail); - } - Node *root; - Node *tail; - Iterator beginIt; - Iterator endIt; - uint32 _size; + Node* allocateNode() + { + Node* node = allocator.allocate(1); + std::memset(node, 0, sizeof(Node)); + assert(node != nullptr); + return node; + } + void deallocateNode(Node* node) + { + allocator.deallocate(node, 1); + } + void markIteratorDirty() + { + beginIt = Iterator(root); + endIt = Iterator(tail); + cbeginIt = ConstIterator(root); + cendIt = ConstIterator(tail); + } + Node *root; + Node *tail; + Iterator beginIt; + Iterator endIt; + ConstIterator cbeginIt; + ConstIterator cendIt; + uint32 _size; + NodeAllocator allocator; }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h index 9578fa5..54e2888 100644 --- a/src/Engine/Containers/Map.h +++ b/src/Engine/Containers/Map.h @@ -171,7 +171,7 @@ public: using pointer = Pair*; Iterator(Node *x = nullptr) - : node(x), traversal(Init_t::NO_INIT) + : node(x) { } Iterator(Node *x, Array &&beginIt) diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp index b24e5db..90b1d57 100644 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ b/src/Engine/Graphics/GraphicsResources.cpp @@ -70,13 +70,9 @@ ShaderCollection& ShaderMap::createShaders( modifyRenderPassMacros(renderPass, createInfo.defines); createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName(); - std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass), std::ios::ate); - auto fileSize = codeStream.tellg(); - codeStream.seekg(0); - Array buffer(static_cast(fileSize)); - codeStream.read(buffer.data(), fileSize); - - createInfo.shaderCode.add(std::string(buffer.data(), 0, fileSize)); + std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass)); + + createInfo.shaderCode.add(std::string(std::istreambuf_iterator{codeStream}, {})); collection.vertexShader = graphics->createVertexShader(createInfo); diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 60cf520..73e7cd0 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -2,27 +2,28 @@ #include "Containers/Map.h" #include "EngineTypes.h" #include "Math/Math.h" +//#include "ThreadPool.h" #define DEFINE_REF(x) \ - typedef RefPtr P##x; \ - typedef UniquePtr UP##x; \ - typedef WeakPtr W##x; + typedef RefPtr P##x; \ + typedef UniquePtr UP##x; \ + typedef WeakPtr W##x; #define DECLARE_REF(x) \ - class x; \ - typedef RefPtr P##x; \ - typedef UniquePtr UP##x; \ - typedef WeakPtr W##x; + class x; \ + typedef RefPtr P##x; \ + typedef UniquePtr UP##x; \ + typedef WeakPtr W##x; #define DECLARE_NAME_REF(nmsp, x) \ - namespace nmsp \ - { \ - class x; \ - typedef RefPtr P##x; \ - typedef UniquePtr UP##x; \ - typedef WeakPtr W##x; \ - } + namespace nmsp \ + { \ + class x; \ + typedef RefPtr P##x; \ + typedef UniquePtr UP##x; \ + typedef WeakPtr W##x; \ + } extern Seele::Map registeredObjects; extern std::mutex registeredObjectsLock; @@ -34,332 +35,332 @@ template class RefObject { public: - RefObject(T *ptr) - : handle(ptr), refCount(1) - { - registeredObjects[ptr] = this; - } - inline RefObject(const RefObject &rhs) - : handle(rhs.handle), refCount(rhs.refCount) - { - } - RefObject(RefObject &&rhs) - : handle(std::move(rhs.handle)), refCount(std::move(rhs.refCount)) - { - } - ~RefObject() - { - { - std::unique_lock lock(registeredObjectsLock); - registeredObjects.erase(handle); - } - #pragma warning( disable: 4150) - delete handle; - #pragma warning( default: 4150) - } - RefObject &operator=(const RefObject &rhs) - { - if (*this != rhs) - { - handle = rhs.handle; - refCount = rhs.refCount; - } - return *this; - } - RefObject &operator=(RefObject &&rhs) - { - if (*this != rhs) - { - handle = std::move(rhs.handle); - refCount = std::move(rhs.refCount); - rhs.handle = nullptr; - rhs.refCount = 0; - } - return *this; - } - inline bool operator==(const RefObject &other) const - { - return handle == other.handle; - } - inline bool operator!=(const RefObject &other) const - { - return handle != other.handle; - } - inline bool operator<(const RefObject &other) const - { - return handle < other.handle; - } - void addRef() - { - refCount++; - } - inline void removeRef() - { - refCount--; - if (refCount == 0) - { - delete this; - } - } - T *getHandle() const - { - return handle; - } + RefObject(T *ptr) + : handle(ptr), refCount(1) + { + registeredObjects[ptr] = this; + } + inline RefObject(const RefObject &rhs) + : handle(rhs.handle), refCount(rhs.refCount) + { + } + RefObject(RefObject &&rhs) + : handle(std::move(rhs.handle)), refCount(std::move(rhs.refCount)) + { + } + ~RefObject() + { + { + std::unique_lock lock(registeredObjectsLock); + registeredObjects.erase(handle); + } + #pragma warning( disable: 4150) + delete handle; + #pragma warning( default: 4150) + } + RefObject &operator=(const RefObject &rhs) + { + if (*this != rhs) + { + handle = rhs.handle; + refCount = rhs.refCount; + } + return *this; + } + RefObject &operator=(RefObject &&rhs) + { + if (*this != rhs) + { + handle = std::move(rhs.handle); + refCount = std::move(rhs.refCount); + rhs.handle = nullptr; + rhs.refCount = 0; + } + return *this; + } + inline bool operator==(const RefObject &other) const + { + return handle == other.handle; + } + inline bool operator!=(const RefObject &other) const + { + return handle != other.handle; + } + inline bool operator<(const RefObject &other) const + { + return handle < other.handle; + } + void addRef() + { + refCount++; + } + inline void removeRef() + { + refCount--; + if (refCount == 0) + { + delete this; + } + } + T *getHandle() const + { + return handle; + } private: - T *handle; - std::atomic_uint64_t refCount; - friend class RefPtr; + T *handle; + std::atomic_uint64_t refCount; + friend class RefPtr; }; template class RefPtr { public: - RefPtr() - { - object = nullptr; - } - RefPtr(nullptr_t) - { - object = nullptr; - } - RefPtr(T *ptr) - { - std::unique_lock l(registeredObjectsLock); - auto registeredObj = registeredObjects.find(ptr); - // get here for thread safetly - auto registeredEnd = registeredObjects.end(); - if (registeredObj == registeredEnd) - { - object = new RefObject(ptr); - l.unlock(); - } - else - { - l.unlock(); - object = (RefObject *)registeredObj->value; - object->addRef(); - } - } - explicit RefPtr(RefObject *other) - : object(other) - { - object->addRef(); - } - inline RefPtr(const RefPtr &other) - : object(other.object) - { - if (object != nullptr) - { - object->addRef(); - } - } - RefPtr(RefPtr &&rhs) - : object(std::move(rhs.object)) - { - rhs.object = nullptr; - //Dont change references, they stay the same - } - template - RefPtr(const RefPtr &other) - { - F *f = other.getObject()->getHandle(); - assert(static_cast(f)); - object = (RefObject *)other.getObject(); - object->addRef(); - } + RefPtr() + { + object = nullptr; + } + RefPtr(nullptr_t) + { + object = nullptr; + } + RefPtr(T *ptr) + { + std::unique_lock l(registeredObjectsLock); + auto registeredObj = registeredObjects.find(ptr); + // get here for thread safetly + auto registeredEnd = registeredObjects.end(); + if (registeredObj == registeredEnd) + { + object = new RefObject(ptr); + l.unlock(); + } + else + { + l.unlock(); + object = (RefObject *)registeredObj->value; + object->addRef(); + } + } + explicit RefPtr(RefObject *other) + : object(other) + { + object->addRef(); + } + inline RefPtr(const RefPtr &other) + : object(other.object) + { + if (object != nullptr) + { + object->addRef(); + } + } + RefPtr(RefPtr &&rhs) + : object(std::move(rhs.object)) + { + rhs.object = nullptr; + //Dont change references, they stay the same + } + template + RefPtr(const RefPtr &other) + { + F *f = other.getObject()->getHandle(); + assert(static_cast(f)); + object = (RefObject *)other.getObject(); + object->addRef(); + } - template - RefPtr cast() - { - T *t = object->getHandle(); - F *f = dynamic_cast(t); - if (f == nullptr) - { - return nullptr; - } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); - } + template + RefPtr cast() + { + T *t = object->getHandle(); + F *f = dynamic_cast(t); + if (f == nullptr) + { + return nullptr; + } + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); + } - template - const RefPtr cast() const - { - T *t = object->getHandle(); - F *f = dynamic_cast(t); - if (f == nullptr) - { - return nullptr; - } - RefObject *newObject = (RefObject *)object; - return RefPtr(newObject); - } + template + const RefPtr cast() const + { + T *t = object->getHandle(); + F *f = dynamic_cast(t); + if (f == nullptr) + { + return nullptr; + } + RefObject *newObject = (RefObject *)object; + return RefPtr(newObject); + } - RefPtr &operator=(const RefPtr &other) - { - if (*this != other) - { - if (object != nullptr) - { - object->removeRef(); - } - object = other.object; - if (object != nullptr) - { - object->addRef(); - } - } - return *this; - } - RefPtr &operator=(RefPtr &&rhs) - { - if (*this != rhs) - { - if (object != nullptr) - { - object->removeRef(); - } - object = std::move(rhs.object); - rhs.object = nullptr; - } - return *this; - } - ~RefPtr() - { - if (object != nullptr) - { - object->removeRef(); - } - } - inline bool operator==(const RefPtr &other) const - { - return object == other.object; - } - inline bool operator!=(const RefPtr &other) const - { - return object != other.object; - } - bool operator<(const RefPtr &other) const - { - return object < other.object; - } - inline T *operator->() - { - assert(object != nullptr); - return object->handle; - } - inline const T *operator->() const - { - assert(object != nullptr); - return object->handle; - } - RefObject *getObject() const - { - return object; - } - inline T *getHandle() - { - return object->getHandle(); - } - inline const T *getHandle() const - { - return object->getHandle(); - } + RefPtr &operator=(const RefPtr &other) + { + if (this != &other) + { + if (object != nullptr) + { + object->removeRef(); + } + object = other.object; + if (object != nullptr) + { + object->addRef(); + } + } + return *this; + } + RefPtr &operator=(RefPtr &&rhs) + { + if (this != &rhs) + { + if (object != nullptr) + { + object->removeRef(); + } + object = std::move(rhs.object); + rhs.object = nullptr; + } + return *this; + } + ~RefPtr() + { + if (object != nullptr) + { + object->removeRef(); + } + } + inline bool operator==(const RefPtr &other) const + { + return object == other.object; + } + inline bool operator!=(const RefPtr &other) const + { + return object != other.object; + } + bool operator<(const RefPtr &other) const + { + return object < other.object; + } + inline T *operator->() + { + assert(object != nullptr); + return object->handle; + } + inline const T *operator->() const + { + assert(object != nullptr); + return object->handle; + } + RefObject *getObject() const + { + return object; + } + inline T *getHandle() + { + return object->getHandle(); + } + inline const T *getHandle() const + { + return object->getHandle(); + } private: - RefObject *object; - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int) - { - ar & *object->getHandle(); - } + RefObject *object; + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int) + { + ar & *object->getHandle(); + } }; template class UniquePtr { public: - UniquePtr() - : handle(nullptr) - { - } - UniquePtr(nullptr_t) - : handle(nullptr) - { - } - UniquePtr(T *ptr) - : handle(ptr) - { - } - UniquePtr(const UniquePtr &rhs) = delete; - UniquePtr(UniquePtr &&rhs) noexcept - : handle(rhs.handle) - { - rhs.handle = nullptr; - } - UniquePtr &operator=(const UniquePtr &rhs) = delete; - UniquePtr &operator=(UniquePtr &&rhs) - { - handle = rhs.handle; - rhs.handle = nullptr; - return *this; - } - ~UniquePtr() - { - delete handle; - } - inline bool operator==(const UniquePtr &other) const - { - return handle == other.handle; - } - inline bool operator!=(const UniquePtr &other) const - { - return handle != other.handle; - } - inline T *operator->() - { - return handle; - } - bool isValid() - { - return handle != nullptr; - } + UniquePtr() + : handle(nullptr) + { + } + UniquePtr(nullptr_t) + : handle(nullptr) + { + } + UniquePtr(T *ptr) + : handle(ptr) + { + } + UniquePtr(const UniquePtr &rhs) = delete; + UniquePtr(UniquePtr &&rhs) noexcept + : handle(rhs.handle) + { + rhs.handle = nullptr; + } + UniquePtr &operator=(const UniquePtr &rhs) = delete; + UniquePtr &operator=(UniquePtr &&rhs) + { + handle = rhs.handle; + rhs.handle = nullptr; + return *this; + } + ~UniquePtr() + { + delete handle; + } + inline bool operator==(const UniquePtr &other) const + { + return handle == other.handle; + } + inline bool operator!=(const UniquePtr &other) const + { + return handle != other.handle; + } + inline T *operator->() + { + return handle; + } + bool isValid() + { + return handle != nullptr; + } private: - T *handle; - friend class boost::serialization::access; - template - void serialize(Archive& ar, const unsigned int version) - { - ar & *handle; - } + T *handle; + friend class boost::serialization::access; + template + void serialize(Archive& ar, const unsigned int version) + { + ar & *handle; + } }; //A weak pointer has no ownership over an object and thus cant delete it template class WeakPtr { public: - WeakPtr() - : pointer(nullptr) - { - } - WeakPtr(RefPtr &sharedPtr) - : pointer(sharedPtr) - { - } - WeakPtr &operator=(WeakPtr &weakPtr) - { - pointer = weakPtr.pointer; - return *this; - } - WeakPtr &operator=(RefPtr &sharedPtr) - { - pointer = sharedPtr; - return *this; - } + WeakPtr() + : pointer(nullptr) + { + } + WeakPtr(RefPtr &sharedPtr) + : pointer(sharedPtr) + { + } + WeakPtr &operator=(WeakPtr &weakPtr) + { + pointer = weakPtr.pointer; + return *this; + } + WeakPtr &operator=(RefPtr &sharedPtr) + { + pointer = sharedPtr; + return *this; + } private: - RefPtr pointer; + RefPtr pointer; }; } // namespace Seele diff --git a/src/Engine/Scene/SceneUpdater.h b/src/Engine/Scene/SceneUpdater.h index a1034ea..948c9e7 100644 --- a/src/Engine/Scene/SceneUpdater.h +++ b/src/Engine/Scene/SceneUpdater.h @@ -1,4 +1,5 @@ #pragma once +#include "MinimalEngine.h" #include "Containers/List.h" #include diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index c43b38f..e4967ac 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -2,7 +2,11 @@ using namespace Seele; -static ThreadPool gThreadPool; + +void Event::await_suspend(std::coroutine_handle h) +{ + getGlobalThreadPool().addJob(Job(h)); +} Job JobPromise::get_return_object() noexcept { return Job { std::coroutine_handle::from_promise(*this) }; @@ -14,7 +18,16 @@ ThreadPool::ThreadPool(uint32 threadCount) } -static ThreadPool& getGlobalThreadPool() +ThreadPool::~ThreadPool() { - return gThreadPool; + for(auto& thread : workers) + { + thread.join(); + } +} + +ThreadPool& Seele::getGlobalThreadPool() +{ + static ThreadPool threadPool; + return threadPool; } \ No newline at end of file diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 5ff03b5..aadd369 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -1,23 +1,35 @@ #pragma once #include #include -#include "MinimalEngine.h" +#include "Containers/List.h" namespace Seele { -enum class JobStage +struct JobPromise; +struct Event { - INPUT, - GAMELOGIC, - RENDER, - DONT_CARE +public: + void raise() + { + flag.test_and_set(); + flag.notify_all(); + } + void reset() + { + flag.clear(); + } + bool await_ready() { return flag.test(); } + void await_suspend(std::coroutine_handle h); + void await_resume() {} +private: + std::atomic_flag flag; }; struct [[nodiscard]] Job; struct JobPromise { Job get_return_object() noexcept; - std::suspend_never initial_suspend() const noexcept { return {}; } + std::suspend_always initial_suspend() const noexcept { return {}; } std::suspend_never final_suspend() const noexcept { return {}; } void return_void() noexcept {} @@ -31,9 +43,8 @@ struct [[nodiscard]] Job public: using promise_type = JobPromise; - explicit Job(std::coroutine_handle handle, JobStage stage = JobStage::DONT_CARE) + explicit Job(std::coroutine_handle handle) : handle(handle) - , stage(stage) {} ~Job() { @@ -44,22 +55,21 @@ public: } private: std::coroutine_handle handle; - JobStage stage; }; class ThreadPool { public: - ThreadPool(uint32 threadCount = std::thread::hardware_concurrency); + ThreadPool(uint32 threadCount = std::thread::hardware_concurrency()); virtual ~ThreadPool(); - void schedule(std::function function) + void addJob(Job&& job) { - + jobs.add(std::move(job)); } private: - Array workers; - Map> jobs; + std::vector workers; + List jobs; void threadLoop(); }; -static ThreadPool& getGlobalThreadPool(); +extern ThreadPool& getGlobalThreadPool(); } // namespace Seele diff --git a/src/Engine/Window/Window.cpp b/src/Engine/Window/Window.cpp index f9c3f12..e13bd7f 100644 --- a/src/Engine/Window/Window.cpp +++ b/src/Engine/Window/Window.cpp @@ -16,7 +16,7 @@ void Window::addView(PView view) { WindowView* windowView = new WindowView(); windowView->view = view; - windowView->worker = std::thread(&Window::viewWorker, this, windowView); + //windowView->worker = std::thread(&Window::viewWorker, this, windowView); views.add(windowView); } @@ -24,11 +24,19 @@ void Window::render() { gfxHandle->beginFrame(); for(auto& windowView : views) - { + { windowView->view->beginUpdate(); windowView->view->update(); - windowView->view->commitUpdate(); - windowView->view->prepareRender(); + { + std::unique_lock lock(windowView->workerMutex); + windowView->view->commitUpdate(); + } + windowView->updateFinished.raise(); + { + std::unique_lock lock(windowView->workerMutex); + windowView->view->prepareRender(); + } + windowView->updateFinished.reset(); windowView->view->render(); } gfxHandle->endFrame(); diff --git a/src/Engine/Window/Window.h b/src/Engine/Window/Window.h index c7c0fbb..67d906d 100644 --- a/src/Engine/Window/Window.h +++ b/src/Engine/Window/Window.h @@ -1,12 +1,14 @@ #pragma once #include "Graphics/GraphicsResources.h" #include "View.h" +#include "ThreadPool.h" namespace Seele { struct WindowView { PView view; + Event updateFinished; std::thread worker; std::mutex workerMutex; }; diff --git a/src/Engine/Window/WindowManager.cpp b/src/Engine/Window/WindowManager.cpp index 5a30ec5..58ba69a 100644 --- a/src/Engine/Window/WindowManager.cpp +++ b/src/Engine/Window/WindowManager.cpp @@ -35,12 +35,3 @@ PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo) windows.add(window); return window; } - -void WindowManager::render() -{ - for(auto window : windows) - { - window->render(); - } -} - diff --git a/src/Engine/Window/WindowManager.h b/src/Engine/Window/WindowManager.h index 823637a..68cb27d 100644 --- a/src/Engine/Window/WindowManager.h +++ b/src/Engine/Window/WindowManager.h @@ -12,7 +12,6 @@ public: WindowManager(); ~WindowManager(); PWindow addWindow(const WindowCreateInfo &createInfo); - void render(); static Gfx::PGraphics getGraphics() { return graphics; diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index 2444ca7..0daa6f0 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -34,9 +34,9 @@ int main() PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo); window->addView(inspectorView); sceneView->setFocused(); - while (windowManager->isActive()) + while(true) { - windowManager->render(); + window->render(); } return 0; } \ No newline at end of file