- A few Vulkan wrapper structs
- Framework for Vulkan context - Fixed a bug with dynarray where if `resize()` shrinks the array, destructors are not called. - Fixed grammar issues with the containers library and added property tables to existing data structures.
This commit is contained in:
@@ -82,7 +82,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}
|
||||
|
||||
# Core Files
|
||||
fennec_add_sources(
|
||||
# CORE =================================================================================================================
|
||||
# CORE =================================================================================================================
|
||||
include/fennec/core/engine.h source/core/engine.cpp
|
||||
include/fennec/core/event.h source/core/event.cpp
|
||||
include/fennec/core/logger.h source/core/logger.cpp
|
||||
@@ -91,7 +91,7 @@ fennec_add_sources(
|
||||
include/fennec/core/system.h
|
||||
|
||||
|
||||
# SCENE ================================================================================================================
|
||||
# SCENE ================================================================================================================
|
||||
include/fennec/scene/scene.h source/scene/scene.cpp
|
||||
include/fennec/scene/component.h
|
||||
include/fennec/scene/scene_node.h
|
||||
@@ -100,15 +100,14 @@ fennec_add_sources(
|
||||
|
||||
|
||||
|
||||
# RENDERERS ============================================================================================================
|
||||
# RENDERERS ============================================================================================================
|
||||
include/fennec/renderers/interface/forward.h
|
||||
|
||||
include/fennec/renderers/interface/gfxcontext.h
|
||||
include/fennec/renderers/interface/gfxsubpass.h
|
||||
include/fennec/renderers/interface/gfxresourcepool.h
|
||||
include/fennec/renderers/interface/gfxsurface.h
|
||||
|
||||
|
||||
# CONTAINERS ===========================================================================================================
|
||||
# CONTAINERS ===========================================================================================================
|
||||
include/fennec/containers/containers.h
|
||||
|
||||
include/fennec/containers/array.h
|
||||
|
||||
@@ -30,6 +30,9 @@ if( TARGET Vulkan::Headers AND TARGET Vulkan::volk # Base Headers and Meta-Loade
|
||||
fennec_add_definitions(FENNEC_GRAPHICS_VULKAN=1)
|
||||
|
||||
fennec_add_sources(
|
||||
include/fennec/renderers/vulkan/lib/app_info.h
|
||||
include/fennec/renderers/vulkan/lib/instance.h
|
||||
|
||||
include/fennec/renderers/vulkan/vkcontext.h include/fennec/renderers/vulkan/vkcontext.cpp
|
||||
)
|
||||
else()
|
||||
|
||||
@@ -45,10 +45,10 @@ namespace fennec
|
||||
///
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:-----------:|
|
||||
/// |:-----------:|:-----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -65,9 +65,18 @@ struct array {
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Definitions
|
||||
/// @{
|
||||
|
||||
using value_t = ValueT; ///< Alias for \f$ValueT\f$
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
// Public Members ======================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Public Members
|
||||
/// @{
|
||||
@@ -81,6 +90,7 @@ public:
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Properties
|
||||
/// @{
|
||||
@@ -93,13 +103,14 @@ public:
|
||||
///
|
||||
/// \brief returns **true** when the array is empty
|
||||
/// \return \f$ElemV == 0\f$
|
||||
[[nodiscard]] constexpr bool_t empty() const { return ElemV == 0; }
|
||||
[[nodiscard]] constexpr bool_t is_empty() const { return ElemV == 0; }
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Element Access
|
||||
/// @{
|
||||
@@ -168,6 +179,7 @@ public:
|
||||
|
||||
|
||||
// Comparison ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Comparison Operators
|
||||
/// @{
|
||||
@@ -188,6 +200,7 @@ public:
|
||||
|
||||
|
||||
// Iteration ===========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Iteration
|
||||
/// @{
|
||||
@@ -224,6 +237,8 @@ public:
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
// Helpers =============================================================================================================
|
||||
private:
|
||||
template<size_t...i>
|
||||
static bool _compare(const array& lhs, const array& rhs, index_metasequence<i...>) {
|
||||
|
||||
@@ -42,6 +42,22 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief Structure defining a binary tree
|
||||
///
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:-----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(N)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam TypeT The data type
|
||||
/// \tparam AllocT An allocator class
|
||||
template<typename TypeT, class AllocT = allocator<TypeT>>
|
||||
@@ -52,10 +68,15 @@ private:
|
||||
struct node;
|
||||
|
||||
public:
|
||||
/// \name Definitions
|
||||
/// @{
|
||||
|
||||
using value_t = TypeT; //!< The element type
|
||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>; //!< The allocator type
|
||||
static constexpr size_t npos = -1; //!< null position constant
|
||||
|
||||
/// @}
|
||||
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
|
||||
@@ -145,7 +166,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no elements in the tree, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
@@ -159,7 +180,7 @@ public:
|
||||
/// \returns The next id to be returned by \f$insert\f$ or \f$emplace\f$.
|
||||
constexpr size_t next_id() const {
|
||||
size_t i = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
i = _freed.front();
|
||||
}
|
||||
return i;
|
||||
@@ -455,7 +476,7 @@ public:
|
||||
queue.push_back(_root);
|
||||
}
|
||||
|
||||
while (not queue.empty()) {
|
||||
while (not queue.is_empty()) {
|
||||
size_t i = queue.front();
|
||||
queue.pop_front();
|
||||
|
||||
@@ -540,7 +561,7 @@ public:
|
||||
visit.push_back(chd);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -591,7 +612,7 @@ public:
|
||||
visit.push_front(chd);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -642,7 +663,7 @@ public:
|
||||
visit.push_front(next);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -692,7 +713,7 @@ public:
|
||||
visit.push_front(this->_successor(tree, pright));
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -926,7 +947,7 @@ private:
|
||||
|
||||
constexpr size_t _next_free() {
|
||||
size_t i = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
i = _freed.front();
|
||||
_freed.pop_front();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,22 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief Bitfield Container with basic Bit Ops
|
||||
///
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:------------------------------:|
|
||||
/// | stable | Elements cannot be referenced. |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(N)\f$ |
|
||||
/// | insertion | ⛔ |
|
||||
/// | deletion | ⛔ |
|
||||
///
|
||||
/// \tparam N The number of bits in the bitfield
|
||||
template<size_t N>
|
||||
struct bitfield {
|
||||
|
||||
@@ -40,6 +40,23 @@
|
||||
///
|
||||
/// \code #include <fennec/containers/containers.h> \endcode
|
||||
///
|
||||
/// \section Data Structure Properties
|
||||
///
|
||||
/// | Property | Meaning |
|
||||
/// |:-----------:|:----------------------------------------------------------------------------------------------:|
|
||||
/// | stable | Any pointer reference to an element remains constant for the lifetime of the data structure. |
|
||||
/// | dynamic | Memory for this data structure is allocated on the heap. |
|
||||
/// | homogeneous | The types of all elements are either identical, or inherit the same base type. |
|
||||
/// | distinct | Elements are guaranteed to be unique in their value. |
|
||||
/// | ordered | Elements are guaranteed to be in order, such that for any index \f$i\f$, \f$E_i < E_{i + 1}\f$ |
|
||||
/// | space | The amount of memory allocated with respect to the number of elements, in big-O notation. |
|
||||
/// | linear | Each element is sequential in terms of access. |
|
||||
/// | access | The runtime of the access operators and functions, in big-O notation. |
|
||||
/// | find | The runtime of finding an element in the data structure, in big-O notation. |
|
||||
/// | insertion | The runtime of inserting an element in the data structure, in big-O notation. |
|
||||
/// | deletion | The runtime of erasing an element in the data structure, in big-O notation. |
|
||||
///
|
||||
///
|
||||
/// \section fennec_containers_cppstdlib C++ Standard Template Library
|
||||
///
|
||||
/// | Symbol | Implemented | Passed |
|
||||
|
||||
@@ -47,10 +47,10 @@ namespace fennec
|
||||
/// It is one of the few data structures in this library that is stable, i.e. pointers to elements do not change.
|
||||
///
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when the deque is empty, \f$false\f$ otherwise
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
@@ -175,28 +175,28 @@ public:
|
||||
///
|
||||
/// \returns a reference to the first element in the deque
|
||||
value_t& front() {
|
||||
assert(not empty(), "Attempted to access an empty deque.");
|
||||
assert(not is_empty(), "Attempted to access an empty deque.");
|
||||
return _first->value;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns a const-qualified reference to the first element in the deque
|
||||
const value_t& front() const {
|
||||
assert(not empty(), "Attempted to access an empty deque.");
|
||||
assert(not is_empty(), "Attempted to access an empty deque.");
|
||||
return _first->value;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns a reference to the last element in the deque
|
||||
value_t& back() {
|
||||
assert(not empty(), "Attempted to access an empty deque.");
|
||||
assert(not is_empty(), "Attempted to access an empty deque.");
|
||||
return _last->value;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns a const-qualified reference to the last element in the deque
|
||||
const value_t& back() const {
|
||||
assert(not empty(), "Attempted to access an empty deque.");
|
||||
assert(not is_empty(), "Attempted to access an empty deque.");
|
||||
return _last->value;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ namespace fennec
|
||||
/// \brief Wrapper for dynamically sized and allocated arrays
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -62,15 +62,15 @@ namespace fennec
|
||||
/// \tparam TypeT value type
|
||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||
struct dynarray {
|
||||
public:
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
|
||||
public:
|
||||
using value_t = TypeT; ///< Alias for the value type
|
||||
using alloc_t = Alloc; ///< Alias for the allocator type
|
||||
|
||||
|
||||
// Constructors ========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Constructors & Destructor
|
||||
/// @{
|
||||
@@ -260,6 +260,7 @@ public:
|
||||
/// @}
|
||||
|
||||
// Assignment ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Properties
|
||||
/// @{
|
||||
@@ -322,6 +323,7 @@ public:
|
||||
/// @}
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Properties
|
||||
/// @{
|
||||
@@ -340,7 +342,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns True when there are no elements active, otherwise false
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
@@ -348,6 +350,7 @@ public:
|
||||
|
||||
|
||||
// Element Access ======================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Access
|
||||
/// @{
|
||||
@@ -358,7 +361,7 @@ public:
|
||||
/// \returns A reference to the element at index \f$i\f$
|
||||
constexpr TypeT& operator[](size_t i) {
|
||||
assertd(i < _size, "Array Out of Bounds");
|
||||
return _alloc.data()[i];
|
||||
return _alloc[i];
|
||||
}
|
||||
|
||||
///
|
||||
@@ -367,7 +370,7 @@ public:
|
||||
/// \returns A const qualified reference to the element at index \f$i\f$
|
||||
constexpr const TypeT& operator[](size_t i) const {
|
||||
assertd(i < _size, "Array Out of Bounds");
|
||||
return _alloc.data()[i];
|
||||
return _alloc[i];
|
||||
}
|
||||
|
||||
///
|
||||
@@ -394,10 +397,23 @@ public:
|
||||
return this->operator[](size() - 1);
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns A pointer to the underlying allocation
|
||||
constexpr TypeT* data() {
|
||||
return _alloc.data();
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns A pointer to the underlying allocation
|
||||
constexpr const TypeT* data() const {
|
||||
return _alloc.data();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
// Modifiers ===========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Modifiers
|
||||
/// @{
|
||||
@@ -510,31 +526,47 @@ public:
|
||||
/// \brief Resize the dynarray, invoking the default constructor for all new elements
|
||||
/// \param n The new size in elements
|
||||
constexpr void resize(size_t n) {
|
||||
_reduce(n);
|
||||
_alloc.creallocate(n);
|
||||
|
||||
while (_size < n) {
|
||||
emplace_back();
|
||||
for (size_t i = _size; i < n; ++i) {
|
||||
fennec::construct(&_alloc[i]);
|
||||
}
|
||||
|
||||
_size = n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Resize the dynarray, invoking the copy constructor for all new elements
|
||||
/// \param n The new size in elements
|
||||
/// \param val The value to fill with
|
||||
///
|
||||
/// \details if \f$n\f$ is less than the current size, any elements that would be removed are destructed
|
||||
constexpr void resize(size_t n, const TypeT& val) {
|
||||
_reduce(n);
|
||||
_alloc.creallocate(n);
|
||||
|
||||
while (_size < n) {
|
||||
emplace_back(val);
|
||||
for (size_t i = _size; i < n; ++i) {
|
||||
fennec::construct(&_alloc[i], val);
|
||||
}
|
||||
|
||||
_size = n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Reserve the array, allocating new space without initialization
|
||||
/// \param n The new capacity in elements
|
||||
///
|
||||
/// \details if \f$n\f$ is less than the current size, any elements that would be removed are destructed
|
||||
constexpr void reserve(size_t n) {
|
||||
_reduce(n);
|
||||
_alloc.creallocate(n);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Clears the contents of the dynarray, destructing all elements and releasing the allocation.
|
||||
constexpr void clear() {
|
||||
while (_size > 0) {
|
||||
fennec::destruct(&_alloc[--_size]);
|
||||
}
|
||||
_reduce(0);
|
||||
_alloc.deallocate();
|
||||
}
|
||||
|
||||
@@ -542,6 +574,7 @@ public:
|
||||
|
||||
|
||||
// Iteration ===========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Iteration
|
||||
/// @{
|
||||
@@ -567,13 +600,26 @@ public:
|
||||
|
||||
/// @}
|
||||
|
||||
// Private Members =====================================================================================================
|
||||
private:
|
||||
allocation<value_t, alloc_t> _alloc;
|
||||
size_t _size;
|
||||
|
||||
|
||||
// Private Helpers =====================================================================================================
|
||||
private:
|
||||
|
||||
// helper to double the capacity of the allocation
|
||||
constexpr void _grow() {
|
||||
_alloc.creallocate(_alloc.capacity() * 2);
|
||||
}
|
||||
|
||||
allocation<value_t, alloc_t> _alloc;
|
||||
size_t _size;
|
||||
// helper to destruct elements past n
|
||||
constexpr void _reduce(size_t n) {
|
||||
while (_size > n) {
|
||||
fennec::destruct(&_alloc[--_size]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,20 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief A struct capable of holding a single object of any type
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogeneous | ⛔ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(1)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | ⛔ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
struct generic {
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
@@ -114,6 +128,7 @@ public:
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief runtime type acquisition
|
||||
@@ -130,6 +145,7 @@ public:
|
||||
|
||||
|
||||
// Assignment ==========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief copy assignment
|
||||
@@ -169,7 +185,8 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Utility =============================================================================================================
|
||||
// Insertion & Deletion ================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief emplace value
|
||||
@@ -195,6 +212,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Utility =============================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief C++ 11 Swap Specification
|
||||
/// \param gen the generic to swap with
|
||||
@@ -223,10 +244,15 @@ public:
|
||||
return static_cast<T>(*static_cast<U*>(_handle));
|
||||
}
|
||||
|
||||
|
||||
// Members =============================================================================================================
|
||||
private:
|
||||
void* _handle;
|
||||
manager_t _manage;
|
||||
|
||||
|
||||
// Helpers =============================================================================================================
|
||||
private:
|
||||
template<typename T>
|
||||
static void* _manage_impl(uint8_t op, void* hnd) {
|
||||
static fennec::type t = type::get<T>();
|
||||
|
||||
@@ -56,10 +56,10 @@ namespace fennec
|
||||
///
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -67,7 +67,7 @@ namespace fennec
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(1)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(N)\f$ |
|
||||
/// | deletion | \f$O(M)\f$ |
|
||||
///
|
||||
/// Graphs contain vertices and edges. Graphs are either directed
|
||||
/// or undirected. This structure allows the creation of both directed and undirected edges. As
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no vertices in the graph, \f$false\f$ otherwise
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return num_vertices() == 0;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
/// \param b The id of the second vertex
|
||||
/// \returns A pointer to the value stored in the edge, \f$nullptr\f$ if not found
|
||||
constexpr edge_t* operator[](size_t a, size_t b) {
|
||||
if (empty()) {
|
||||
if (is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
edge_t* it = _edge_map[a][b];
|
||||
@@ -245,7 +245,7 @@ public:
|
||||
/// \param b The id of the second vertex
|
||||
/// \returns A const-qualified pointer to the value stored in the edge, \f$nullptr\f$ if not found
|
||||
constexpr const edge_t* operator[](size_t a, size_t b) const {
|
||||
if (empty()) {
|
||||
if (is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
const edge_t* it = _edge_map[a][b];
|
||||
@@ -261,7 +261,7 @@ public:
|
||||
/// \returns A list containing all vertices \f$x\f$ with edges from \f$vertex\f$ to `x...`
|
||||
list<size_t> outgoing(size_t vertex) {
|
||||
list<size_t> res;
|
||||
if (empty() || vertex >= _edge_map.size()) {
|
||||
if (is_empty() || vertex >= _edge_map.size()) {
|
||||
return res;
|
||||
}
|
||||
for (const auto& it : _edge_map[vertex]) {
|
||||
@@ -276,7 +276,7 @@ public:
|
||||
/// \returns A list containing all vertices \f$x\f$ with edges from `x...` to \f$vertex\f$
|
||||
list<size_t> incoming(size_t vertex) {
|
||||
list<size_t> res;
|
||||
if (empty() || vertex >= _edge_map.size()) {
|
||||
if (is_empty() || vertex >= _edge_map.size()) {
|
||||
return res;
|
||||
}
|
||||
for (size_t n = 0; n < _edge_map.size(); ++n) {
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
/// \returns A list containing all vertices \f$x\f$ that have symmetric edges with \f$vertex\f$
|
||||
list<size_t> symmetric(size_t vertex) {
|
||||
list<size_t> res;
|
||||
if (empty() || vertex >= _edge_map.size()) {
|
||||
if (is_empty() || vertex >= _edge_map.size()) {
|
||||
return res;
|
||||
}
|
||||
for (const auto& it : _edge_map[vertex]) {
|
||||
@@ -314,7 +314,7 @@ public:
|
||||
/// \returns A list containing all vertices \f$x\f$ that have symmetric edges with \f$vertex\f$
|
||||
list<size_t> undirected(size_t vertex) {
|
||||
list<size_t> res;
|
||||
if (empty() || vertex >= _edge_map.size()) {
|
||||
if (is_empty() || vertex >= _edge_map.size()) {
|
||||
return res;
|
||||
}
|
||||
for (const auto& it : _edge_map[vertex]) {
|
||||
@@ -332,7 +332,7 @@ public:
|
||||
/// \param vertex The id of the vertex
|
||||
/// \returns A pointer to a map containing edges mapped from this vertex
|
||||
const auto* edges(size_t vertex) {
|
||||
if (empty() || vertex >= _edge_map.size()) {
|
||||
if (is_empty() || vertex >= _edge_map.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &_edge_map[vertex];
|
||||
|
||||
@@ -49,19 +49,22 @@ namespace fennec
|
||||
/// following properties:
|
||||
///
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | access | \f$O(N)\f$ |
|
||||
/// | find | \f$O(N)\f$ |
|
||||
/// | insertion | \f$O(N)\f$ |
|
||||
/// | deletion | \f$O(N)\f$ |
|
||||
///
|
||||
/// \note Access, Insertion, and Deletion are \f$O(N)\f$ using the index pattern,
|
||||
/// using the iterator pattern yields \f$O(1)\f$ runtime.
|
||||
///
|
||||
/// \tparam TypeT value type
|
||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||
struct list {
|
||||
@@ -82,8 +85,13 @@ public:
|
||||
class iterator; ///< Iterator type for forward iteration over the list
|
||||
class const_iterator; ///< Iterator type for forward iteration over a constant list
|
||||
|
||||
private:
|
||||
using table_t = dynarray<node, alloc_t>;
|
||||
using freed_t = dynarray<size_t>;
|
||||
|
||||
|
||||
// Constructors & Destructor ===========================================================================================
|
||||
public:
|
||||
|
||||
/// \name Constructors & Destructor
|
||||
/// @{
|
||||
@@ -127,6 +135,7 @@ public:
|
||||
/// @}
|
||||
|
||||
// Assignment ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Assignment
|
||||
/// @{
|
||||
@@ -160,6 +169,7 @@ public:
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Properties
|
||||
/// @{
|
||||
@@ -173,12 +183,12 @@ public:
|
||||
///
|
||||
/// \returns The capacity of the list in elements.
|
||||
constexpr size_t capacity() const {
|
||||
return _table.capacity();
|
||||
return _table.size();
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when the list is empty, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _root == npos;
|
||||
}
|
||||
|
||||
@@ -186,6 +196,7 @@ public:
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Access
|
||||
/// @{
|
||||
@@ -248,6 +259,7 @@ public:
|
||||
|
||||
|
||||
// Modifiers ===========================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Modifiers
|
||||
/// @{
|
||||
@@ -259,7 +271,7 @@ public:
|
||||
/// \returns The id of the inserted node
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
constexpr size_t insert(const iterator& it, const value_t& x) {
|
||||
constexpr iterator insert(const iterator& it, const value_t& x) {
|
||||
return this->_insert(it._n, x);
|
||||
}
|
||||
|
||||
@@ -270,7 +282,7 @@ public:
|
||||
/// \returns The id of the inserted node
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
constexpr size_t insert(const iterator& it, value_t&& x) {
|
||||
constexpr iterator insert(const iterator& it, value_t&& x) {
|
||||
return this->_insert(it._n, fennec::forward<value_t>(x));
|
||||
}
|
||||
|
||||
@@ -281,7 +293,7 @@ public:
|
||||
/// \returns The id of the inserted node
|
||||
///
|
||||
/// \details \f$O(N)\f$
|
||||
constexpr size_t insert(size_t i, const value_t& x) {
|
||||
constexpr iterator insert(size_t i, const value_t& x) {
|
||||
assert(i <= size(), "Index out of Bounds");
|
||||
|
||||
size_t n = _walk(min(i, size_t(size() - 1)));
|
||||
@@ -295,7 +307,7 @@ public:
|
||||
/// \returns The id of the inserted node
|
||||
///
|
||||
/// \details \f$O(N)\f$
|
||||
constexpr size_t insert(size_t i, value_t&& x) {
|
||||
constexpr iterator insert(size_t i, value_t&& x) {
|
||||
assert(i <= size(), "Index out of Bounds");
|
||||
|
||||
size_t n = _walk(min(i, size_t(size() - 1)));
|
||||
@@ -311,18 +323,31 @@ public:
|
||||
///
|
||||
/// \details \f$O(N)\f$
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t emplace(size_t i, ArgsT&&...args) {
|
||||
constexpr iterator emplace(size_t i, ArgsT&&...args) {
|
||||
assert(i <= size(), "Index out of Bounds");
|
||||
|
||||
size_t n = _walk(min(i, size_t(size() - 1)));
|
||||
return this->_insert(n, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Insertion
|
||||
/// \tparam ArgsT Argument types
|
||||
/// \param it Location to insert at
|
||||
/// \param args Arguments to construct with
|
||||
/// \returns The id of the inserted node
|
||||
///
|
||||
/// \details \f$O(N)\f$
|
||||
template<typename...ArgsT>
|
||||
constexpr iterator emplace(const iterator& it, ArgsT&&...args) {
|
||||
return this->_insert(it._n, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Push Front Copy
|
||||
/// \param x Value to copy
|
||||
/// \returns The id of the inserted node
|
||||
constexpr size_t push_front(const value_t& x) {
|
||||
constexpr iterator push_front(const value_t& x) {
|
||||
return this->_insert(_root, x);
|
||||
}
|
||||
|
||||
@@ -330,7 +355,7 @@ public:
|
||||
/// \brief Push Front Move
|
||||
/// \param x Value to move
|
||||
/// \returns The id of the inserted node
|
||||
constexpr size_t push_front(value_t&& x) {
|
||||
constexpr iterator push_front(value_t&& x) {
|
||||
return this->_insert(_root, fennec::forward<value_t>(x));
|
||||
}
|
||||
|
||||
@@ -340,7 +365,7 @@ public:
|
||||
/// \tparam ArgsT Argument types
|
||||
/// \returns The id of the inserted node
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t emplace_front(ArgsT&&...args) {
|
||||
constexpr iterator emplace_front(ArgsT&&...args) {
|
||||
return this->_insert(_root, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
@@ -348,7 +373,7 @@ public:
|
||||
/// \brief Push Back Copy
|
||||
/// \param x Value to copy
|
||||
/// \returns The id of the inserted node
|
||||
constexpr size_t push_back(const value_t& x) {
|
||||
constexpr iterator push_back(const value_t& x) {
|
||||
return this->_insert(npos, x);
|
||||
}
|
||||
|
||||
@@ -356,7 +381,7 @@ public:
|
||||
/// \brief Push Back Move
|
||||
/// \param x Value to move
|
||||
/// \returns The id of the inserted node
|
||||
constexpr size_t push_back(value_t&& x) {
|
||||
constexpr iterator push_back(value_t&& x) {
|
||||
return this->_insert(npos, fennec::forward<value_t>(x));
|
||||
}
|
||||
|
||||
@@ -366,7 +391,7 @@ public:
|
||||
/// \tparam ArgsT Argument types
|
||||
/// \returns The id of the inserted node
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t emplace_back(ArgsT&&...args) {
|
||||
constexpr iterator emplace_back(ArgsT&&...args) {
|
||||
return this->_insert(npos, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
@@ -383,7 +408,7 @@ public:
|
||||
/// \brief Erase Element
|
||||
/// \param it Location to Erase
|
||||
constexpr void erase(const iterator& it) {
|
||||
_erase(it._n);
|
||||
this->_erase(it._n);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -403,15 +428,16 @@ public:
|
||||
constexpr void clear() {
|
||||
size_t i = _root;
|
||||
while (i != npos) {
|
||||
fennec::destruct(&_table[i]);
|
||||
_table[i].value = nullopt;
|
||||
i = this->_next(i);
|
||||
}
|
||||
_table.deallocate();
|
||||
_table.clear();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
// ITERATOR ============================================================================================================
|
||||
// Iterator ============================================================================================================
|
||||
public:
|
||||
|
||||
/// \name Iteration
|
||||
/// @{
|
||||
@@ -587,15 +613,19 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Members =============================================================================================================
|
||||
private:
|
||||
allocation<node, alloc_t> _table;
|
||||
dynarray<size_t> _freed;
|
||||
table_t _table;
|
||||
freed_t _freed;
|
||||
size_t _root, _last, _size;
|
||||
|
||||
friend class iterator;
|
||||
|
||||
|
||||
// Helpers =============================================================================================================
|
||||
private:
|
||||
constexpr void _expand() {
|
||||
_table.creallocate(fennec::max(_table.capacity(), size_t(1)) * 2);
|
||||
_table.resize(fennec::max(_table.size(), size_t(4)) * 2);
|
||||
}
|
||||
|
||||
struct node {
|
||||
@@ -608,18 +638,6 @@ private:
|
||||
, next(npos) {
|
||||
}
|
||||
|
||||
constexpr node(size_t p, size_t n)
|
||||
: value()
|
||||
, prev(p)
|
||||
, next(n) {
|
||||
}
|
||||
|
||||
constexpr node(size_t p, size_t n, value_t&& val)
|
||||
: value(fennec::forward<value_t>(val))
|
||||
, prev(p)
|
||||
, next(n) {
|
||||
}
|
||||
|
||||
constexpr ~node() = default;
|
||||
|
||||
constexpr void clear() {
|
||||
@@ -647,7 +665,7 @@ private:
|
||||
}
|
||||
|
||||
constexpr size_t _next_free() {
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
size_t n = _freed.back();
|
||||
_freed.pop_back();
|
||||
return n;
|
||||
@@ -656,20 +674,20 @@ private:
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t _insert(size_t n, ArgsT&&...args) {
|
||||
constexpr iterator _insert(size_t n, ArgsT&&...args) {
|
||||
if (size() == capacity()) {
|
||||
_expand();
|
||||
}
|
||||
|
||||
size_t i = _next_free();
|
||||
++_size;
|
||||
fennec::construct(&_table[i].value, fennec::forward<ArgsT>(args)...);
|
||||
_table[i].value.emplace(fennec::forward<ArgsT>(args)...);
|
||||
|
||||
if (_root == npos) {
|
||||
_table[i].prev = npos;
|
||||
_table[i].next = npos;
|
||||
_root = _last = i;
|
||||
return i;
|
||||
return iterator(this, i);
|
||||
}
|
||||
|
||||
if (n == npos) {
|
||||
@@ -677,20 +695,20 @@ private:
|
||||
_table[i].prev = _last;
|
||||
_table[i].next = npos;
|
||||
_last = i;
|
||||
return i;
|
||||
return iterator(this, i);
|
||||
}
|
||||
|
||||
_table[i].prev = _prev(n);
|
||||
_table[i].next = n;
|
||||
_table[n].prev = i;
|
||||
_root = n == _root ? i : _root;
|
||||
return i;
|
||||
return iterator(this, i);
|
||||
}
|
||||
|
||||
constexpr void _erase(size_t n) {
|
||||
if (n == npos) return;
|
||||
|
||||
fennec::destruct(&_table[n].value);
|
||||
_table[n].value = nullopt;
|
||||
_freed.push_back(n);
|
||||
--_size;
|
||||
|
||||
|
||||
@@ -59,19 +59,21 @@ namespace fennec
|
||||
/// \brief Data Structure defining a mapping of \f$key\f$ \f$KeyT\f$ to \f$value\f$ \f$ValueT\f$
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ✅ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(1)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \note These runtimes are amortized, in theory the worst case is \f$O(N)\f$, but that is highly improbable.
|
||||
///
|
||||
/// \tparam KeyT The Key Type
|
||||
/// \tparam ValueT The Value Type
|
||||
/// \tparam Hash The Hash to Use
|
||||
@@ -146,7 +148,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no elements in the set, \f$false\f$ otherwise
|
||||
constexpr size_t empty() const {
|
||||
constexpr size_t is_empty() const {
|
||||
return _set.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,21 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief Struct which holds a pool of objects associated with ids
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(N)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam TypeT The value type
|
||||
/// \tparam AllocT The allocator type
|
||||
template<typename TypeT, typename AllocT = allocator<TypeT>>
|
||||
@@ -93,7 +108,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no objects in the pool, \f$false\f$ otherwise
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@@ -104,7 +119,7 @@ public:
|
||||
/// \returns The id of the next inserted node
|
||||
constexpr size_t next_id() const {
|
||||
size_t next = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
next = _freed.front();
|
||||
}
|
||||
return next;
|
||||
@@ -429,7 +444,7 @@ private:
|
||||
|
||||
size_t _next_free() {
|
||||
size_t next = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
next = _freed.front();
|
||||
_freed.pop_front();
|
||||
}
|
||||
|
||||
@@ -52,6 +52,21 @@ constexpr nullopt_t nullopt_v = {};
|
||||
|
||||
///
|
||||
/// \brief Structure to hold an optional value.
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | ⛔ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam T
|
||||
template<typename T>
|
||||
struct optional {
|
||||
@@ -160,7 +175,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there is no held value, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return not _set;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,21 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief Struct for holding a pair of values
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogeneous | ⛔ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | ⛔ |
|
||||
/// | insertion | ⛔ |
|
||||
/// | deletion | ⛔ |
|
||||
///
|
||||
/// \tparam TypeT0 The type of the first value
|
||||
/// \tparam TypeT1 The type of the second value
|
||||
template<typename TypeT0, typename TypeT1>
|
||||
|
||||
@@ -55,6 +55,21 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief a priority queue data structure implemented using a binary heap
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ✅ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ✅ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | ⛔ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam ValueT The value type
|
||||
/// \tparam CompareT The compare type, defaults to `fennec::less`
|
||||
/// \tparam AllocT The allocator type, defaults to `fennec::allocator`
|
||||
@@ -87,6 +102,7 @@ private:
|
||||
|
||||
// Constructors & Destructor ===========================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief default constructor
|
||||
/// \details initializes an empty queue
|
||||
@@ -105,6 +121,7 @@ public:
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \returns the size of the queue
|
||||
@@ -120,12 +137,13 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ if the queue holds no elements
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
// Access ==============================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \returns the value at the front of the queue
|
||||
@@ -135,6 +153,7 @@ public:
|
||||
|
||||
|
||||
// Modifiers ===========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief push a new key into the queue
|
||||
@@ -173,7 +192,9 @@ private:
|
||||
alloc_t _table;
|
||||
size_t _size;
|
||||
|
||||
|
||||
// Helpers =============================================================================================================
|
||||
private:
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr void _insert(ArgsT&&...args) {
|
||||
|
||||
@@ -43,6 +43,21 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief Rooted-Directed Tree
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | \f$O(N)\f$ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam TypeT Data type
|
||||
/// \tparam AllocT Allocator Type
|
||||
template<typename TypeT, typename AllocT = allocator<TypeT>>
|
||||
@@ -177,7 +192,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no nodes in the tree, \f$false\f$ otherwise
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
@@ -311,7 +326,7 @@ public:
|
||||
/// \returns The next node id were \f$insert\f$ or \f$emplace\f$ to be called
|
||||
constexpr size_t next_id() const {
|
||||
size_t i = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
i = _freed.front();
|
||||
}
|
||||
return i;
|
||||
@@ -365,7 +380,7 @@ public:
|
||||
visit.push_front({ root, parent });
|
||||
size_t res = npos;
|
||||
|
||||
while (not visit.empty()) {
|
||||
while (not visit.is_empty()) {
|
||||
auto node = visit.front();
|
||||
visit.pop_front();
|
||||
|
||||
@@ -490,7 +505,7 @@ public:
|
||||
visit.push_back(chd);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -540,7 +555,7 @@ public:
|
||||
visit.push_front(chd);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -592,7 +607,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -642,7 +657,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
if (not visit.is_empty()) {
|
||||
node = visit.front();
|
||||
visit.pop_front();
|
||||
} else {
|
||||
@@ -669,7 +684,7 @@ private:
|
||||
|
||||
size_t _next_free() {
|
||||
size_t next = _size;
|
||||
if (not _freed.empty()) {
|
||||
if (not _freed.is_empty()) {
|
||||
next = _freed.front();
|
||||
_freed.pop_front();
|
||||
}
|
||||
@@ -723,7 +738,7 @@ private:
|
||||
constexpr void _erase(size_t i) {
|
||||
list<size_t> queue;
|
||||
queue.push_back(child(i));
|
||||
while (not queue.empty()) {
|
||||
while (not queue.is_empty()) {
|
||||
size_t n = queue.front(); queue.pop_front();
|
||||
if (n == npos) continue;
|
||||
queue.push_back(next(n));
|
||||
|
||||
@@ -57,10 +57,10 @@ namespace fennec
|
||||
/// This data-structure behaves like an ordered-set, but does not use pointers, instead storing the table in-array
|
||||
///
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:---------------:|
|
||||
/// |:-----------:|:---------------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ✅ |
|
||||
/// | ordered | ✅ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -282,7 +282,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when there are no elements in the sequence, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ public:
|
||||
it._visit.push_front(next);
|
||||
}
|
||||
|
||||
if (not it._visit.empty()) {
|
||||
if (not it._visit.is_empty()) {
|
||||
it._node = it._visit.front();
|
||||
it._visit.pop_front();
|
||||
} else {
|
||||
@@ -513,7 +513,7 @@ public:
|
||||
it._visit.push_front(next);
|
||||
}
|
||||
|
||||
if (not it._visit.empty()) {
|
||||
if (not it._visit.is_empty()) {
|
||||
it._node = it._visit.front();
|
||||
it._visit.pop_front();
|
||||
} else {
|
||||
|
||||
@@ -50,10 +50,10 @@ namespace fennec
|
||||
/// This data-structure behaves like a set, but does not use pointers, instead storing the table in-array
|
||||
///
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:----------:|
|
||||
/// |:-----------:|:----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ✅ |
|
||||
/// | homogeneous | ✅ |
|
||||
/// | distinct | ✅ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ when the set is empty, \f$false\f$ otherwise
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ namespace fennec
|
||||
/// \brief Tuple, holds a collection of values of different types
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:----------:|:-----------:|
|
||||
/// |:-----------:|:-----------:|
|
||||
/// | stable | ⛔ |
|
||||
/// | dynamic | ✅ |
|
||||
/// | homogenous | ⛔ |
|
||||
/// | homogeneous | ⛔ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
|
||||
@@ -41,6 +41,21 @@ namespace fennec
|
||||
|
||||
///
|
||||
/// \brief A structure that represents a union between `TypesT...`
|
||||
/// \details
|
||||
/// | Property | Value |
|
||||
/// |:-----------:|:-----------:|
|
||||
/// | stable | ✅ |
|
||||
/// | dynamic | ⛔ |
|
||||
/// | homogeneous | ⛔ |
|
||||
/// | distinct | ⛔ |
|
||||
/// | ordered | ⛔ |
|
||||
/// | space | \f$O(N)\f$ |
|
||||
/// | linear | ⛔ |
|
||||
/// | access | \f$O(1)\f$ |
|
||||
/// | find | ⛔ |
|
||||
/// | insertion | \f$O(1)\f$ |
|
||||
/// | deletion | \f$O(1)\f$ |
|
||||
///
|
||||
/// \tparam TypesT The types to hold in the variant
|
||||
template<typename...TypesT>
|
||||
struct variant {
|
||||
|
||||
@@ -41,10 +41,18 @@ namespace fennec
|
||||
///
|
||||
/// \brief simple version struct for drivers and systems
|
||||
struct version {
|
||||
uint32_t major; //!< the major version
|
||||
uint32_t minor; //!< the minor version
|
||||
uint32_t patch; //!< the patch
|
||||
string str; //!< string representation of the version
|
||||
uint32_t major = { 1 }; //!< the major version
|
||||
uint32_t minor = { 0 }; //!< the minor version
|
||||
uint32_t patch = { 0 }; //!< the patch
|
||||
string str = { string("") }; //!< string representation of the version
|
||||
|
||||
friend bool operator==(const version& lhs, const version& rhs) {
|
||||
return lhs.major == rhs.major and lhs.minor == rhs.minor and lhs.patch == rhs.patch and lhs.str == rhs.str;
|
||||
}
|
||||
|
||||
friend bool operator!=(const version& lhs, const version& rhs) {
|
||||
return lhs.major != rhs.major or lhs.minor != rhs.minor or lhs.patch != rhs.patch or lhs.str != rhs.str;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ if the path is empty or points to root
|
||||
bool empty() {
|
||||
bool is_empty() {
|
||||
size_t size = _str.size();
|
||||
if (size == 0) return true;
|
||||
#if FENNEC_PLATFORM_WINDOWS
|
||||
@@ -221,7 +221,7 @@ public:
|
||||
}
|
||||
return _str.substring(0, start);
|
||||
#else
|
||||
size_t start = _str.size() - 1;
|
||||
size_t start = _str.size();
|
||||
start = _str[start] == '/' ? start - 1 : start;
|
||||
return path(_str.substring(0, _str.rfind('/', start)));
|
||||
#endif
|
||||
@@ -243,9 +243,9 @@ public:
|
||||
working = current();
|
||||
}
|
||||
|
||||
while (not parse.empty()) {
|
||||
while (not parse.is_empty()) {
|
||||
// Handle dots
|
||||
while (not parse.empty() && parse._str[0] == '.') {
|
||||
while (not parse.is_empty() && parse._str[0] == '.') {
|
||||
// Check for ".."
|
||||
if (parse._str[1] == '.') {
|
||||
// ".."
|
||||
@@ -265,7 +265,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (parse.empty()) break;
|
||||
if (parse.is_empty()) break;
|
||||
|
||||
// Push the path
|
||||
const size_t loc = parse._str.find('/');
|
||||
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ if there is not a held pointer, \f$false\f$ otherwise
|
||||
bool empty() {
|
||||
bool is_empty() {
|
||||
return _handle == nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <fennec/rtti/enable.h>
|
||||
|
||||
#include <fennec/renderers/interface/forward.h>
|
||||
#include <fennec/renderers/interface/gfxresourcepool.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
@@ -49,8 +48,6 @@ class gfxcontext {
|
||||
public:
|
||||
using handle_t = uint32_t;
|
||||
|
||||
gfxresourcepool resources;
|
||||
|
||||
gfxcontext(display_server* display)
|
||||
: display(display)
|
||||
, version(0, 0, 0, string("")) {
|
||||
@@ -65,7 +62,6 @@ public:
|
||||
|
||||
virtual gfxsurface* create_surface(window* window) = 0;
|
||||
|
||||
virtual gfxpass* create_pass() = 0;
|
||||
virtual const version& get_version() const { return version; };
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file gfxcontext.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/string/string.h>
|
||||
#include <fennec/renderers/interface/forward.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Defines an interface that holds a series of passes with one coherent objective
|
||||
/// \details This represents the overarching renderer, and not any platform specific behaviour.
|
||||
/// I.E. This acts as a proxy for creating API objects, but the behaviour of those objects
|
||||
/// is defined elsewhere.
|
||||
class gfxpass {
|
||||
public:
|
||||
gfxsubpass* add_subpass();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class gfxsubpass {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_GFXCONTEXT_H
|
||||
@@ -1,43 +0,0 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file gfxresourcepool.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class gfxresourcepool {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_GFXRESOURCEPOOL_H
|
||||
@@ -1,41 +0,0 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file gfxsubpass.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
#ifndef FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
#define FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_INTERFACE_GFXSUBPASS_H
|
||||
@@ -45,9 +45,6 @@ public:
|
||||
: gfxcontext(display) {
|
||||
}
|
||||
|
||||
/// \brief create a render pass
|
||||
/// \returns a new render pass
|
||||
gfxpass* create_pass() override;
|
||||
|
||||
private:
|
||||
#ifndef FENNEC_DOXYGEN
|
||||
|
||||
210
include/fennec/renderers/vulkan/lib/app_info.h
Normal file
210
include/fennec/renderers/vulkan/lib/app_info.h
Normal file
@@ -0,0 +1,210 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file instance.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
|
||||
#ifndef FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H
|
||||
#define FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H
|
||||
|
||||
#include <volk.h>
|
||||
|
||||
#include <fennec/core/version.h>
|
||||
#include <fennec/string/cstring.h>
|
||||
|
||||
namespace fennec::vk
|
||||
{
|
||||
|
||||
struct app_info : private VkApplicationInfo {
|
||||
|
||||
// Constructors & Destructor ===========================================================================================
|
||||
public:
|
||||
///
|
||||
/// \brief Create a Vulkan application information structure
|
||||
/// \param app_name the name of the application, this cstring must exist for the lifetime of this object
|
||||
/// until a structure of type fennec::vk::instance is constructed
|
||||
/// \param app_version the internal version of the application
|
||||
/// \param engine_name the name of the engine, this cstring must exist for the lifetime of this object
|
||||
/// until a structure of type fennec::vk::instance is constructed
|
||||
/// \param engine_version the internal version of the engine
|
||||
/// \param api_version the Vulkan API version to use, version::patch and version::str are ignored
|
||||
/// \param ext a pointer to an extension structure, the object next points to must exist for the lifetime of this
|
||||
/// object until a structure of type fennec::vk::instance is constructed
|
||||
/// TODO: DEFINE EXTENSION STRUCTURE WRAPPERS
|
||||
app_info(
|
||||
const cstring& app_name = {}, const version& app_version = {},
|
||||
const cstring& engine_name = {}, const version& engine_version = {},
|
||||
const version& api_version = {},
|
||||
void* ext = nullptr
|
||||
) noexcept : VkApplicationInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = ext,
|
||||
.pApplicationName = app_name,
|
||||
.applicationVersion = VK_MAKE_VERSION(app_version.major, app_version.minor, app_version.patch),
|
||||
.pEngineName = engine_name,
|
||||
.engineVersion = VK_MAKE_VERSION(engine_version.major, engine_version.minor, engine_version.patch),
|
||||
.apiVersion = VK_MAKE_API_VERSION(0, api_version.major, api_version.minor, 0),
|
||||
} {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Constructor
|
||||
app_info(const app_info&) noexcept = default;
|
||||
|
||||
///
|
||||
/// \brief Move Constructor
|
||||
app_info(app_info&&) noexcept = default;
|
||||
|
||||
///
|
||||
/// \brief Destructor
|
||||
~app_info() noexcept = default;
|
||||
|
||||
|
||||
// Assignment Operators ================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief Copy Assignment
|
||||
app_info& operator=(const app_info&) noexcept = default;
|
||||
|
||||
///
|
||||
/// \brief Move Assignment
|
||||
app_info& operator=(app_info&&) noexcept = default;
|
||||
|
||||
|
||||
// Implicit Conversions ================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
operator VkApplicationInfo*() noexcept {
|
||||
return this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Implicit Pointer Conversion
|
||||
operator const VkApplicationInfo*() const noexcept {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
// Properties ==========================================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \returns A cstring containing the application name
|
||||
cstring get_app_name() const {
|
||||
return cstring(pApplicationName, strlen(pApplicationName));
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set the application name
|
||||
/// \param str A cstring containing the new name
|
||||
void set_app_name(const cstring& str) {
|
||||
pApplicationName = str;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns A version struct containing the application version
|
||||
version get_app_version() const {
|
||||
return version {
|
||||
.major = VK_VERSION_MAJOR(applicationVersion),
|
||||
.minor = VK_VERSION_MINOR(applicationVersion),
|
||||
.patch = VK_VERSION_PATCH(applicationVersion)
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set the engine version
|
||||
/// \param ver A version struct containing the new version
|
||||
void set_engine_version(const version& ver) {
|
||||
engineVersion = VK_MAKE_VERSION(ver.major, ver.minor, ver.patch);
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns A cstring containing the engine name
|
||||
cstring get_engine_name() const { return cstring(pEngineName, strlen(pEngineName)); }
|
||||
|
||||
///
|
||||
/// \brief Set the engine name
|
||||
/// \param str A cstring containing the new name
|
||||
void set_engine_name(const cstring& str) { pEngineName = str; }
|
||||
|
||||
///
|
||||
/// \returns A version struct containing the engine version
|
||||
version get_engine_version() const {
|
||||
return version {
|
||||
.major = VK_VERSION_MAJOR(engineVersion),
|
||||
.minor = VK_VERSION_MINOR(engineVersion),
|
||||
.patch = VK_VERSION_PATCH(engineVersion)
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set the engine version
|
||||
/// \param ver A version struct containing the new version
|
||||
void set_engine_version(const version& ver) {
|
||||
engineVersion = VK_MAKE_VERSION(ver.major, ver.minor, ver.patch);
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns A version struct containing the Vulkan API version
|
||||
version get_api_version() const {
|
||||
return version {
|
||||
.major = VK_API_VERSION_MAJOR(apiVersion),
|
||||
.minor = VK_API_VERSION_MINOR(apiVersion)
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set the Vulkan API version
|
||||
/// \param ver A version struct containing the new version
|
||||
void set_api_version(const version& ver) {
|
||||
apiVersion = VK_MAKE_API_VERSION(0, ver.major, ver.minor, 0);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Set the extension structure
|
||||
/// \param ext A pointer to the new extension object
|
||||
void set_extension(void* ext) {
|
||||
pNext = ext;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Clear the extension structure with \f$nullptr\f$
|
||||
void set_extension(nullptr_t) {
|
||||
pNext = nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Private Members =====================================================================================================
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_VULKAN_LIB_APP_INFO_H
|
||||
89
include/fennec/renderers/vulkan/lib/instance.h
Normal file
89
include/fennec/renderers/vulkan/lib/instance.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
///
|
||||
/// \file instance.h
|
||||
/// \brief
|
||||
///
|
||||
///
|
||||
/// \details
|
||||
/// \author Medusa Slockbower
|
||||
///
|
||||
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||
///
|
||||
///
|
||||
|
||||
|
||||
#ifndef FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H
|
||||
#define FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H
|
||||
|
||||
#include <volk.h>
|
||||
#include <fennec/containers/dynarray.h>
|
||||
|
||||
#include <fennec/renderers/vulkan/lib/app_info.h>
|
||||
|
||||
namespace fennec::vk
|
||||
{
|
||||
|
||||
struct instance {
|
||||
public:
|
||||
using create_flags = VkInstanceCreateFlags;
|
||||
|
||||
struct create_info : private VkInstanceCreateInfo {
|
||||
public:
|
||||
template<size_t LayersN, size_t ExtensionsN>
|
||||
create_info(
|
||||
create_flags flags, const app_info& info,
|
||||
const cstring (&layers)[LayersN], const cstring (&extensions)[ExtensionsN],
|
||||
void* ext
|
||||
) : VkInstanceCreateInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = ext,
|
||||
.flags = flags,
|
||||
.pApplicationInfo = info,
|
||||
.enabledLayerCount = LayersN,
|
||||
.ppEnabledLayerNames = nullptr,
|
||||
.enabledExtensionCount = ExtensionsN,
|
||||
.ppEnabledExtensionNames = nullptr,
|
||||
} {
|
||||
_layers.reserve(LayersN);
|
||||
for (const auto& layer : layers) { _layers.push_back(layer); }
|
||||
|
||||
_extensions.reserve(ExtensionsN);
|
||||
for (const auto& extension : extensions) { _extensions.push_back(extension); }
|
||||
|
||||
ppEnabledLayerNames = _layers.data();
|
||||
ppEnabledExtensionNames = _extensions.data();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
dynarray<const char*> _layers;
|
||||
dynarray<const char*> _extensions;
|
||||
};
|
||||
|
||||
instance();
|
||||
|
||||
private:
|
||||
VkInstance _handle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_VULKAN_LIB_INSTANCE_H
|
||||
@@ -23,7 +23,6 @@ namespace fennec {
|
||||
|
||||
vkcontext::vkcontext(display_server* display)
|
||||
: gfxcontext(display) {
|
||||
|
||||
}
|
||||
|
||||
vkcontext::~vkcontext() {
|
||||
|
||||
@@ -40,15 +40,14 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class vkcontext : gfxcontext {
|
||||
class vkcontext : public gfxcontext {
|
||||
public:
|
||||
vkcontext(display_server* display);
|
||||
~vkcontext();
|
||||
|
||||
bool is_valid() override;
|
||||
|
||||
private:
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
} // fennec
|
||||
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
typelist.resize(uuid * 2);
|
||||
}
|
||||
|
||||
if (typelist[uuid].empty()) {
|
||||
if (typelist[uuid].is_empty()) {
|
||||
typelist[uuid] = fennec::forward<unique_ptr<type_data>>(_make_data<T>());
|
||||
}
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ public:
|
||||
/// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator
|
||||
constexpr cstring(char* str, size_t n)
|
||||
: _str(str)
|
||||
, _size(n - 1)
|
||||
, _size(n)
|
||||
, _const(false) {
|
||||
if constexpr(not is_constant_evaluated()) {
|
||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||
assert(_str[n] == '\0', "Invalid NTBS.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,10 +114,10 @@ public:
|
||||
/// \note If used with `::strlen`, the result should be incremented by 1 to include the null terminator
|
||||
constexpr cstring(const char* str, size_t n)
|
||||
: _cstr(str)
|
||||
, _size(n - 1)
|
||||
, _size(n)
|
||||
, _const(true) {
|
||||
if constexpr(not is_constant_evaluated()) {
|
||||
assert(_str[n - 1] == '\0', "Invalid NTBS.");
|
||||
assert(_str[n] == '\0', "Invalid NTBS.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ public:
|
||||
return _size + 1;
|
||||
}
|
||||
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _cstr == nullptr || _size == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ if the string contains no characters, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ public:
|
||||
/// \returns the size of the string including its null terminator, i.e. `(*str)[capacity() - 1] == '\0'`
|
||||
constexpr size_t capacity() const { return _size + 1; }
|
||||
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return _cstr == nullptr || _size == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
|
||||
///
|
||||
/// \returns \f$true\f$ if the string contains no characters, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
constexpr bool is_empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
return _data.capacity();
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
bool is_empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ path path::current() {
|
||||
if (getcwd(cstr, sizeof(cstr)) == nullptr) {
|
||||
return path("");
|
||||
}
|
||||
return path(cstring(cstr, strlen(cstr) + 1));
|
||||
return path(cstring(cstr, strlen(cstr)));
|
||||
}
|
||||
|
||||
path path::current(const path& path) {
|
||||
|
||||
@@ -30,7 +30,7 @@ void _assert_impl(const char* expr, size_t expr_l,
|
||||
fennec::cstring(expr, expr_l),
|
||||
fennec::cstring(file, file_l), line,
|
||||
fennec::cstring(func, func_l),
|
||||
fennec::cstring(desc, ::strlen(desc) + 1)
|
||||
fennec::cstring(desc, ::strlen(desc))
|
||||
);
|
||||
|
||||
if (halt) {
|
||||
|
||||
@@ -112,7 +112,7 @@ void wayland_server::connect() {
|
||||
#endif
|
||||
|
||||
auto contexts = ctx_registry::get_type_list();
|
||||
while (not contexts.empty()) {
|
||||
while (not contexts.is_empty()) {
|
||||
const auto& ctx = contexts.front();
|
||||
gfx_context = unique_ptr(ctx.ctor(this));
|
||||
|
||||
@@ -125,7 +125,7 @@ void wayland_server::connect() {
|
||||
}
|
||||
}
|
||||
|
||||
assertf(not gfx_context.empty(), "Failed to create graphics context.");
|
||||
assertf(not gfx_context.is_empty(), "Failed to create graphics context.");
|
||||
}
|
||||
|
||||
void wayland_server::disconnect() {
|
||||
@@ -191,7 +191,7 @@ void wayland_server::_wl_registry_listen_global(void* data, wl_registry* reg, ui
|
||||
};
|
||||
|
||||
wayland_server* server = static_cast<wayland_server*>(data);
|
||||
const cstring interface = cstring(name, strlen(name) + 1);
|
||||
const cstring interface = cstring(name, strlen(name));
|
||||
|
||||
if (interface == "wl_compositor") {
|
||||
server->compositor = static_cast<wl_compositor*>(wl_registry_bind(reg, id, &wl_compositor_interface, version));
|
||||
|
||||
@@ -44,7 +44,7 @@ void window_manager::initialize() {
|
||||
display_server::entrylist_t display_servers = display_server::get_type_list();
|
||||
|
||||
// Find first valid server
|
||||
while (not display_servers.empty()) {
|
||||
while (not display_servers.is_empty()) {
|
||||
display_server::entry it = display_servers.front();
|
||||
display_servers.pop();
|
||||
|
||||
|
||||
@@ -21,8 +21,5 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
gfxpass* glcontext::create_pass() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace fennec
|
||||
scene_node* scene::operator[](const cstring& name) const {
|
||||
list<size_t> parse;
|
||||
parse.push_back(table_t::root);
|
||||
while (not parse.empty()) {
|
||||
while (not parse.is_empty()) {
|
||||
size_t n = parse.front();
|
||||
if (_table[n]->name == name) {
|
||||
return _table[n].get();
|
||||
@@ -54,7 +54,7 @@ scene_node* scene::operator[](const cstring& name) const {
|
||||
scene_node* scene::operator[](const string& name) const {
|
||||
list<size_t> parse;
|
||||
parse.push_back(table_t::root);
|
||||
while (not parse.empty()) {
|
||||
while (not parse.is_empty()) {
|
||||
size_t n = parse.front();
|
||||
if (_table[n]->name == name) {
|
||||
return _table[n].get();
|
||||
|
||||
@@ -51,7 +51,7 @@ inline void fennec_test_containers_bintree() {
|
||||
|
||||
test.clear();
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
fennec_test_spacer(1);
|
||||
|
||||
@@ -98,7 +98,7 @@ inline void fennec_test_containers_bintree() {
|
||||
|
||||
test.clear();
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ inline void fennec_test_containers_deque() {
|
||||
test.pop_back();
|
||||
}
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ inline void fennec_test_containers_graph() {
|
||||
test.erase(i);
|
||||
}
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ inline void fennec_test_containers_list() {
|
||||
assertf(test.insert(p, i) == i, "List Construct Test Failed.");
|
||||
}
|
||||
|
||||
while (test.empty() == false) {
|
||||
while (test.is_empty() == false) {
|
||||
test.pop_back();
|
||||
}
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ inline void fennec_test_containers_object_pool() {
|
||||
test.erase(i);
|
||||
}
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ inline void fennec_test_containers_rdtree() {
|
||||
|
||||
test.erase(0);
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
fennec_test_spacer(1);
|
||||
|
||||
@@ -108,7 +108,7 @@ inline void fennec_test_containers_rdtree() {
|
||||
|
||||
test.erase(0);
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ inline void fennec_test_containers_sequence() {
|
||||
test.erase(v);
|
||||
}
|
||||
|
||||
fennec_test_run(test.empty(), true);
|
||||
fennec_test_run(test.is_empty(), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ inline void fennec_test_threading_test_mpscq_producer(mpscq<size_t>* queue, size
|
||||
}
|
||||
|
||||
inline void fennec_test_threading_test_mpscq_consumer(mpscq<size_t>* queue, atomic<size_t>* res, atomic<bool>* done) {
|
||||
while (not done->load() or not queue->empty()) {
|
||||
while (not done->load() or not queue->is_empty()) {
|
||||
unique_ptr<size_t> ptr = queue->pop();
|
||||
if (ptr) {
|
||||
*res += *ptr;
|
||||
|
||||
Reference in New Issue
Block a user