diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 25bdc19..2e584a5 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,5 +1,6 @@ # engine add_subdirectory(./base) +add_subdirectory(./memory) add_subdirectory(./time) add_subdirectory(./logger) add_subdirectory(./debug) @@ -14,7 +15,7 @@ add_subdirectory(./input) # add_subdirectory(./ui) # add_subdirectory(./surface) -# add_subdirectory(./renderer) +add_subdirectory(./renderer) add_subdirectory(./ecs) # add_subdirectory(./app) diff --git a/modules/memory/CMakeLists.txt b/modules/memory/CMakeLists.txt new file mode 100644 index 0000000..dded065 --- /dev/null +++ b/modules/memory/CMakeLists.txt @@ -0,0 +1 @@ +add_library_module(memory) diff --git a/modules/memory/public/pointer_types/null_on_move.hpp b/modules/memory/public/pointer_types/null_on_move.hpp new file mode 100644 index 0000000..9cda10e --- /dev/null +++ b/modules/memory/public/pointer_types/null_on_move.hpp @@ -0,0 +1,73 @@ +#pragma once + +namespace lt::memory { + +/** Holds an `Underlying_T`, assigns it to `null_value` when this object is moved. + * + * @note For avoiding the need to explicitly implement the move constructor for objects that hold + * Vulkan objects. But may server other purposes, hence why I kept the implementation generic. + */ +template +class NullOnMove +{ +public: + NullOnMove() = default; + + NullOnMove(Underlying_T value): m_value(value) + { + } + + ~NullOnMove() = default; + + NullOnMove(const NullOnMove &) = delete; + + auto operator=(const NullOnMove &) -> NullOnMove & = delete; + + NullOnMove(NullOnMove &&other) noexcept + { + *this = std::move(other); + } + + auto operator=(NullOnMove &&other) noexcept -> NullOnMove & + { + if (this->m_value == other.m_value) + { + return *this; + } + + m_value = other.m_value; + other.m_value = null_value; + + return *this; + } + + auto operator&() const -> const Underlying_T * + { + return &m_value; + } + + auto operator&() -> Underlying_T * + { + return &m_value; + } + + operator bool() const + { + return m_value != null_value; + } + + operator Underlying_T() const + { + return m_value; + } + + operator Underlying_T() + { + return m_value; + } + +private: + Underlying_T m_value; +}; + +} // namespace lt::memory diff --git a/modules/memory/public/pointer_types/reference.hpp b/modules/memory/public/pointer_types/reference.hpp new file mode 100644 index 0000000..6c1665a --- /dev/null +++ b/modules/memory/public/pointer_types/reference.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace lt::memory { + +/** Wrapper around std::shared_ptr. */ +template +using Ref = std::shared_ptr; + +/** Allocates memory for an `Underlying_T` and directly constructs it there. + * + * @return A Ref to the constructed object. + */ +template +constexpr Ref create_ref(Args &&...args) +{ + return std::make_shared(std::forward(args)...); +} + +/** Converts c-style pointer of type `Underlying_T` to a `Ref`. */ +template +constexpr Ref make_ref(Underlying_T *raw_pointer) +{ + return Ref(raw_pointer); +} + +} // namespace lt::memory diff --git a/modules/memory/public/pointer_types/scoped.hpp b/modules/memory/public/pointer_types/scoped.hpp new file mode 100644 index 0000000..8a0eb5a --- /dev/null +++ b/modules/memory/public/pointer_types/scoped.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace lt::memory { + +/** Wrapper around std::unique_ptr. */ +template +using Scope = std::unique_ptr; + +/** Allocates memory for an `Underlying_T` and directly constructs it there. + * + * @return A Scope to the constructed object. + */ +template +constexpr Scope create_scope(Args &&...args) +{ + return std::make_unique(std::forward(args)...); +} + +/** Converts c-style pointer of type `Underlying_T` to a `Scope`. */ +template +constexpr Scope make_scope(Underlying_T *raw_pointer) +{ + return Scope(raw_pointer); +} + +} // namespace lt::memory