- More documentation

This commit is contained in:
2025-12-18 16:18:07 -05:00
parent 9e6f00eb60
commit 88e33bdcc8
50 changed files with 987 additions and 264 deletions

View File

@@ -136,7 +136,7 @@ fennec_add_sources(
include/fennec/containers/detail/_tuple.h
# lang =================================================================================================================
# lang =================================================================================================================
include/fennec/lang/lang.h
include/fennec/lang/metaprogramming.h
@@ -145,6 +145,7 @@ fennec_add_sources(
include/fennec/lang/constants.h
include/fennec/lang/conditional_types.h
include/fennec/lang/declval.h
include/fennec/lang/function.h
include/fennec/lang/hashing.h
include/fennec/lang/intrinsics.h
include/fennec/lang/limits.h
@@ -165,6 +166,7 @@ fennec_add_sources(
include/fennec/lang/detail/_bits.h
include/fennec/lang/detail/_declval.h
include/fennec/lang/detail/_function.h
include/fennec/lang/detail/_int.h
include/fennec/lang/detail/_numeric_transforms.h
include/fennec/lang/detail/_stdlib.h
@@ -173,7 +175,7 @@ fennec_add_sources(
include/fennec/lang/detail/_type_sequences.h
# RTTI =================================================================================================================
# RTTI =================================================================================================================
include/fennec/rtti/typeid.h
include/fennec/rtti/type_data.h
include/fennec/rtti/type.h
@@ -190,7 +192,7 @@ fennec_add_sources(
include/fennec/rtti/detail/_type_name.h
# MEMORY ===============================================================================================================
# MEMORY ===============================================================================================================
include/fennec/memory/new.h source/memory/new.cpp
include/fennec/memory/allocator.h
@@ -202,11 +204,11 @@ fennec_add_sources(
include/fennec/memory/detail/_ptr_traits.h
# DEBUG ================================================================================================================
# DEBUG ================================================================================================================
source/debug/assert_impl.cpp
# MATH =================================================================================================================
# MATH =================================================================================================================
include/fennec/math/math.h
include/fennec/math/scalar.h
@@ -243,7 +245,16 @@ fennec_add_sources(
# string ===============================================================================================================
# threading ============================================================================================================
include/fennec/threading/atomic.h
include/fennec/threading/thread.h
include/fennec/threading/detail/_thread.h
# string ===============================================================================================================
include/fennec/string/locale.h
include/fennec/string/cstring.h
include/fennec/string/string.h
@@ -252,7 +263,7 @@ fennec_add_sources(
# format ===============================================================================================================
# format ===============================================================================================================
include/fennec/format/format.h
include/fennec/format/format_arg.h
include/fennec/format/formatter.h
@@ -264,26 +275,26 @@ fennec_add_sources(
# filesystem ===========================================================================================================
# filesystem ===========================================================================================================
include/fennec/filesystem/file.h source/filesystem/file.cpp
include/fennec/filesystem/path.h source/filesystem/path.cpp
# interpret ============================================================================================================
# interpret ============================================================================================================
include/fennec/interpret/tokenizer.h
# PLATFORM =============================================================================================================
# PLATFORM =============================================================================================================
include/fennec/platform/interface/fwd.h
include/fennec/platform/interface/display_server.h
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
include/fennec/platform/interface/window.h source/platform/interface/window.cpp
include/fennec/platform/window_manager.h source/platform/window_manager.cpp
# GRAPHICS =============================================================================================================
# GRAPHICS =============================================================================================================
include/fennec/gfx3d/mesh_instance.h
)
# add the test suite as a sub-project
@@ -291,14 +302,6 @@ add_subdirectory(test)
add_library(fennec STATIC
${FENNEC_SOURCES}
include/fennec/platform/window_manager.h
include/fennec/platform/window_manager.cpp
include/fennec/platform/window_manager.h
include/fennec/lang/function.h
include/fennec/threading/thread.h
include/fennec/threading/detail/_thread.h
include/fennec/lang/detail/_function.h
include/fennec/threading/atomic.h
)

View File

@@ -424,17 +424,17 @@ public:
///
/// \brief C++ Iterator Specification `end()`
/// \returns An iterator for the end of the list
constexpr iterator end() {
return iterator(this, npos);
}
///
/// \returns A const iterator for the first element in the list
constexpr const_iterator begin() const {
return const_iterator(this, _root);
}
///
/// \returns An iterator for the end of the list
constexpr iterator end() {
return iterator(this, npos);
}
///
/// \brief Const C++ Iterator Specification `end()`
/// \returns A const iterator for the end of the list

View File

@@ -362,6 +362,7 @@ public:
/// @{
///
/// \brief C++ Iterator Specification `begin()`
/// \returns An iterator for all elements of the set in no particular order
constexpr iterator begin() const {
iterator it(this, 0);
@@ -372,6 +373,7 @@ public:
}
///
/// \brief C++ Iterator Specification `end()`
/// \returns An iterator representing the end of the set
constexpr iterator end() const {
return iterator(this, npos);

View File

@@ -1,47 +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 mesh_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_GFX3D_MESH_INSTANCE_H
#define FENNEC_GFX3D_MESH_INSTANCE_H
#include <fennec/scene/component.h>
namespace fennec
{
class mesh_instance : component {
public:
private:
};
}
#endif // FENNEC_GFX3D_MESH_INSTANCE_H

View File

@@ -55,7 +55,8 @@
namespace fennec
{
///
/// \brief Escape Sequence Specification
struct escape_sequence {
virtual size_t operator[](const string& str, size_t i) = 0;
};

View File

@@ -68,21 +68,32 @@
#define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
using assert_handler = void (*)(const char *, const char *, int , const char *);
#ifndef FENNEC_DOXYGEN
void _assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc, bool halt);
#endif
// flagged unlikely to optimize branch prediction
///
/// \brief base assert function, halts only in debug mode
/// \param expression the expression to validate
/// \param description the description of the assertion
#define assert(expression, description) \
if(not(expression)) [[unlikely]] { \
_assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \
}
///
/// \brief fail assert function, always halts
/// \param expression the expression to validate
/// \param description the description of the assertion
#define assertf(expression, description) \
if(not(expression)) [[unlikely]] { \
_assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \
}
///
/// \brief debug assert function, only defined in debug mode
/// \param expression the expression to validate
/// \param description the description of the assertion
#if FENNEC_RELEASE
#define assertd(expression, description)
#else

View File

@@ -26,27 +26,58 @@ namespace fennec
// equality ============================================================================================================
///
/// \brief Struct to test equality of two values
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> struct equality;
///
/// \brief Implementations for two types that have a common equality operator \f$==\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires has_equals_v<T0, T1>
struct equality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x == y;
}
};
///
/// \brief Implementations for two types that have a common less operator \f$<\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires(not has_equals_v<T0, T1>
and has_less_v<T0, T1> and has_less_v<T1, T0>)
struct equality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return not(x < y) and not(y < x);
}
};
///
/// \brief Implementations for two types that have a common greater operator \f$>\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires(not(has_equals_v<T0, T1>)
and(not has_less_v<T0, T1> or not has_less_v<T1, T0>)
and(has_greater_v<T0, T1> and has_greater_v<T1, T0>))
struct equality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return not(x > y) and not(y > x);
}
@@ -55,24 +86,72 @@ struct equality<T0, T1> {
// inequality ==========================================================================================================
///
/// \brief Struct to test inequality of two values
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> struct inequality;
///
/// \brief Implementations for two types that have a common inequality operator \f$\neq\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires has_nequals_v<T0, T1>
struct inequality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if not equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x != y;
}
};
///
/// \brief Implementations for two types that have a common equality operator \f$==\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires has_equals_v<T0, T1>
struct inequality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if not equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return not (x == y);
}
};
///
/// \brief Implementations for two types that have a common less operator \f$<\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires has_less_v<T0, T1> and has_less_v<T1, T0>
struct inequality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if not equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return (x < y) or (y < x);
}
};
///
/// \brief Implementations for two types that have a common greater operator \f$>\f$
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1> requires has_greater_v<T0, T1> and has_greater_v<T1, T0>
struct inequality<T0, T1> {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if not equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return (x > y) or (y > x);
}
@@ -81,8 +160,17 @@ struct inequality<T0, T1> {
// less ================================================================================================================
///
/// \brief Struct to test if a value of type `T0` is less than a value of type `T1`
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> requires has_less_v<T0, T1>
struct less {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if less, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x < y;
}
@@ -91,30 +179,57 @@ struct less {
// less_equal ==========================================================================================================
///
/// \brief Struct to test if a value of type `T0` is less than or equal to a value of type `T1`
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> requires has_less_equals_v<T0, T1>
struct less_equals {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if less than or equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x <= y;
}
};
// less ================================================================================================================
// greater =============================================================================================================
///
/// \brief Struct to test if a value of type `T0` is greater than a value of type `T1`
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> requires has_greater_v<T0, T1>
struct greater {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if greater, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x < y;
return x > y;
}
};
// less_equal ==========================================================================================================
///
/// \brief Struct to test if a value of type `T0` is greater than or equal to a value of type `T1`
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0> requires has_greater_equals_v<T0, T1>
struct greater_equals {
///
/// \brief operator to test the two values
/// \param x the value of type \f$T0\f$
/// \param y the value of type \f$T1\f$
/// \returns \f$true\f$ if greater than or equal, \f$false\f$ otherwise
constexpr bool operator()(const T0& x, const T1& y) const {
return x <= y;
return x >= y;
}
};

View File

@@ -89,7 +89,7 @@ template<bool B, typename TrueT, typename FalseT>
using conditional_t
= typename conditional<B, TrueT, FalseT>::type;
#ifndef FENNEC_DOXYGEN
// specialization of fennec::conditional for \f$true\f$ case
template<typename T, typename F>
struct conditional<true, T, F> : type_identity<T>{};
@@ -98,7 +98,7 @@ struct conditional<true, T, F> : type_identity<T>{};
// specialization of fennec::conditional for \f$false\f$ case
template<typename T, typename F>
struct conditional<false, T, F> : type_identity<F>{};
#endif
// fennec::detect ======================================================================================================
@@ -113,8 +113,8 @@ struct conditional<false, T, F> : type_identity<F>{};
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
struct detect
{
using type = DefaultT;
static constexpr bool is_detected = false;
using type = DefaultT; //!< the detected type
static constexpr bool is_detected = false; //!< whether it was detected
};
///
@@ -123,6 +123,7 @@ template<typename DefaultT, template<typename...> typename DetectT, typename...A
using detect_t = typename detect<DefaultT, DetectT, ArgsT...>::type;
#ifndef FENNEC_DOXYGEN
// true case
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
requires requires { typename DetectT<ArgsT...>; }
@@ -131,6 +132,7 @@ struct detect<DefaultT, DetectT, ArgsT...>
using type = DetectT<ArgsT...>;
static constexpr bool is_detected = true;
};
#endif
// fennec::enable_if ===================================================================================================
@@ -156,9 +158,11 @@ struct enable_if {};
template<bool B, typename T = void>
using enable_if_t = typename enable_if<B, T>::type;
#ifndef FENNEC_DOXYGEN
// true case
template<typename T>
struct enable_if<true, T> { using type = T; };
#endif
}

View File

@@ -28,8 +28,8 @@
///
///
#ifndef FENNEC_LANGCPP_DECLVAL_H
#define FENNEC_LANGCPP_DECLVAL_H
#ifndef FENNEC_LANG_DECLVAL_H
#define FENNEC_LANG_DECLVAL_H
#include <fennec/lang/detail/_declval.h>
@@ -38,6 +38,10 @@ namespace fennec
// fennec::declval =====================================================================================================
///
/// \brief Metaprogramming helper for testing values of type T
/// \tparam T the type
/// \returns a metavalue of type \f$T\f$
template<typename T> auto declval() noexcept -> decltype(detail::_declval<T>(0)) {
static_assert(detail::_declval_protector<T>{}, "declval must not be used");
return detail::_declval<T>(0);
@@ -45,4 +49,4 @@ template<typename T> auto declval() noexcept -> decltype(detail::_declval<T>(0))
}
#endif // FENNEC_LANGCPP_DECLVAL_H
#endif // FENNEC_LANG_DECLVAL_H

View File

@@ -40,39 +40,86 @@
namespace fennec
{
///
/// \brief a class capable of holding a function or non-capturing lambda
template<typename> class function;
///
/// \brief a class capable of holding a function or non-capturing lambda
/// \tparam ReturnT The return type of the function
/// \tparam ArgsT The argument types of the function
template<typename ReturnT, typename...ArgsT>
class function<ReturnT(ArgsT...)> {
public:
///
/// \brief default constructor
constexpr function() noexcept = default;
///
/// \brief destructor
constexpr ~function() = default;
constexpr function(const function&) noexcept = default;
constexpr function( function&&) noexcept = default;
///
/// \brief copy constructor
/// \param func the function to copy
constexpr function(const function& func) noexcept = default;
///
/// \brief move constructor
/// \param func the function to take ownership of
constexpr function(function&& func) noexcept = default;
///
/// \brief function constructor
/// \param func the function to capture
constexpr function(ReturnT (*func)(ArgsT...))
: call(func) {
}
///
/// \brief null constructor
constexpr function(nullptr_t) noexcept : function() {}
constexpr function& operator=(const function&) = default;
constexpr function& operator=(function&&) = default;
///
/// \brief copy assignment
/// \param func the function to copy
/// \returns a reference to self
constexpr function& operator=(const function& func) = default;
///
/// \brief move assignment
/// \param func the function to capture
/// \returns a reference to self
constexpr function& operator=(function&& func) = default;
///
/// \brief null assignment
/// \returns a reference to self
constexpr function& operator=(nullptr_t) {
call = nullptr;
return *this;
}
///
/// \brief function assignment
/// \param func the function to capture
/// \returns a reference to self
constexpr function& operator=(ReturnT (*func)(ArgsT...)) {
call = func;
return *this;
}
constexpr operator bool() const noexcept { return call != nullptr; }
///
/// \brief implicit bool check
/// \returns \f$true\f$ if a function is captured, \f$false\f$ otherwise
constexpr operator bool() const noexcept {
return call != nullptr;
}
///
/// \brief function call operator
/// \param args the arguments to call the function with
/// \returns the result of the function call
ReturnT operator()(ArgsT...args) const noexcept {
assertf(call != nullptr, "Attempted to call a null function object!");
return call(fennec::forward<ArgsT>(args)...);

View File

@@ -31,10 +31,13 @@ namespace fennec
/// \tparam Key The type to hash
template<typename Key> struct hash;
// Murmur3 Hash for 64-bit ints
/// \brief Murmur3 Hash for 64-bit ints
template<>
struct hash<uint64_t> {
using type_t = uint64_t;
using type_t = uint64_t; //!< the type of the hash
/// \brief hash operator
/// \param x the value to hash
/// \returns an integer hash for the value
constexpr size_t operator()(uint64_t x) const {
// Murmur3
x ^= x >> 33U;
@@ -46,16 +49,22 @@ struct hash<uint64_t> {
}
};
// Wrapper for casting ints
/// \brief Hashing for integer types
/// \tparam IntT the integer type
template<typename IntT>
requires is_integral_v<IntT>
struct hash<IntT> : hash<uint64_t> {
using type_t = IntT;
using type_t = IntT; //!< the type of the hash
};
// Wrapper for pointers
/// \brief Hashing for pointer types
/// \tparam PtrT The base type
template<typename PtrT>
struct hash<PtrT*> : hash<uintptr_t> {
using type_t = PtrT*; //!< the type of the hash
/// \brief hash operator
/// \param ptr the pointer to hash
/// \returns an integer hash for the value
constexpr size_t operator()(PtrT* ptr) const {
return hash<uintptr_t>::operator()((uintptr_t)(const void*)ptr);
}
@@ -64,6 +73,10 @@ struct hash<PtrT*> : hash<uintptr_t> {
// Float
template<>
struct hash<float> : hash<uint32_t> {
using type_t = float; //!< the type of the hash
/// \brief hash operator
/// \param x the value to hash
/// \returns an integer hash for the value
constexpr size_t operator()(float x) const {
return hash<uint32_t>::operator()(bit_cast<uint32_t>(x));
}
@@ -71,6 +84,10 @@ struct hash<float> : hash<uint32_t> {
template<>
struct hash<double> : hash<uint64_t> {
using type_t = double; //!< the type of the hash
/// \brief hash operator
/// \param x the value to hash
/// \returns an integer hash for the value
constexpr size_t operator()(double x) const {
return hash<uint64_t>::operator()(bit_cast<uint64_t>(x));
}

View File

@@ -28,40 +28,72 @@
///
///
#ifndef FENNEC_LANGCPP_RANGES_H
#define FENNEC_LANGCPP_RANGES_H
#ifndef FENNEC_LANG_RANGES_H
#define FENNEC_LANG_RANGES_H
#include <fennec/lang/types.h>
namespace fennec
{
///
/// \brief C++ Iterator Specification `begin()`
/// \tparam ContainerT the container type
/// \param c the container to iterate on
/// \returns an iterator at the start of the container
template<typename ContainerT>
inline constexpr auto begin(ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) {
return c.begin();
}
///
/// \brief C++ Iterator Specification `begin()`
/// \tparam ContainerT the container type
/// \param c the container to iterate on
/// \returns an iterator at the start of the container
template<typename ContainerT>
inline constexpr auto begin(const ContainerT& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()) {
return c.begin();
}
///
/// \brief C++ Iterator Specification `begin()`
/// \tparam T the element type
/// \tparam N the bounds of the array
/// \param arr a bounded array to iterate on
/// \returns an iterator at the start of the array
template<typename T, size_t N>
inline constexpr T* begin(T (&arr)[N]) noexcept {
return arr;
}
///
/// \brief C++ Iterator Specification `end()`
/// \tparam ContainerT the container type
/// \param c the container to iterate on
/// \returns an iterator at the end of the container
template<typename ContainerT>
inline constexpr auto end(ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) {
return c.end();
}
///
/// \brief C++ Iterator Specification `end()`
/// \tparam ContainerT the container type
/// \param c the container to iterate on
/// \returns an iterator at the end of the container
template<typename ContainerT>
inline constexpr auto end(const ContainerT& c) noexcept(noexcept(c.end())) -> decltype(c.end()) {
return c.end();
}
///
/// \brief C++ Iterator Specification `end()`
/// \tparam T the element type
/// \tparam N the bounds of the array
/// \param arr a bounded array to iterate on
/// \returns an iterator at the end of the array
template<typename T, size_t N>
inline constexpr T* end(T (&arr)[N]) noexcept {
return arr + N;
@@ -69,4 +101,4 @@ inline constexpr T* end(T (&arr)[N]) noexcept {
}
#endif // FENNEC_LANGCPP_RANGES_H
#endif // FENNEC_LANG_RANGES_H

View File

@@ -19,12 +19,17 @@
#ifndef FENNEC_LANG_STARTUP_H
#define FENNEC_LANG_STARTUP_H
// Helper for running a function before main()
///
/// \brief Macro for running a function before main
/// \param f the name of the function
#define FENNEC_PRIVATE_STATIC_CONSTRUCTOR(f) \
inline static void f(void); \
struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \
inline static void f(void)
///
/// \brief Macro for running a function before main in a class scope
/// \param f the name of the function
#define FENNEC_CLASS_STATIC_CONSTRUCTOR(f) \
struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \
inline static void f(void)

View File

@@ -26,26 +26,38 @@ namespace fennec
// has_equals ==========================================================================================================
///
/// \brief Checks if a type has a defined equality operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_equals {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() == declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_equals_v = has_equals<T0, T1>::value;
// has_nequals =========================================================================================================
///
/// \brief Checks if a type has a defined inequality operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_nequals {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() != declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_nequals_v = has_nequals<T0, T1>::value;
@@ -53,13 +65,19 @@ template<typename T0, typename T1 = T0> constexpr bool has_nequals_v = has_nequa
// has_less ============================================================================================================
///
/// \brief Checks if a type has a defined less operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_less {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() < declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_less_v = has_less<T0, T1>::value;
@@ -67,13 +85,19 @@ template<typename T0, typename T1 = T0> constexpr bool has_less_v = has_less<T0,
// has_less_equals =====================================================================================================
///
/// \brief Checks if a type has a defined less equals operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_less_equals {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() <= declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_less_equals_v = has_less_equals<T0, T1>::value;
@@ -81,13 +105,19 @@ template<typename T0, typename T1 = T0> constexpr bool has_less_equals_v = has_l
// has_greater =========================================================================================================
///
/// \brief Checks if a type has a defined greater operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_greater {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() > declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_greater_v = has_greater<T0, T1>::value;
@@ -95,13 +125,19 @@ template<typename T0, typename T1 = T0> constexpr bool has_greater_v = has_great
// has_greater_equals ==================================================================================================
///
/// \brief Checks if a type has a defined greater equals operator
/// \tparam T0 The first type
/// \tparam T1 The second type
template<typename T0, typename T1 = T0>
struct has_greater_equals {
private:
// Use SFINAE to check for the operator
template<typename U, typename V> static auto test(U*) -> decltype(declval<U>() >= declval<V>());
template<typename, typename> static auto test(...) -> false_type;
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>;
public:
static constexpr bool value = is_same_v<bool, decltype(test<T0, T1>(0))>; //!< The result of the check
};
template<typename T0, typename T1 = T0> constexpr bool has_greater_equals_v = has_greater_equals<T0, T1>::value;

View File

@@ -77,7 +77,8 @@ template<typename...TypesT> struct type_sequence {};
template<typename...TypesT> struct first_element : detail::_first_element<TypesT...> {};
///
/// \brief alias for first_element<TypesT>::type
/// \brief alias for `first_element<TypesT...>::type`
/// \tparam TypesT the Parameter Pack
template<typename...TypesT> using first_element_t = typename first_element<TypesT...>::type;
@@ -90,6 +91,10 @@ template<typename...TypesT> using first_element_t = typename first_element<Types
/// \tparam TypesT The type sequence
template<size_t n, typename...TypesT> struct nth_element : detail::_nth_element<n, 0, TypesT...> {};
///
/// \brief alias for nth_element<n, TypesT>::type
/// \tparam n The index in the type sequence
/// \tparam TypesT the Parameter Pack
template<size_t n, typename...TypesT> using nth_element_t = nth_element<n, TypesT...>::type;
@@ -100,6 +105,7 @@ template<size_t n, typename...TypesT> using nth_element_t = nth_element<n, Types
/// \brief Take a Template with a Pack `ClassT<ArgsT...>` and replace the first \f$ArgT\f$ of `ArgsT...` with \f$SubT\f$
template<typename ClassT, typename SubT> struct replace_first_element { };
#ifndef FENNEC_DOXYGEN
// Implementation
template<
template<typename, typename...> class ClassT // The Base Template
@@ -107,6 +113,7 @@ template<
, typename... RestT> // The Rest of the Parameter Pack
struct replace_first_element<ClassT<OriginT, RestT...>, SubT> // Specialization
{ using type = ClassT<SubT, RestT...>; }; // Definition
#endif
@@ -155,9 +162,13 @@ template<template<typename> typename SearchT, typename...TypesT> struct search_e
/// \tparam TypesT The type sequence to search
template<template<typename> typename SearchT, typename...TypesT> using search_element_t = search_element<SearchT, TypesT...>::type;
template<template<typename, typename...> typename, typename, typename...> struct search_element_args;
///
/// \brief Find the first element `T` in `TypesT...` that satisfies `SearchT<T, ArgsT...>`
/// \tparam SearchT A type that satisfies `template<typename>` and contains `static constexpr bool value;` to use for searching
/// \tparam TypesT The type sequence to search
/// \tparam ArgsT The arguments for the search
template<template<typename, typename...> typename SearchT, typename...TypesT, typename...ArgsT>
struct search_element_args<SearchT, type_sequence<ArgsT...>, TypesT...>
: detail::_search_element_args<SearchT, detail::_type_sequence<ArgsT...>, TypesT...> {
@@ -189,12 +200,14 @@ template<typename T, typename...Ts> constexpr bool contains_element_v = contains
/// \tparam Ts The type sequence to check
template<typename...Ts> struct is_unique : false_type {};
#ifndef FENNEC_DOXYGEN
// Single type case
template<typename T> struct is_unique<T> : true_type {};
// Recursion case
template<typename T, typename...Ts> requires(not is_same_v<T, Ts> && ...)
struct is_unique<T, Ts...> : is_unique<Ts...> {};
#endif
///
/// \brief Shorthand for `is_unique<Ts...>::value`

View File

@@ -434,6 +434,9 @@
namespace fennec
{
///
/// \brief metaprogramming helper for determining if a function is consteval
/// \returns \f$true\f$ if under `consteval`, \f$false\f$ otherwise
constexpr inline bool is_constant_evaluated() noexcept {
if consteval {
return true;
@@ -1147,12 +1150,14 @@ template<typename T> struct is_scoped_enum
template<typename T> struct is_scoped_enum
: false_type {};
#ifndef FENNEC_DOXYGEN
// true case
template<typename T>
requires __is_enum(T) and requires(remove_cv_t<T> test) { test = test; } // fails if incomplete
struct is_scoped_enum<T>
: bool_constant<!requires(T test, void(*testf)(int)) { testf(test); }> {
};
#endif
#endif

View File

@@ -129,8 +129,14 @@ namespace fennec
// Decay Conversions ===================================================================================================
///
/// \brief decays a type into its most basic form
/// \tparam T the type to decay
template<typename T> struct decay : detail::_decay<T> {};
///
/// \brief shorthand for `typename decay<T>::type`
/// \tparam T the type to decay
template<typename T> using decay_t = typename decay<T>::type;
// Pointer Conversions =================================================================================================
@@ -170,6 +176,8 @@ template<typename T> struct strip_pointers : conditional_t<
type_identity<T>
> {};
///
/// \brief shorthand for `typename strip_pointers<T>::type`
template<typename T> using strip_pointers_t = strip_pointers<T>::type;

View File

@@ -76,10 +76,12 @@ template<typename T> constexpr T&& forward(remove_reference_t<T>& x) noexcept {
return static_cast<T&&>(x);
}
#ifndef FENNEC_DOXYGEN
// specialization for T&&
template<typename T> constexpr T&& forward(remove_reference_t<T>&& x) noexcept {
return static_cast<T&&>(x);
}
#endif
///

View File

@@ -826,6 +826,7 @@ constexpr genType mix(genType x, genType y, genBType a) {
// Internal ============================================================================================================
#ifndef FENNEC_DOXYGEN
template<typename genType, size_t...i>
constexpr vector<genType, i...> sign(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::sign(x[i]) ...);
@@ -1011,6 +1012,7 @@ template<typename genType, typename genBType = bool_t, size_t...i> requires(is_b
constexpr vector<genType, i...> mix(const vector<genType, i...>& x, const vector<genType, i...>& y, const vector<genBType, i...>& a) {
return genDType((a[i] ? y[i] : x[i])...);
}
#endif // FENNEC_DOXYGEN
/// @}

View File

@@ -196,6 +196,7 @@ template<typename genType> constexpr genType inversesqrt(genType x) {
// Internal ============================================================================================================
#ifndef FENNEC_DOXYGEN
template<typename genType, size_t...i>
constexpr vector<genType, i...> pow(const vector<genType, i...> & x, const vector<genType, i...> & y) {
return vector<genType, i...>(fennec::pow(x[i], y[i]) ...);
@@ -225,6 +226,7 @@ template<typename genType, size_t...i>
constexpr vector<genType, i...> inversesqrt(const vector<genType, i...>& x) {
return vector<genType, i...>(fennec::inversesqrt(x[i]) ...);
}
#endif // FENNEC_DOXYGEN
}

View File

@@ -77,18 +77,20 @@ constexpr qua<genType> reciprocal(const qua<genType>& q) {
return ~q / fennec::sqnorm(q);
}
///
/// \brief quaternion structure type
/// \tparam ScalarT the base scalar type
template<typename ScalarT>
struct quaternion : detail::vector_base_type<ScalarT, 4>
{
public:
// Typedefs ============================================================================================================
using base_type = detail::vector_base_type<ScalarT, 4>;
using scalar_t = ScalarT;
using quat_t = quaternion;
using vec3_t = vec<scalar_t, 3>;
using vec4_t = vec<scalar_t, 4>;
using base_type = detail::vector_base_type<ScalarT, 4>; //!< base vector_storage type
using scalar_t = ScalarT; //!< scalar type
using quat_t = quaternion; //!< quaternion type
using vec3_t = vec<scalar_t, 3>; //!< scalar equivalent vec3 type
using vec4_t = vec<scalar_t, 4>; //!< scalar equivalent vec4 type
using base_type::data;
using base_type::x, base_type::y, base_type::z, base_type::w;
@@ -158,6 +160,7 @@ public:
///
/// \brief Copy Assignment Operator
/// \param q The quaternion to copy
/// \returns a reference to self
constexpr quat_t& operator=(const quat_t& q) {
data = q.data;
return *this;
@@ -166,6 +169,7 @@ public:
///
/// \brief Move Assignment Operator
/// \param q The quaternion to move
/// \returns a reference to self
constexpr quat_t& operator=(quat_t&& q) noexcept {
data = q.data;
return *this;
@@ -282,6 +286,11 @@ public:
// Quaternion Vector Arithmetic Operators ==============================================================================
///
/// \brief Quaternion-Vector Multiplication Operator
/// \param q the quaternion
/// \param v the vector
/// \returns the linear algebraic product of \f$q\f$ and \f$v\f$
constexpr friend vec3_t operator*(const quat_t& q, const vec3_t& v) {
const vec3_t u = q.xyz;
const vec3_t uv = fennec::cross(u, v);
@@ -289,21 +298,41 @@ public:
return v + (uv*q.w + uuv) * scalar_t(2);
}
///
/// \brief Vector-Quaternion Multiplication Operator
/// \param v the vector
/// \param q the quaternion
/// \returns the linear algebraic product of \f$v\f$ and \f$q\f$
constexpr friend vec3_t operator*(const vec3_t& v, const quat_t& q) {
return fennec::reciprocal(q) * v;
}
///
/// \brief Quaternion-Vector Multiplication Operator
/// \param q the quaternion
/// \param v the vector
/// \returns the linear algebraic product of \f$q\f$ and \f$v\f$
constexpr friend vec4_t operator*(const quat_t& q, const vec4_t& v) {
return vec4_t(q * v.xyz, v.w);
}
///
/// \brief Vector-Quaternion Multiplication Operator
/// \param v the vector
/// \param q the quaternion
/// \returns the linear algebraic product of \f$v\f$ and \f$q\f$
constexpr friend vec4_t operator*(const vec4_t& v, const quat_t& q) {
return fennec::reciprocal(q) * v;
}
// Quaternion Quaternion Arithmetic Operators ==========================================================================
// Quaternion-Quaternion Arithmetic Operators ==========================================================================
///
/// \brief Quaternion-Quaternion Addition Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the component-wise sum of \f$lhs\f$ and \f$rhs\f$
constexpr friend quat_t operator+(const quat_t& lhs, const quat_t& rhs) {
return quat_t(
lhs.w + rhs.w,
@@ -313,6 +342,11 @@ public:
);
}
///
/// \brief Quaternion-Quaternion Subtraction Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the component-wise difference of \f$lhs\f$ and \f$rhs\f$
constexpr friend quat_t operator-(const quat_t& lhs, const quat_t& rhs) {
return quat_t(
lhs.w - rhs.w,
@@ -322,6 +356,11 @@ public:
);
}
///
/// \brief Quaternion-Quaternion Multiplication Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the linear algebraic product of \f$lhs\f$ and \f$rhs\f$
constexpr friend quat_t operator*(const quat_t& lhs, const quat_t& rhs) {
return quat_t(
lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z * rhs.z,
@@ -334,6 +373,11 @@ public:
// Quaternion Quaternion Arithmetic Assignment Operators ===============================================================
///
/// \brief Quaternion-Quaternion Addition Assignment Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the component-wise sum of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$
constexpr friend quat_t& operator+=(quat_t& lhs, const quat_t& rhs) {
lhs.w += rhs.w;
lhs.x += rhs.x;
@@ -342,6 +386,11 @@ public:
return lhs;
}
///
/// \brief Quaternion-Quaternion Subtraction Assignment Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the component-wise difference of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$
constexpr friend quat_t& operator-=(quat_t& lhs, const quat_t& rhs) {
lhs.w -= rhs.w;
lhs.x -= rhs.x;
@@ -350,6 +399,11 @@ public:
return lhs;
}
///
/// \brief Quaternion-Quaternion Multiplication Assignment Operator
/// \param lhs the left hand side
/// \param rhs the right hand side
/// \returns the linear algebraic product of \f$lhs\f$ and \f$rhs\f$ stored in \f$lhs\f$
constexpr friend quat_t& operator*=(quat_t& lhs, const quat_t& rhs) {
return lhs = lhs * rhs;
}

View File

@@ -37,15 +37,19 @@
namespace fennec
{
///
/// \brief a math structure representing the bounds of a rectangle
/// \tparam ScalarT the scalar type
template<typename ScalarT>
struct rectangle {
tvec2<ScalarT> position, size;
tvec2<ScalarT> position; //!< the cartesian position of the box
tvec2<ScalarT> size; //!< the cartesian size of the box
};
using rect = rectangle<float_t>;
using irect = rectangle<int32_t>;
using urect = rectangle<uint32_t>;
using drect = rectangle<double_t>;
using rect = rectangle<float_t>; //!< a floating point rectangle
using irect = rectangle<int32_t>; //!< an integer rectangle
using urect = rectangle<uint32_t>; //!< an unsigned integer rectangle
using drect = rectangle<double_t>; //!< a double-precision floating point rectangle
}

View File

@@ -160,8 +160,7 @@ constexpr mat<scalar, rows, sizeof...(cols)> transpose(const matrix<scalar, rows
}
///
/// \brief Returns the determinant of m.
/// \param m the matrix
/// \brief Returns the determinant of \f$m\f$.
/// \returns the determinant of m.
template<typename scalar, size_t rows, size_t...cols>
constexpr scalar determinant(const matrix<scalar, rows, cols...>&) noexcept {
@@ -169,6 +168,9 @@ constexpr scalar determinant(const matrix<scalar, rows, cols...>&) noexcept {
return 0;
}
///
/// \brief Returns the determinant of \f$m\f$.
/// \returns \f$m^{-1}\f$
template<typename scalar, size_t rows, size_t...cols>
constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols...>&) noexcept {
static_assert(false, "implementation undefined");
@@ -176,10 +178,10 @@ constexpr matrix<scalar, rows, cols...> inverse(const matrix<scalar, rows, cols.
}
///
/// \brief
/// \tparam ScalarT
/// \tparam RowsV
/// \tparam ColIndicesV
/// \brief matrix structure
/// \tparam ScalarT The scalar type
/// \tparam RowsV The number of rows
/// \tparam ColIndicesV The indices of the columns
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV> requires(is_scalar_v<ScalarT>)
struct matrix
{
@@ -260,6 +262,10 @@ struct matrix
: data{ mat.data } {
}
///
/// \brief scalar conversion operator
/// \tparam OScalarT the scalar type of the other matrix
/// \param mat the matrix to convert
template<typename OScalarT>
constexpr matrix(const matrix<OScalarT, RowsV, ColIndicesV...>& mat)
: matrix() {
@@ -270,6 +276,10 @@ struct matrix
}
}
///
/// \brief scalar conversion operator
/// \tparam OScalarT the scalar type of the other matrix
/// \param mat the matrix to convert
template<typename OScalarT>
constexpr matrix(matrix<OScalarT, RowsV, ColIndicesV...>&& mat) noexcept
: matrix() {
@@ -645,6 +655,7 @@ struct matrix
/// \brief performs a linear algebraic matrix multiplication
/// \param lhs the rows to multiply with
/// \param rhs the columns to multiply with
/// \returns a matrix with the result of the multiplication
template<size_t ORowsV, size_t...OColIndicesV> requires(columns == ORowsV)
constexpr friend matrix<scalar_t, RowsV, OColIndicesV...> operator*(const matrix_t& lhs, const matrix<scalar_t, ORowsV, OColIndicesV...>& rhs) {
return matrix<scalar_t, RowsV, OColIndicesV...>(
@@ -652,6 +663,10 @@ struct matrix
);
}
///
/// \brief performs a linear algebraic matrix multiplication assignment
/// \param rhs the columns to multiply with
/// \returns a reference to self
template<size_t ORowsV, size_t...OColIndicesV> requires(columns == ORowsV)
constexpr matrix<scalar_t, RowsV, OColIndicesV...>& operator*=(const matrix<scalar_t, ORowsV, OColIndicesV...>& rhs) {
return *this = *this * rhs;
@@ -665,13 +680,15 @@ struct matrix
public:
///
/// \param mat the matrix to transpose
/// \returns \f$m^T\f$
static constexpr matrix_t transpose(const transpose_t& mat) {
return matrix_t(fennec::row(mat, ColIndicesV)...);
}
private:
// ReSharper disable once CppMemberFunctionMayBeStatic
template<size_t i0 = 0>
constexpr void _construct() {
// base case, does nothing, this will get optimized away

View File

@@ -65,10 +65,10 @@
namespace fennec
{
using byte = uint8_t;
using ubyte = uint8_t;
using ushort = uint16_t;
using uint = uint32_t;
using byte = uint8_t; //!< a single byte type
using ubyte = uint8_t; //!< a single unsigned byte type
using ushort = uint16_t; //!< an unsigned short type
using uint = uint32_t; //!< an unsigned int type
}

View File

@@ -338,6 +338,9 @@ struct vector : detail::vector_base_type<ScalarT, sizeof...(IndicesV)>
vector::_construct<0>(args...);
}
///
/// \brief initializer list constructor
/// \param init the initializer list
constexpr vector(initializer_list<ScalarT> init) {
size_t i = 0;
for (ScalarT x : init) {
@@ -345,6 +348,9 @@ struct vector : detail::vector_base_type<ScalarT, sizeof...(IndicesV)>
}
}
///
/// \brief initializer list conversion constructor
/// \param init the initializer list
template<typename OScalarT>
constexpr vector(initializer_list<OScalarT> init) {
size_t i = 0;

View File

@@ -60,7 +60,7 @@ struct vector_base_type_helper
/// \tparam IndicesV Indices of the vector to pull from
template<size_t...IndicesV> struct SwizzleGen
{
// \brief generated swizzle type
/// \brief generated swizzle type
using type = swizzle<VectorT, DataT, ScalarT, IndicesV...>;
};
@@ -68,7 +68,7 @@ struct vector_base_type_helper
/// \tparam IndicesV Indices of the vector to pull from
template<size_t IndexV> struct SwizzleGen<IndexV>
{
// \brief decayed scalar type
/// \brief decayed scalar type
using type = ScalarT;
};

View File

@@ -46,7 +46,7 @@ namespace fennec::detail
template <template <size_t...> class SwizzleGenT, typename DataT>
struct vector_storage<1, SwizzleGenT, DataT>
{
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type;
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type
vector_storage() = default;
@@ -74,7 +74,7 @@ namespace fennec::detail
{
//
// alias to allow for increased legibility
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type;
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type
vector_storage() = default;
@@ -123,7 +123,7 @@ namespace fennec::detail
template <template <size_t...> class SwizzleGenT, typename DataT>
struct vector_storage<3, SwizzleGenT, DataT>
{
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type;
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type
vector_storage() = default;
@@ -261,7 +261,7 @@ namespace fennec::detail
template <template <size_t...> class SwizzleGenT, typename DataT>
struct vector_storage<4, SwizzleGenT, DataT>
{
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type;
template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type
vector_storage() = default;

View File

@@ -724,7 +724,7 @@ public:
return _alignment;
}
protected:
private:
alloc_t _alloc; // Allocator object
value_t* _data; // Handle for the memory block
size_t _capacity; // Capacity of the memory block in elements.

View File

@@ -139,6 +139,10 @@ private:
/// \brief Byte Array Hash Function
template<>
struct hash<byte_array> {
///
/// \brief hash operator
/// \param bytes the byte_array to hash
/// \returns the murmur2 hash of the byte array
size_t operator()(const byte_array& bytes) const {
// Murmur2

View File

@@ -53,28 +53,53 @@ struct nothrow_t
/// \returns the page size for the current environment
size_t pagesize();
///
/// \brief Default construct the object of type \f$TypeT\f$ at \f$ptr\f$
/// \tparam TypeT the type to construct
/// \param ptr the pointer to the object to construct
template<typename TypeT> void construct(TypeT* ptr) {
new(ptr) TypeT();
}
///
/// \brief Copy construct the object of type \f$TypeT\f$ at \f$ptr\f$
/// \tparam TypeT the type to construct
/// \param ptr the pointer to the object to construct
/// \param val the value to copy
template<typename TypeT> void construct(TypeT* ptr, const TypeT& val) {
new(ptr) TypeT(val);
}
///
/// \brief Move construct the object of type \f$TypeT\f$ at \f$ptr\f$
/// \tparam TypeT the type to construct
/// \param ptr the pointer to the object to construct
/// \param val the value to take ownership of
template<typename TypeT> void construct(TypeT* ptr, TypeT&& val) {
new(ptr) TypeT(fennec::forward<TypeT>(val));
}
///
/// \brief Variadic construct the object of type \f$TypeT\f$ at \f$ptr\f$
/// \tparam TypeT the type to construct
/// \tparam ArgsT the argument types
/// \param ptr the pointer to the object to construct
/// \param args the argument values
template<typename TypeT, typename...ArgsT> void construct(TypeT* ptr, ArgsT&&...args) {
new(ptr) TypeT(fennec::forward<ArgsT>(args)...);
}
///
/// \brief Destruct the object of type \f$TypeT\f$ at \f$ptr\f$
/// \tparam TypeT the type to destruct
/// \param ptr the pointer to the object to destruct
template<typename TypeT> void destruct(TypeT* ptr) {
ptr->~TypeT();
}
}
#ifndef FENNEC_DOXYGEN
void* operator new (fennec::size_t size);
void* operator new[](fennec::size_t size);
void* operator new (fennec::size_t size, const fennec::nothrow_t&);
@@ -103,6 +128,7 @@ void operator delete[](void* ptr, fennec::align_t, const fennec::nothrow_t&) noe
template<typename TypeT> constexpr void* operator new (fennec::size_t, TypeT* ptr) { return ptr; }
template<typename TypeT> constexpr void* operator new[](fennec::size_t, TypeT* ptr) { return ptr; }
#endif
#endif // FENNEC_MEMORY_NEW_H

View File

@@ -32,15 +32,17 @@ template<typename ClassT>
struct pointer_traits
: detail::_ptr_traits_impl<ClassT, detail::_ptr_get_element<ClassT>> {};
// overload for C-Style Pointers
///
/// \brief overload for C-Style pointers
/// \tparam ElemT the element type
template<typename ElemT>
struct pointer_traits<ElemT*> : detail::_ptr_traits_ptr_to<ElemT*, ElemT>
{
using pointer_t = ElemT*;
using element_t = ElemT;
using diff_t = ptrdiff_t;
using pointer_t = ElemT*; //!< the pointer type
using element_t = ElemT; //!< the element type
using diff_t = ptrdiff_t; //!< the difference type
template<typename U> using rebind = U*;
template<typename U> using rebind = U*; //!< rebind type
};
}

View File

@@ -135,6 +135,10 @@ public:
constexpr unique_ptr& operator=(const unique_ptr&) = delete;
///
/// \brief move constructor
/// \param r the pointer to take ownership of
/// \returns a reference to self
constexpr unique_ptr& operator=(unique_ptr&& r) noexcept {
_delete = r._delete;
_handle = r._handle;
@@ -142,13 +146,18 @@ public:
return *this;
}
///
/// \brief reset the pointer, destroying the held object
/// \param ptr the new pointer to own
void reset(pointer_t ptr) {
if(_handle) {
_delete(_handle);
}
_handle = ptr;
}
}
///
/// \brief reset the pointer, destroying the held object
void reset(nullptr_t = nullptr) {
if(_handle) {
_delete(_handle);
@@ -156,28 +165,43 @@ public:
}
}
///
/// \brief releases the held pointer, returning it
/// \returns the released pointer
pointer_t release() {
pointer_t retval = _handle;
_handle = nullptr;
return retval;
}
///
/// \returns a reference to the held pointer
pointer_t get() const {
return _handle;
}
///
/// \returns \f$true\f$ if there is not a held pointer, \f$false\f$ otherwise
bool empty() {
return _handle == nullptr;
}
///
/// \returns the held object for access
pointer_t operator->() {
return _handle;
}
///
/// \brief access operator
/// \returns the held object for access
const_pointer_t operator->() const {
return _handle;
}
///
/// \brief implicit boolean conversion
/// \returns \f$true\f$ if there is a held pointer, \f$false\f$ otherwise
operator bool() const {
return _handle != nullptr;
}

View File

@@ -58,80 +58,109 @@ class display_server : public type_registry<display_server, platform*> {
// Typedefs/Constants/Enums ============================================================================================
public:
enum feature_ : uint32_t {
feature_subwindows = 0,
feature_icon,
///
/// \brief enum representing features to test support for against the display server
enum feature_ : uint32_t {
feature_subwindows = 0, //!< sub window support
feature_icon, //!< icon support
feature_window_drag,
feature_window_drag, //!< window dragging support
feature_mouse,
feature_cursors,
feature_custom_cursors,
feature_mouse, //!< mouse support
feature_cursors, //!< multiple cursor type support
feature_custom_cursors, //!< custom cursor image support
feature_clipboard,
feature_clipboard_primary,
feature_virtual_keyboard,
feature_clipboard, //!< clipboard support
feature_clipboard_primary, //!< highlight support
feature_virtual_keyboard, //!< virtual keyboard support
feature_status_indicators,
feature_dialogues,
feature_input_dialogues,
feature_file_dialogues,
feature_filtered_file_dialogues,
feature_status_indicators, //!< taskbar status indicators
feature_dialogues, //!< popup dialog support
feature_input_dialogues, //!< popup dialog text input support
feature_file_dialogues, //!< file navigation support
feature_filtered_file_dialogues, //!< filtered file navigation support
feature_orientation,
feature_hidpi,
feature_hdr,
feature_swap_buffers,
feature_window_transparency,
feature_orientation, //!< display orientation support
feature_hidpi, //!< high dpi support
feature_hdr, //!< hdr support
feature_swap_buffers, //!< swap buffer support
feature_window_transparency, //!< window transparency support
feature_screen_reader,
feature_text_to_speech,
feature_touchscreen,
feature_system_theme,
feature_screen_reader, //!< screen reader support
feature_text_to_speech, //!< text to speech system support
feature_touchscreen, //!< touchscreen support
feature_system_theme, //!< system specified theming
feature_count,
feature_count, //!< number of features
};
using featureset_t = bitfield<feature_count>;
using window_id = uint32_t;
using window_pool = object_pool<unique_ptr<window>>;
using featureset_t = bitfield<feature_count>; //!< a bitset holding the supported feature set
// Public Members ======================================================================================================
platform* const platform;
platform* const platform; //!< the parent platform
///
/// \brief display server constructor
/// \param p the parent platform
explicit display_server(fennec::platform* p)
: platform(p) {
}
///
/// \brief base destructor
virtual ~display_server() {
}
///
/// \brief feature support checking function
/// \param feature the feature to check
/// \returns \f$true\f$ if the feature is supported, \f$false\f$ otherwise
bool has_feature(uint32_t feature) const {
return features.test(feature);
}
virtual window* create_window(const window::config&, window* = nullptr) = 0;
///
/// \brief create a new window with the specified configuration and parent
/// \param cfg the configuration
/// \param p the parent window
/// \returns the created window
virtual window* create_window(const window::config& cfg, window* p = nullptr) = 0;
///
/// \brief connect to the display server
virtual void connect() = 0;
///
/// \brief disconnect from the display server
virtual void disconnect() = 0;
///
/// \returns \f$true\f$ if connected to the display server, \f$false\f$ otherwise
virtual bool connected() const = 0;
///
/// \brief dispatch the current context to the display server
virtual void dispatch() = 0;
///
/// \returns the underlying native handle
virtual void* get_native_handle() = 0;
///
/// \returns the graphics context of the display connection
gfxcontext* get_gfx_context() {
return gfx_context.get();
}
protected:
featureset_t features;
unique_ptr<gfxcontext> gfx_context;
featureset_t features; //!< the feature set of the display server
unique_ptr<gfxcontext> gfx_context; //!< the graphics context of the display server
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}
#endif
};
///
@@ -139,12 +168,15 @@ protected:
template<typename DisplayT, typename WindowT>
class display_server_base : public display_server, public type_registry<gfxcontext, DisplayT*> {
public:
///
/// \brief display server constructor
/// \param p the parent platform
display_server_base(fennec::platform* p)
: display_server(p) {
}
using ctx_registry = type_registry<gfxcontext, DisplayT*>;
using window_t = WindowT;
using ctx_registry = type_registry<gfxcontext, DisplayT*>; //!< registry for graphics contexts
using window_t = WindowT; //!< the window type of the display server
};
}

View File

@@ -65,26 +65,47 @@ namespace fennec
/// \brief Main platform class
class platform : public singleton<platform*> {
public:
using shared_object = struct shared_object;
using symbol = void*;
using shared_object = struct shared_object; //!< handle for shared object code
using symbol = void*; //!< handle for a symbol loaded from a shared object
///
/// \brief constructor
platform();
///
/// \brief destructor
virtual ~platform() = default;
platform(const platform&) = delete;
// Dynamically linked objects
///
/// \brief shared object linker
/// \param file the name of the shared object to link
/// \returns a reference to the shared object
virtual shared_object* load_object(const cstring& file) = 0;
///
/// \brief shared object release
/// \param obj the shared object to release
virtual void unload_object(shared_object* obj) = 0;
///
/// \brief shared object symbol locator
/// \param obj the shared object to search
/// \param name the name of the symbol to search for
/// \returns a reference to the symbol
virtual symbol find_symbol(shared_object* obj, const cstring& name) = 0;
virtual void initialize(); // Initialize Drivers and Contexts
virtual void shutdown(); // Close Drivers and Contexts
virtual void initialize(); //!< Initialize Drivers and Contexts
virtual void shutdown(); //!< Close Drivers and Contexts
protected:
unique_ptr<window_manager> wmanager;
unique_ptr<window_manager> wmanager; //!< the window manager
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE() {
}
#endif
};
}

View File

@@ -44,38 +44,46 @@
namespace fennec
{
///
/// \brief base window interface
class window {
// Structures & Typedefs ===============================================================================================
// Definitions =========================================================================================================
public:
static constexpr size_t nullid = -1;
///
/// \brief window mode
enum mode_ : uint8_t {
mode_windowed = 0,
mode_minimized,
mode_maximized,
mode_fullscreen,
mode_exclusive_fullscreen,
mode_windowed = 0, //!< normal window mode
mode_minimized, //!< minimized to the taskbar
mode_maximized, //!< maximized to take up the whole screen
mode_fullscreen, //!< window surface takes the whole screen without border decorations
mode_exclusive_fullscreen, //!< takes exclusive control of the display
};
///
/// \brief vsync mode
enum vsync_ : uint8_t {
vsync_disabled = 0,
vsync_enabled,
vsync_adaptive
vsync_disabled = 0, //!< no vertical sync
vsync_enabled, //!< enabled vertical sync
vsync_adaptive //!< adaptive sync
};
///
/// \brief window behaviour flags
enum flag_ : uint8_t {
flag_always_on_top = 0, // Window always appears on top level
flag_borderless, // Window has no border decorations
flag_modal, // Window always appears above parent and blocks input going to parent
flag_pass_mouse, // Mouse interaction passes to next underlying window in the application
flag_popup, // Window does not show in taskbar and closes when loses focus
flag_resizable, // Window can be resized through functions defined by Desktop Environment
flag_transparent, // Window has an alpha value
flag_no_focus, // Window can be focused
flag_always_on_top = 0, //!< Window always appears on top level
flag_borderless, //!< Window has no border decorations
flag_modal, //!< Window always appears above parent and blocks input going to parent
flag_pass_mouse, //!< Mouse interaction passes to next underlying window in the application
flag_popup, //!< Window does not show in taskbar and closes when loses focus
flag_resizable, //!< Window can be resized through functions defined by Desktop Environment
flag_transparent, //!< Window has an alpha value
flag_no_focus, //!< Window can be focused
flag_count
flag_count //!< the number of flags
};
///
/// \brief window state flags
enum state_ : uint8_t {
state_running = 0, // Window is running
state_child, // Window is a child
@@ -85,104 +93,270 @@ public:
state_count
};
using flags_t = bitfield<flag_count>;
using state_t = bitfield<state_count>;
using flags_t = bitfield<flag_count>; //!< flag bitset
using state_t = bitfield<state_count>; //!< state bitset
///
/// \brief accessibility information
struct accessibility {
string name, description;
string name; //!< the name of the window provided to accessibility features
string description; //!< the description of the window provided to accessibility features
};
///
/// \brief window configuration
struct config {
string title;
flags_t flags;
uint8_t mode;
string title; //!< title of the window
flags_t flags; //!< window behaviour flags
uint8_t mode; //!< the window mode
size_t parent;
irect rect;
irect rect; //!< the bounds of the window
double_t fractional_scaling;
double_t fractional_scaling; //!< fractional scaling factor
accessibility accessibility;
accessibility accessibility; //!< accessibility info
};
///
/// \brief window state info
struct state {
uint8_t mode;
irect rect;
state_t flags;
int_t buffer_scale;
double_t fractional_scaling;
uint8_t mode; //!< the current window mode
irect rect; //!< the current bounds of the window
state_t flags; //!< the current behaviour flags of the window
int_t buffer_scale; //!< buffer scaling
double_t fractional_scaling; //!< current fractional scaling factor
};
// Constructors & Destructor ===========================================================================================
///
/// \brief window constructor
/// \param server the display server the window belongs to
/// \param conf the configuration to construct the window with
/// \param parent a reference to the parent window
window(display_server* server, const config& conf, window* parent);
///
/// \brief base destructor
virtual ~window();
// Properties ==========================================================================================================
///
/// \returns the current configuration of the window
const config& get_config() const { return cfg; }
///
/// \returns the parent window
window* get_parent() const { return parent; }
///
/// \returns the nearest top-level window in the hierarchy
window* get_root() const { return root; }
///
/// \returns the underlying handle of the window
virtual void* get_native_handle() = 0;
// Positional Info =====================================================================================================
///
/// \returns the size of the window
const ivec2& get_size() const { return state.rect.size; }
///
/// \returns the position of the window
const ivec2& get_position() const { return state.rect.position; }
///
/// \returns the width of the window
int get_width() const { return state.rect.size.x; }
///
/// \returns the height of the window
int get_height() const { return state.rect.size.y; }
///
/// \returns the x position of the window
int get_pos_x() const { return state.rect.position.x; }
///
/// \returns the y position of the window
int get_pos_y() const { return state.rect.position.y; }
// Status ==============================================================================================================
///
/// \brief tests if the window is visible
/// \returns \f$true\f$ if the window is visible, \f$false\f$ otherwise
bool is_visible() const { return state.flags.test(state_visible); }
///
/// \brief tests if the window is a child
/// \returns \f$true\f$ if the window is a child, \f$false\f$ otherwise
bool is_child() const { return state.flags.test(state_child); }
///
/// \brief tests if the window is running
/// \returns \f$true\f$ if the window is running, \f$false\f$ otherwise
bool is_running() const { return state.flags.test(state_running); }
///
/// \brief tests if the window is suspended
/// \returns \f$true\f$ if the window is suspended, \f$false\f$ otherwise
bool is_suspended() const { return state.flags.test(state_suspended); }
// Behaviour ===========================================================================================================
///
/// \brief tests a specific flag
/// \param flag the flag from `window::flag_`
/// \returns \f$true\f$ if the flag is set, \f$false\f$ otherwise
bool get_flag(uint8_t flag) const { return cfg.flags.test(flag); }
///
/// \brief check if the window is flagged to always be on top of other windows
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_always_on_top() const { return get_flag(flag_always_on_top); }
///
/// \brief check if the window is flagged to have no window decorations
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_borderless() const { return get_flag(flag_borderless); }
///
/// \brief check if the window is flagged to be modal
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_modal() const { return get_flag(flag_modal); }
///
/// \brief check if the window is flagged to pass mouse input to windows underneath from the same application
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_passing_mouse() const { return get_flag(flag_pass_mouse); }
///
/// \brief check if the window is flagged as a popup
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_popup() const { return get_flag(flag_popup); }
///
/// \brief check if the window is flagged to be resizable
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_resizable() const { return get_flag(flag_resizable); }
///
/// \brief check if the window is flagged to be transparent
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_transparent() const { return get_flag(flag_transparent); }
///
/// \brief check if the window is flagged to be unfocusable
/// \returns \f$true\f$ if set, \f$false\f$ otherwise
bool is_no_focus() const { return get_flag(flag_no_focus); }
///
/// \brief sets a specific flag
/// \param flag the flag from `window::flag_`
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
virtual bool set_flag(uint8_t flag, bool val) = 0;
///
/// \brief sets whether to always be on top of other windows
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_always_on_top(bool val) { return set_flag(flag_always_on_top, val); }
///
/// \brief sets whether to have no window decorations
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_borderless(bool val) { return set_flag(flag_borderless, val); }
///
/// \brief sets whether to be modal
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_modal(bool val) { return set_flag(flag_modal, val); }
///
/// \brief sets whether to pass mouse input to windows underneath from the same application
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_passing_mouse(bool val) { return set_flag(flag_pass_mouse, val); }
///
/// \brief sets whether the window is a popup
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_popup(bool val) { return set_flag(flag_popup, val); }
///
/// \brief sets whether to be resizable
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_resizable(bool val) { return set_flag(flag_resizable, val); }
///
/// \brief sets whetherto be transparent
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_transparent(bool val) { return set_flag(flag_transparent, val); }
///
/// \brief sets whether to be unfocusable
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_no_focus(bool val) { return set_flag(flag_no_focus, val); }
virtual void initialize() = 0;
virtual void shutdown() = 0;
virtual void begin_frame();
virtual void end_frame();
virtual void* get_native_handle() = 0;
// Window Management Functions =========================================================================================
virtual void initialize() = 0; //!< initialization function
virtual void shutdown() = 0; //!< shutdown function
virtual void begin_frame(); //!< start a frame for the window, setting the correct graphics context
virtual void end_frame(); //!< end a frame for the window, swapping the underlying buffers
protected:
display_server* const server;
window* const parent;
config cfg;
state state;
window* root;
unique_ptr<gfxsurface> gfx_surface;
display_server* const server; //!< the display server the window belongs to
window* const parent; //!< the parent window
config cfg; //!< the current configuration
state state; //!< the current state
window* root; //!< the nearest top-level window in the hierarchy
unique_ptr<gfxsurface> gfx_surface; //!< the corresponding graphics surface
};
///
/// \brief Interface resembling the API for a window of a display server
template<typename DisplayT>
class window_base : public window {
public:
///
/// \brief constructor
/// \param display the display server
/// \param conf the configuration
/// \param parent the parent window
window_base(display_server* display, const config& conf, window* parent)
: window(display, conf, parent) {
}
using display_t = DisplayT;
using display_t = DisplayT; //!< corresponding display server type
};
}

View File

@@ -25,16 +25,18 @@ namespace fennec
class linux_platform : public unix_platform {
public:
/// \brief constructor
linux_platform()
: unix_platform() {
}
void initialize() override;
void shutdown() override;
void initialize() override; //!< platform initialization
void shutdown() override; //!< platform shutdown
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(unix_platform) {
}
#endif
};
}

View File

@@ -37,17 +37,28 @@
namespace fennec
{
///
/// \brief wayland egl context
class wayland_eglcontext : public eglcontext {
public:
/// \brief constructor
/// \param display the display server
explicit wayland_eglcontext(display_server* display);
/// \brief destructor
~wayland_eglcontext();
/// \brief create a surface for a window
/// \param window the window
/// \returns a new surface for the window
gfxsurface* create_surface(window* window) override;
private:
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(eglcontext) {
wayland_server::ctx_registry::register_type<wayland_eglcontext>();
}
#endif
};
}

View File

@@ -38,11 +38,20 @@
namespace fennec
{
///
/// \brief wayland egl surface
class wayland_eglsurface : public eglsurface {
public:
/// \brief constructor
/// \param win the wayland window
/// \param ctx the egl context
wayland_eglsurface(wayland_window* win, eglcontext* ctx);
/// \brief destructor
~wayland_eglsurface();
/// \brief resize the surface
/// \param size the new size
void resize(const ivec2& size) override;
private:

View File

@@ -38,6 +38,7 @@
#include <fennec/platform/linux/wayland/libdecor/libdecor.h>
#endif
#ifndef FENNEC_DOXYGEN
// forward defs to avoid flooding global namespace
struct wl_display;
struct wl_shm;
@@ -47,6 +48,7 @@ struct wl_seat;
struct wp_viewporter;
struct xdg_wm_base;
#endif
namespace fennec
{
@@ -55,17 +57,26 @@ namespace fennec
/// \brief Class for handling the Wayland Display Server
class wayland_server : public display_server_base<wayland_server, wayland_window> {
public:
/// \brief constructor
/// \param p the platform
explicit wayland_server(fennec::platform* p);
/// \brief destructor
~wayland_server() override;
void connect() override;
void disconnect() override;
bool connected() const override;
void connect() override; //!< connect to wayland
void disconnect() override; //!< disconnect from wayland
bool connected() const override; //!< check if connected to wayland \returns \f$true\f$ if connected, \f$false\f$ otherwise
void dispatch() override;
void dispatch() override; //!< dispatch the current context
/// \brief create a window
/// \param conf the configuration
/// \param parent the parent window
/// \returns a new window with the provided configuration and parent
window* create_window(const window::config& conf, window* parent) override;
/// \returns the native wl_display handle
void* get_native_handle() override { return display; }
@@ -98,9 +109,11 @@ private:
static void _libdecor_on_error(struct libdecor*, libdecor_error error, const char* message);
#endif
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(display_server) {
display_server::register_type<wayland_server>(1);
}
#endif
friend class wayland_window;
};

View File

@@ -34,6 +34,7 @@
#include <fennec/platform/linux/wayland/fwd.h>
#include <fennec/platform/interface/window.h>
#ifndef FENNEC_DOXYGEN
struct wl_array;
struct wl_callback;
struct wl_output;
@@ -42,22 +43,39 @@ struct wl_surface;
struct xdg_surface;
struct xdg_toplevel;
#if FENNEC_HAS_LIBDECOR
struct libdecor_frame;
struct libdecor_configuration;
#endif
#endif
namespace fennec
{
///
/// \brief Class for handling a Wayland window
class wayland_window : public window_base<wayland_server> {
public:
/// \brief constructor
/// \param server the display server
/// \param cfg the configuration
/// \param parent the parent window
wayland_window(display_server* server, const config& cfg, window* parent);
/// \brief destructor
~wayland_window();
void initialize() override;
void shutdown() override;
void initialize() override; //!< initialize the window
void shutdown() override; //!< shutdown the window
/// \returns the native wl_surface handle
void* get_native_handle() override;
///
/// \brief sets a specific flag
/// \param flag the flag from `window::flag_`
/// \param val the value to set the flag to
/// \returns \f$true\f$ on success, \f$false\f$ otherwise
bool set_flag(uint8_t flag, bool val) override;

View File

@@ -41,11 +41,17 @@
namespace fennec
{
/// \brief base egl context with platform-independent behaviour
class eglcontext : public glcontext {
public:
/// \brief constructor
/// \param display the corresponding display server
eglcontext(display_server* display);
/// \brief destructor
~eglcontext();
/// \returns \f$true\f$ if the context is valid, \f$false\f$ otherwise
bool is_valid() override;
private:
@@ -55,8 +61,10 @@ private:
EGLint _eglvmajor, _eglvminor, _eglctype;
cstring _extensions;
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(glcontext) {
}
#endif
friend class eglsurface;
};

View File

@@ -35,6 +35,9 @@
#include <EGL/egl.h>
#include <fennec/string/cstring.h>
/// \brief convert egl error to a readable string
/// \param err the error code
/// \returns the error string corresponding to \f$err\f$
inline fennec::cstring eglErrorString(EGLint err) {
switch (err) {
case EGL_SUCCESS: return "None";

View File

@@ -40,18 +40,22 @@
namespace fennec
{
/// \brief base egl surface with platform-independent behaviour
class eglsurface : public gfxsurface {
public:
/// \brief constructor
/// \param win the associated window
/// \param ctx the associated context
/// \param eglwindow the create egl window
eglsurface(fennec::window* win, eglcontext* ctx, void* eglwindow);
~eglsurface();
void make_current() override;
void swap() override;
void make_current() override; //!< makes this surface the current target of the context
void swap() override; //!< swaps the front and back buffers
protected:
void* _eglwindow;
EGLSurface _eglsurface;
void* _eglwindow; //!< the underlying handle to the window
EGLSurface _eglsurface; //!< the handle for the surface
};
} // fennec

View File

@@ -23,21 +23,38 @@
namespace fennec
{
/// \brief base unix platform for generic unix functionality
class unix_platform : public platform {
public:
///
/// \brief constructor
explicit unix_platform()
: platform() {
}
///
/// \brief shared object linker
/// \param file the name of the shared object to link
/// \returns a reference to the shared object
shared_object* load_object(const cstring& file) override;
///
/// \brief shared object release
/// \param obj the shared object to release
void unload_object(shared_object* obj) override;
///
/// \brief shared object symbol locator
/// \param obj the shared object to search
/// \param name the name of the symbol to search for
/// \returns a reference to the symbol
symbol find_symbol(shared_object* obj, const cstring& name) override;
private:
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(platform) {
}
#endif
};
}

View File

@@ -41,6 +41,8 @@
namespace fennec
{
///
/// \brief class for handling display servers and windows
class window_manager {
// Definitions =========================================================================================================
private:
@@ -51,7 +53,13 @@ private:
// Constructors & Destructor ===========================================================================================
public:
///
/// \brief constructor
/// \param platform the platform
window_manager(platform* platform);
///
/// \brief destructor
~window_manager();
window_manager(const window_manager&) = delete;
@@ -59,9 +67,9 @@ public:
// Thread-Specific Functions ===========================================================================================
void initialize();
void shutdown();
void dispatch();
void initialize(); //!< initialize the window system
void shutdown(); //!< shutdown the window system
void dispatch(); //!< dispatch the commands to the system
// Thread-Safe Functions ===============================================================================================

View File

@@ -35,18 +35,24 @@
namespace fennec
{
/// \brief base OpenGL context with platform-independent behavior
class glcontext : public gfxcontext {
public:
/// \brief
/// \param display
explicit glcontext(display_server* display)
: gfxcontext(display) {
}
/// \brief create a render pass
/// \returns a new render pass
gfxpass* create_pass() override;
private:
#ifndef FENNEC_DOXYGEN
FENNEC_RTTI_CLASS_ENABLE(gfxcontext) {
}
#endif
};
}

View File

@@ -43,9 +43,9 @@ template<typename AllocT>
struct _string
{
public:
static constexpr size_t npos = -1;
using char_t = char;
using alloc_t = allocation<char, AllocT>;
static constexpr size_t npos = -1; //!< null position
using char_t = char; //!< the character type
using alloc_t = allocation<char, AllocT>; //!< the allocator type
// Constructors ========================================================================================================

View File

@@ -46,9 +46,9 @@ template<typename AllocT>
struct _wstring
{
public:
static constexpr size_t npos = -1;
using char_t = wchar_t;
using alloc_t = allocation<wchar_t, AllocT>;
static constexpr size_t npos = -1; //!< null position
using char_t = wchar_t; //!< the character type
using alloc_t = allocation<wchar_t, AllocT>; //!< the allocator type
// Constructors ========================================================================================================

View File

@@ -18,8 +18,6 @@
#include <fennec/lang/detail/_stdlib.h>
using assert_handler = void (*)(const char *, const char *, int , const char *);
void _assert_callback(const char* expression, const char* file, int line, const char* function, const char* description);
void _assert_impl(const char* expression, const char* file, int line, const char* function, const char* description, bool halt)

View File

@@ -83,7 +83,7 @@ void window_manager::shutdown() {
}
void window_manager::dispatch() {
assertf(_thread == thread::current(), "Attempted to shutdown Window Manager on a different thread!");
assertf(_thread == thread::current(), "Attempted to dispatch Window Manager on a different thread!");
_display->dispatch();
}