Compare commits
2 Commits
2117e4347c
...
7ea2710ee0
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ea2710ee0 | |||
| f9de242b87 |
@@ -174,6 +174,8 @@ add_library(fennec STATIC
|
||||
include/fennec/lang/type_operators.h
|
||||
include/fennec/containers/tuple.h
|
||||
include/fennec/containers/detail/__tuple.h
|
||||
include/fennec/platform/linux/wayland/window.h
|
||||
include/fennec/containers/list.h
|
||||
)
|
||||
|
||||
add_dependencies(fennec metaprogramming)
|
||||
|
||||
@@ -47,12 +47,12 @@ public:
|
||||
|
||||
///
|
||||
/// \brief Default Constructor, initializes an empty allocation.
|
||||
dynarray() : _alloc(8), _size(0) {}
|
||||
constexpr dynarray() : _alloc(8), _size(0) {}
|
||||
|
||||
///
|
||||
/// \brief Alloc Constructor, initialize empty allocation with allocator instance.
|
||||
/// \param alloc An allocator object to copy, for instances where the allocator needs to be initialized with some data.
|
||||
dynarray(const alloc_t& alloc)
|
||||
constexpr dynarray(const alloc_t& alloc)
|
||||
: _alloc(8, alloc)
|
||||
, _size(0) {
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
///
|
||||
/// \brief Sized Allocation, create an allocation with a size of `n` elements, initialized with the default constructor.
|
||||
dynarray(size_t n)
|
||||
constexpr dynarray(size_t n)
|
||||
: _alloc(n)
|
||||
, _size(n)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
/// \brief
|
||||
/// \param n
|
||||
/// \param alloc
|
||||
dynarray(size_t n, const alloc_t& alloc)
|
||||
constexpr dynarray(size_t n, const alloc_t& alloc)
|
||||
: _alloc(n, alloc)
|
||||
, _size(n) {
|
||||
element_t* addr = _alloc.data();
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
///
|
||||
/// \brief Create an allocation of size `n`, with each element constructed using the copy constructor
|
||||
/// \brief n the number of elements
|
||||
dynarray(size_t n, const TypeT& val)
|
||||
constexpr dynarray(size_t n, const TypeT& val)
|
||||
: _alloc(n)
|
||||
, _size(n) {
|
||||
element_t* addr = _alloc.data();
|
||||
@@ -96,37 +96,49 @@ public:
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
dynarray(size_t n, ArgsT&&...args) {
|
||||
constexpr dynarray(size_t n, ArgsT&&...args) {
|
||||
element_t* addr = _alloc.data();
|
||||
for(; n > 0; --n, ++addr) {
|
||||
fennec::construct(addr, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
~dynarray() {
|
||||
constexpr ~dynarray() {
|
||||
element_t* addr = _alloc.data();
|
||||
for(int n = _size; n > 0; --n, ++addr) {
|
||||
fennec::destruct(addr);
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
constexpr size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
constexpr size_t capacity() const {
|
||||
return _alloc.capacity();
|
||||
}
|
||||
|
||||
TypeT& operator[](size_t i) {
|
||||
constexpr bool empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
constexpr TypeT& operator[](size_t i) {
|
||||
assertd(i < _size, "Array Out of Bounds"); return _alloc.data()[i];
|
||||
}
|
||||
|
||||
const TypeT& operator[](size_t i) const {
|
||||
constexpr const TypeT& operator[](size_t i) const {
|
||||
assertd(i < _size, "Array Out of Bounds"); return _alloc.data()[i];
|
||||
}
|
||||
|
||||
void insert(size_t i, const TypeT& val) {
|
||||
constexpr TypeT& back() {
|
||||
return this->operator[](size() - 1);
|
||||
}
|
||||
|
||||
constexpr const TypeT& back() const {
|
||||
return this->operator[](size() - 1);
|
||||
}
|
||||
|
||||
constexpr void insert(size_t i, const TypeT& val) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) {
|
||||
@@ -146,7 +158,7 @@ public:
|
||||
++_size;
|
||||
}
|
||||
|
||||
void insert(size_t i, TypeT&& val) {
|
||||
constexpr void insert(size_t i, TypeT&& val) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) {
|
||||
@@ -167,7 +179,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
void emplace(size_t i, ArgsT&&...args) {
|
||||
constexpr void emplace(size_t i, ArgsT&&...args) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) {
|
||||
@@ -187,24 +199,29 @@ public:
|
||||
++_size;
|
||||
}
|
||||
|
||||
void push_back(const TypeT& val) {
|
||||
constexpr void push_back(const TypeT& val) {
|
||||
dynarray::insert(_size, val);
|
||||
}
|
||||
|
||||
void push_back(TypeT&& val) {
|
||||
constexpr void push_back(TypeT&& val) {
|
||||
dynarray::insert(_size, fennec::forward<TypeT>(val));
|
||||
}
|
||||
|
||||
template<typename...ArgsT> void emplace_back(ArgsT...args) {
|
||||
constexpr void pop_back() {
|
||||
_alloc[_size--].~TypeT();
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr void emplace_back(ArgsT...args) {
|
||||
dynarray::emplace(_size, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
void resize(size_t n) {
|
||||
constexpr void resize(size_t n) {
|
||||
_alloc.reallocate(n);
|
||||
}
|
||||
|
||||
private:
|
||||
void _grow() {
|
||||
constexpr void _grow() {
|
||||
_alloc.reallocate(_alloc.capacity() * 2);
|
||||
}
|
||||
|
||||
|
||||
205
include/fennec/containers/list.h
Normal file
205
include/fennec/containers/list.h
Normal file
@@ -0,0 +1,205 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_LIST_H
|
||||
#define FENNEC_CONTAINERS_LIST_H
|
||||
|
||||
#include <fennec/containers/dynarray.h>
|
||||
#include <fennec/containers/optional.h>
|
||||
#include <fennec/memory/allocator.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||
struct list {
|
||||
public:
|
||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<TypeT>;
|
||||
using value_t = TypeT;
|
||||
static constexpr size_t npos = -1;
|
||||
|
||||
private:
|
||||
struct node {
|
||||
optional<value_t> data;
|
||||
size_t prev, next;
|
||||
|
||||
constexpr node()
|
||||
: data()
|
||||
, prev(npos)
|
||||
, next(npos) {
|
||||
}
|
||||
|
||||
constexpr node(size_t p, size_t n)
|
||||
: data()
|
||||
, prev(p)
|
||||
, next(n) {
|
||||
}
|
||||
|
||||
constexpr node(size_t p, size_t n, value_t&& val)
|
||||
: data(fennec::forward<value_t>(val))
|
||||
, prev(p)
|
||||
, next(n) {
|
||||
}
|
||||
|
||||
constexpr ~node() = default;
|
||||
|
||||
constexpr void clear() {
|
||||
data = nullopt;
|
||||
prev = npos;
|
||||
next = npos;
|
||||
}
|
||||
};
|
||||
|
||||
size_t _next(size_t n) {
|
||||
return _table[n].next;
|
||||
}
|
||||
|
||||
size_t _prev(size_t n) {
|
||||
return _table[n].prev;
|
||||
}
|
||||
|
||||
size_t _walk(size_t i) {
|
||||
size_t n = _root;
|
||||
if (n == npos) return n;
|
||||
while (i > 0 && n != npos) {
|
||||
n = _next(n); --i;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t _next_free(size_t i) {
|
||||
if (not _freed.empty()) {
|
||||
size_t n = _freed.back();
|
||||
_freed.pop_back();
|
||||
return n;
|
||||
}
|
||||
_table[_size];
|
||||
}
|
||||
|
||||
public:
|
||||
using elem_t = node;
|
||||
|
||||
constexpr list()
|
||||
: _table(), _root(npos), _last(npos), _freed(), _size(0) {
|
||||
}
|
||||
|
||||
constexpr ~list() = default;
|
||||
|
||||
constexpr bool size() const { return _size; }
|
||||
constexpr bool capacity() const { return _table.capacity(); }
|
||||
constexpr bool empty() const { return _root == npos; }
|
||||
|
||||
constexpr value_t& operator[](int i) {
|
||||
assertd(i >= 0, "Index out of Bounds");
|
||||
size_t n = _walk(i);
|
||||
assertd(n != npos, "Index out of Bounds");
|
||||
return _table[n].data;
|
||||
}
|
||||
|
||||
constexpr const value_t& operator[](int i) const {
|
||||
assertd(i >= 0, "Index out of Bounds");
|
||||
size_t n = _walk(i);
|
||||
assertd(n != npos, "Index out of Bounds");
|
||||
return _table[n].data;
|
||||
}
|
||||
|
||||
void insert(size_t i, value_t&& x) {
|
||||
assert(i <= size(), "Index out of Bounds");
|
||||
if (size() == capacity()) {
|
||||
_expand();
|
||||
}
|
||||
size_t n = _walk(min(i, size() - 1));
|
||||
size_t p = _next_free(i);
|
||||
if (n == npos) {
|
||||
_root = p;
|
||||
_table[p].data = fennec::forward<value_t>(x);
|
||||
return;
|
||||
}
|
||||
_table[p].data = fennec::forward<value_t>(x);
|
||||
_table[p].next = n;
|
||||
_table[p].prev = _prev(p);
|
||||
_table[n].prev = p;
|
||||
++_size;
|
||||
|
||||
_last = (n == npos) ? p : _last;
|
||||
}
|
||||
|
||||
void insert(size_t i, const value_t& x) {
|
||||
this->insert(i, elem_t(x));
|
||||
}
|
||||
|
||||
void push_front(const value_t& x) {
|
||||
this->insert(0, x);
|
||||
}
|
||||
|
||||
void push_front(value_t&& x) {
|
||||
this->insert(0, fennec::forward<value_t>(x));
|
||||
}
|
||||
|
||||
void push_back(const value_t& x) {
|
||||
this->insert(_size, x);
|
||||
}
|
||||
|
||||
void push_back(value_t&& x) {
|
||||
this->insert(_size, fennec::forward<value_t>(x));
|
||||
}
|
||||
|
||||
void erase(size_t i) {
|
||||
size_t j = _walk(i);
|
||||
if (j == npos) return;
|
||||
if (not _table[j].data) return;
|
||||
|
||||
// Get the prev and next indices
|
||||
size_t p = _prev(j);
|
||||
size_t n = _next(j);
|
||||
|
||||
// clear the node
|
||||
_table[j].data = nullopt;
|
||||
_table[j].prev = npos;
|
||||
_table[j].next = npos;
|
||||
|
||||
// Fix prev and next nodes
|
||||
if (p != npos) _table[p].next = n;
|
||||
if (n != npos) _table[n].prev = p;
|
||||
else _last = j;
|
||||
|
||||
// Mark node as freed
|
||||
_freed.push_back(j);
|
||||
}
|
||||
|
||||
void pop_front() {
|
||||
erase(0);
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
erase(_size - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
allocation<elem_t, alloc_t> _table;
|
||||
dynarray<size_t> _freed;
|
||||
size_t _root, _last, _size;
|
||||
|
||||
constexpr void _expand() {
|
||||
_table.reallocate(_table.capacity() * 2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_LIST_H
|
||||
@@ -52,30 +52,30 @@ struct pair {
|
||||
constexpr pair(const pair&) = default;
|
||||
constexpr pair(pair&&) noexcept = default;
|
||||
|
||||
pair& operator=(const pair&) = default;
|
||||
pair& operator=(pair&&) noexcept = default;
|
||||
constexpr pair& operator=(const pair&) = default;
|
||||
constexpr pair& operator=(pair&&) noexcept = default;
|
||||
|
||||
bool operator==(const pair& p) const {
|
||||
constexpr bool operator==(const pair& p) const {
|
||||
return first == p.first and second == p.second;
|
||||
}
|
||||
|
||||
bool operator!=(const pair& p) const {
|
||||
constexpr bool operator!=(const pair& p) const {
|
||||
return first != p.first or second != p.second;
|
||||
}
|
||||
|
||||
bool operator<(const pair& p) const {
|
||||
constexpr bool operator<(const pair& p) const {
|
||||
return first < p.first or (first == p.first and second < p.second);
|
||||
}
|
||||
|
||||
bool operator<=(const pair& p) const {
|
||||
constexpr bool operator<=(const pair& p) const {
|
||||
return first < p.first or (first == p.first and second <= p.second);
|
||||
}
|
||||
|
||||
bool operator>(const pair& p) const {
|
||||
constexpr bool operator>(const pair& p) const {
|
||||
return first > p.first or (first == p.first and second > p.second);
|
||||
}
|
||||
|
||||
bool operator>=(const pair& p) const {
|
||||
constexpr bool operator>=(const pair& p) const {
|
||||
return first > p.first or (first == p.first and second >= p.second);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
if (_equal(*_alloc[i].value, val)) { // Check to see if this element is already inserted
|
||||
return;
|
||||
}
|
||||
if (psl >= _alloc[i].psl) { // When psl is higher, swap
|
||||
if (psl > _alloc[i].psl) { // When psl is higher, swap
|
||||
fennec::swap(*_alloc[i].value, value);
|
||||
fennec::swap(_alloc[i].psl, psl);
|
||||
}
|
||||
|
||||
@@ -31,14 +31,14 @@ template<typename...TypesT> struct tuple;
|
||||
|
||||
|
||||
template<size_t i, typename...TypesT>
|
||||
typename tuple<TypesT...>::template elem_t<i>& get(tuple<TypesT...>& x) {
|
||||
constexpr typename tuple<TypesT...>::template elem_t<i>& get(tuple<TypesT...>& x) {
|
||||
using elem_t = typename tuple<TypesT...>::template elem_t<i>;
|
||||
auto it = static_cast<detail::__tuple_leaf<i, elem_t>>(x);
|
||||
auto& it = static_cast<detail::__tuple_leaf<i, elem_t>>(x);
|
||||
return it;
|
||||
}
|
||||
|
||||
template<size_t i, typename...TypesT>
|
||||
const typename tuple<TypesT...>::template elem_t<i>& get(tuple<TypesT...>& x) {
|
||||
constexpr const typename tuple<TypesT...>::template elem_t<i>& get(tuple<TypesT...>& x) {
|
||||
using elem_t = typename tuple<TypesT...>::template elem_t<i>;
|
||||
auto& it = static_cast<detail::__tuple_leaf<i, elem_t>>(x);
|
||||
return it;
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
using elem_t = nth_element<i, TypesT...>;
|
||||
|
||||
template<typename...ArgsT>
|
||||
tuple(ArgsT&&...args) : base_t(args...) {
|
||||
constexpr tuple(ArgsT&&...args) : base_t(args...) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ public:
|
||||
};
|
||||
|
||||
virtual bool connected() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~display() = default;
|
||||
|
||||
private:
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
class wayland_display : public display {
|
||||
public:
|
||||
wayland_display(linux_platform* platform);
|
||||
@@ -46,6 +43,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
namespace libwayland
|
||||
{
|
||||
|
||||
bool load_symbols(linux_platform* platform);
|
||||
|
||||
33
include/fennec/platform/linux/wayland/window.h
Normal file
33
include/fennec/platform/linux/wayland/window.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class wayland_window {
|
||||
public:
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
|
||||
@@ -28,8 +28,6 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
using namespace wayland;
|
||||
|
||||
linux_platform::linux_platform(user _type)
|
||||
: platform(_type)
|
||||
, _display_driver(display_none) {
|
||||
@@ -45,7 +43,10 @@ linux_platform::linux_platform(user _type)
|
||||
}
|
||||
|
||||
linux_platform::~linux_platform() {
|
||||
|
||||
if (_display) {
|
||||
delete _display;
|
||||
_display = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
shared_object* linux_platform::load_object(const cstring& file) {
|
||||
@@ -77,10 +78,10 @@ display* linux_platform::get_display() {
|
||||
|
||||
void linux_platform::_runtime_client_checks() {
|
||||
#ifdef FENNEC_LIB_WAYLAND
|
||||
if (wayland::load_symbols(this)) {
|
||||
if (libwayland::load_symbols(this)) {
|
||||
_display_driver = display_wayland;
|
||||
_display = new wayland_display(this);
|
||||
wayland::unload_symbols(this); // Doesn't actually unload symbols, just resets ref counter to only consider
|
||||
libwayland::unload_symbols(this); // Doesn't actually unload symbols, just resets ref counter to only consider
|
||||
// the created display
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,14 +23,11 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
wayland_display::wayland_display(linux_platform* platform)
|
||||
: display()
|
||||
, _handle()
|
||||
, _platform(platform) {
|
||||
load_symbols(_platform);
|
||||
libwayland::load_symbols(_platform);
|
||||
_handle = wl_display_connect(nullptr);
|
||||
}
|
||||
|
||||
@@ -38,13 +35,13 @@ wayland_display::wayland_display(linux_platform* platform, const cstring& drv)
|
||||
: display()
|
||||
, _handle()
|
||||
, _platform(platform) {
|
||||
load_symbols(_platform);
|
||||
libwayland::load_symbols(_platform);
|
||||
_handle = wl_display_connect(drv);
|
||||
}
|
||||
|
||||
wayland_display::~wayland_display() {
|
||||
wl_display_disconnect(_handle);
|
||||
unload_symbols(_platform);
|
||||
libwayland::unload_symbols(_platform);
|
||||
_handle = nullptr;
|
||||
_platform = nullptr;
|
||||
}
|
||||
@@ -53,6 +50,4 @@ bool wayland_display::connected() const {
|
||||
return _handle != nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
namespace libwayland
|
||||
{
|
||||
|
||||
using shared_lib = platform::shared_lib;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
namespace fennec::test
|
||||
{
|
||||
|
||||
using namespace wayland;
|
||||
|
||||
inline void fennec_test_platform_linux_wayland(linux_platform& platform) {
|
||||
|
||||
wayland_display* display = static_cast<wayland_display*>(platform.get_display());
|
||||
|
||||
Reference in New Issue
Block a user