- More documentation
This commit is contained in:
@@ -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
|
||||
@@ -243,6 +245,15 @@ fennec_add_sources(
|
||||
|
||||
|
||||
|
||||
# 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
|
||||
@@ -280,10 +291,10 @@ fennec_add_sources(
|
||||
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 =============================================================================================================
|
||||
|
||||
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
|
||||
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -55,7 +55,8 @@
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Escape Sequence Specification
|
||||
struct escape_sequence {
|
||||
virtual size_t operator[](const string& str, size_t i) = 0;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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)...);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
///
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -58,80 +58,109 @@ class display_server : public type_registry<display_server, platform*> {
|
||||
// Typedefs/Constants/Enums ============================================================================================
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief enum representing features to test support for against the display server
|
||||
enum feature_ : uint32_t {
|
||||
feature_subwindows = 0,
|
||||
feature_icon,
|
||||
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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ===============================================================================================
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ========================================================================================================
|
||||
|
||||
@@ -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 ========================================================================================================
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user