- Separated Platform and Compiler Dependent Behaviour into CMake scripts
- Implemented Basic Platform Interfaces
- Implemented partial Linux platform and Wayland Display.
- Implemented Dependencies for the above
- map
- set
- optional
- pair
TODO: threading
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "external/sdl"]
|
||||
path = external/sdl
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "external/cpptrace"]
|
||||
path = external/cpptrace
|
||||
url = https://github.com/jeremy-rifkin/cpptrace.git
|
||||
|
||||
106
CMakeLists.txt
106
CMakeLists.txt
@@ -1,34 +1,51 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
project(fennec)
|
||||
|
||||
# External dependencies should be loaded here
|
||||
|
||||
# SDL is a dependency of the project, added as a git submodule
|
||||
add_subdirectory(external/sdl)
|
||||
|
||||
# CppTrace is a dependency of the project, added as a git submodule
|
||||
add_subdirectory(external/cpptrace)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# include scripts
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/build.cmake")
|
||||
|
||||
# find dependencies
|
||||
find_package(Doxygen)
|
||||
fennec_check_platform()
|
||||
|
||||
# any necessary include directories
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
include_directories(${FENNEC_SOURCE_DIR}/include)
|
||||
|
||||
# Metaprogramming is a dependency for generating various type info before compilation of the engine.
|
||||
add_subdirectory(metaprogramming)
|
||||
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} FENNEC_BUILD_NAME)
|
||||
|
||||
message(STATUS "OS: ${CMAKE_SYSTEM_NAME}")
|
||||
message(STATUS "Build: ${FENNEC_BUILD_NAME}")
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${FENNEC_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME})
|
||||
|
||||
# add the test suite as a sub-project
|
||||
add_subdirectory(test)
|
||||
@@ -42,6 +59,10 @@ add_library(fennec STATIC
|
||||
# CONTAINERS ===========================================================================================================
|
||||
include/fennec/containers/array.h
|
||||
include/fennec/containers/dynarray.h
|
||||
include/fennec/containers/map.h
|
||||
include/fennec/containers/optional.h
|
||||
include/fennec/containers/pair.h
|
||||
include/fennec/containers/set.h
|
||||
|
||||
|
||||
# LANG =================================================================================================================
|
||||
@@ -51,15 +72,17 @@ add_library(fennec STATIC
|
||||
include/fennec/lang/bits.h
|
||||
include/fennec/lang/constants.h
|
||||
include/fennec/lang/conditional_types.h
|
||||
include/fennec/lang/hashing.h
|
||||
include/fennec/lang/intrinsics.h
|
||||
include/fennec/lang/limits.h
|
||||
include/fennec/lang/numeric_transforms.h
|
||||
include/fennec/lang/sequences.h
|
||||
include/fennec/lang/type_identity.h
|
||||
include/fennec/lang/type_sequences.h
|
||||
include/fennec/lang/type_traits.h
|
||||
include/fennec/lang/type_transforms.h
|
||||
include/fennec/lang/types.h
|
||||
include/fennec/lang/utility.h
|
||||
include/fennec/lang/type_sequences.h
|
||||
include/fennec/lang/integer.h
|
||||
|
||||
include/fennec/lang/detail/__bits.h
|
||||
@@ -67,6 +90,7 @@ add_library(fennec STATIC
|
||||
include/fennec/lang/detail/__numeric_transforms.h
|
||||
include/fennec/lang/detail/__stdlib.h
|
||||
include/fennec/lang/detail/__type_traits.h
|
||||
include/fennec/lang/detail/__type_transforms.h
|
||||
include/fennec/lang/detail/__type_sequences.h
|
||||
|
||||
include/fennec/lang/assert.h source/lang/assert.cpp
|
||||
@@ -75,8 +99,9 @@ add_library(fennec STATIC
|
||||
# MEMORY ===============================================================================================================
|
||||
include/fennec/memory/new.h source/memory/new.cpp
|
||||
|
||||
include/fennec/memory/common.h
|
||||
include/fennec/memory/allocator.h
|
||||
include/fennec/memory/bytes.h
|
||||
include/fennec/memory/common.h
|
||||
include/fennec/memory/memory.h
|
||||
include/fennec/memory/pointers.h
|
||||
include/fennec/memory/ptr_traits.h
|
||||
@@ -110,10 +135,12 @@ add_library(fennec STATIC
|
||||
|
||||
include/fennec/math/ext/common.h
|
||||
include/fennec/math/ext/constants.h
|
||||
include/fennec/math/ext/primes.h
|
||||
include/fennec/math/ext/quaternion.h
|
||||
include/fennec/math/ext/transform.h
|
||||
include/fennec/math/ext/trigonometric.h
|
||||
|
||||
|
||||
include/fennec/math/detail/__fwd.h
|
||||
include/fennec/math/detail/__math.h
|
||||
include/fennec/math/detail/__matrix.h
|
||||
@@ -132,32 +159,34 @@ add_library(fennec STATIC
|
||||
# Filesystem
|
||||
include/fennec/fproc/filesystem/file.h source/fproc/filesystem/file.cpp
|
||||
include/fennec/fproc/filesystem/path.h source/fproc/filesystem/path.cpp
|
||||
|
||||
# PLATFORM =============================================================================================================
|
||||
include/fennec/platform/interface/fwd.h
|
||||
|
||||
include/fennec/platform/interface/dialog.h
|
||||
include/fennec/platform/interface/display.h
|
||||
include/fennec/platform/interface/window.h source/platform/interface/window.cpp
|
||||
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
|
||||
|
||||
|
||||
${FENNEC_EXTRA_SOURCES}
|
||||
)
|
||||
|
||||
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
|
||||
if(DOXYGEN_FOUND)
|
||||
add_dependencies(fennec fennecdocs metaprogramming) # SDL3-shared cpptrace::cpptrace)
|
||||
else()
|
||||
add_dependencies(fennec metaprogramming) # SDL3-shared cpptrace::cpptrace)
|
||||
endif()
|
||||
add_dependencies(fennec metaprogramming)
|
||||
|
||||
# Compiler Warning Flags
|
||||
if(MSVC)
|
||||
add_compile_options("/W4" "/WX") # All MSVC Warnings throw as Errors
|
||||
else()
|
||||
add_compile_options("-Wall" "-Wextra" "-pedantic" "-Werror") # All gcc/etc. Warnings throw as errors
|
||||
|
||||
target_compile_definitions(fennec PRIVATE _GLIBCXX_INCLUDE_NEXT_C_HEADERS __USE_FILE_OFFSET64)
|
||||
endif()
|
||||
|
||||
target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f") # SIMD Instructions, automatic vectorization will occur
|
||||
target_compile_definitions(fennec PUBLIC
|
||||
${FENNEC_COMPILE_DEFINITIONS}
|
||||
)
|
||||
|
||||
|
||||
target_link_options(fennec PRIVATE "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates") # Do not compile base fennec library with c++ stdlib
|
||||
target_link_options(fennec PRIVATE ${FENNEC_PRIVATE_LINK_OPTIONS}) # Do not compile base fennec library with c++ stdlib
|
||||
# fennec does not use the C++ stdlib because it is bloated, difficult to read, and implementation defined.
|
||||
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
||||
|
||||
target_link_libraries(fennec PRIVATE SDL3-shared cpptrace::cpptrace)
|
||||
target_link_libraries(fennec PRIVATE
|
||||
cpptrace::cpptrace
|
||||
${FENNEC_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -167,10 +196,11 @@ target_link_libraries(fennec PRIVATE SDL3-shared cpptrace::cpptrace)
|
||||
file(COPY logo DESTINATION docs/logo)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
set(DOXY_OUTPUT_DIR "${PROJECT_SOURCE_DIR}/docs")
|
||||
get_filename_component(DOXYGEN_PROJECT_NAME ${PROJECT_SOURCE_DIR} NAME) # Set Doxy Project name to the name of the root dir
|
||||
set(DOXYGEN_CONFIG_IN "${PROJECT_SOURCE_DIR}/doxy/Doxyfile.in") # Input config file with preprocessor arguments
|
||||
set(DOXYGEN_CONFIG_OUT "${PROJECT_SOURCE_DIR}/doxy/Doxyfile") # Generated config file from input
|
||||
add_dependencies(fennec fennecdocs)
|
||||
set(DOXY_OUTPUT_DIR "${FENNEC_SOURCE_DIR}/docs")
|
||||
get_filename_component(DOXYGEN_PROJECT_NAME ${FENNEC_SOURCE_DIR} NAME) # Set Doxy Project name to the name of the root dir
|
||||
set(DOXYGEN_CONFIG_IN "${FENNEC_SOURCE_DIR}/doxy/Doxyfile.in") # Input config file with preprocessor arguments
|
||||
set(DOXYGEN_CONFIG_OUT "${FENNEC_SOURCE_DIR}/doxy/Doxyfile") # Generated config file from input
|
||||
|
||||
configure_file(${DOXYGEN_CONFIG_IN} ${DOXYGEN_CONFIG_OUT} @ONLY) # Execute preprocessing step
|
||||
message("Doxygen Build Started.")
|
||||
@@ -179,8 +209,8 @@ if(DOXYGEN_FOUND)
|
||||
# Target for building docs
|
||||
add_custom_target(fennecdocs ALL
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_CONFIG_OUT}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/logo/raster.png
|
||||
WORKING_DIRECTORY ${FENNEC_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${FENNEC_SOURCE_DIR}/logo/raster.png
|
||||
${DOXY_OUTPUT_DIR}/logo/raster.png
|
||||
COMMENT "Generating Doxygen Documentation"
|
||||
VERBATIM)
|
||||
@@ -189,7 +219,7 @@ if(DOXYGEN_FOUND)
|
||||
|
||||
# Target for cleaning docs
|
||||
add_custom_target(fennecdocs-clean ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E remove -f "${PROJECT_SOURCE_DIR}/docs"
|
||||
COMMAND ${CMAKE_COMMAND} -E remove -f "${FENNEC_SOURCE_DIR}/docs"
|
||||
COMMENT "Cleaning Doxygen Documentation"
|
||||
VERBATIM)
|
||||
else()
|
||||
|
||||
45
PLANNING.md
45
PLANNING.md
@@ -7,6 +7,7 @@
|
||||
1. [Introduction](#introduction)
|
||||
2. [TODO](#todo)
|
||||
1. [Security Ramblings](#file-security-ramblings)
|
||||
2. [Platform Support](#platform--api-support)
|
||||
3. [C++ Language](#c-language-library-lang)
|
||||
4. [Math Library](#math-library-math)
|
||||
5. [Memory Library](#memory-library-memory)
|
||||
@@ -15,7 +16,7 @@
|
||||
8. [Core](#core-core)
|
||||
1. [Tick](#tick)
|
||||
2. [Frame](#frame)
|
||||
9. [Application Layer](#application-layer-app)
|
||||
9. [Platform Support Layer](#platform-support-layer-platform)
|
||||
10. [Scene](#scene-scene)
|
||||
11. [2D Graphics](#2d-graphics-gfx2d)
|
||||
12. [3D Graphics](#3d-graphics-gfx3d)
|
||||
@@ -152,6 +153,38 @@ Directories remain an issue, with `dirent.h` being the only sensible option at t
|
||||
for MSVC.
|
||||
|
||||
|
||||
### Platform & API Support
|
||||
|
||||
I have decided to forgo SDL, this is so the engine can provide specific support for specific platforms.
|
||||
Also, SDL implements a lot of things that will need to be implemented specifically for the engine, so only the window
|
||||
management would be used.
|
||||
|
||||
Platform support will be implemented in the following order:
|
||||
- Linux/BSD
|
||||
- Wayland
|
||||
- XKB
|
||||
- OpenGL (EGL)
|
||||
- PulseAudio
|
||||
- Vulkan
|
||||
- X11
|
||||
- OpenGL (EGL)
|
||||
- ALSA
|
||||
- Vulkan
|
||||
- Microsoft Windows
|
||||
- XInput
|
||||
- OpenGL
|
||||
- DirectSound
|
||||
- Vulkan
|
||||
- Android
|
||||
- OpenGL ES
|
||||
- macOS
|
||||
- iOS
|
||||
|
||||
Most consoles will never get official platform support due to NDAs which conflict with the principles of this engine.
|
||||
fennec will avoid using proprietary libraries except when strictly necessary, such as support for Windows and MacOS.
|
||||
fennec will interact with any drivers required for the listed operating systems above, even if proprietary.
|
||||
|
||||
|
||||
## C++ Language Library (`lang`)
|
||||
|
||||
Implement header files for standard functions relating to the C++ Language.
|
||||
@@ -320,14 +353,12 @@ in their operation order:
|
||||
|
||||
|
||||
|
||||
## Application Layer (`app`)
|
||||
|
||||
This is the core windowing system of fennec. The implementation will initially be an SDL3 wrapper.
|
||||
Custom implementation may be further down the roadmap, however this is extremely complicated and there are better
|
||||
implementations than I could write alone.
|
||||
|
||||
## Platform Support Layer (`platform`)
|
||||
|
||||
This is the core part of platform support for fennec. All necessary drivers
|
||||
and OS specific functionality will be wrapped up nicely into these interfaces.
|
||||
|
||||
See implementation order [here](#platform--api-support)
|
||||
|
||||
|
||||
## Scene (`scene`)
|
||||
|
||||
13
README.md
13
README.md
@@ -142,9 +142,9 @@ for more info.
|
||||
build scripts to use another build manager, see the [CMake documentation for available generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
||||
|
||||
|
||||
  I will at no point provide official cross-compilation toolchains for fennec, if you wish to compile your project for
|
||||
both Windows and Linux, working on Windows with WSL is likely your best option besides dual-booting. For Android and
|
||||
iOS, using the GCC and Clang cross-compilation toolchains, respectively, will suffice.
|
||||
  I will at no point provide official cross-compilation toolchains for fennec. However, I will provide tools for
|
||||
using specific toolchains for specific platforms that necessitate this. The primary examples would be Android and iOS.
|
||||
If you wish to build for Windows *and* Linux, your options are WSL or Dual Boot. I recommend Dual Boot over WSL.
|
||||
|
||||
<br>
|
||||
|
||||
@@ -223,14 +223,17 @@ licensing that mesh under another license.
|
||||
|
||||
Any code that is linked against fennec or uses any part is by definition a covered work must be licensed under GPLv3.
|
||||
|
||||
  Later down the line, I plan on implementing scripts in a manner that allows the script itself to remain proprietary.
|
||||
The scripts will likely be trans-compiled to another language before being compiled to binary, but this is only an
|
||||
intermediate step and will be erased when no longer needed.
|
||||
|
||||
  As long as you use the official editor, it will properly include licenses in project content when provided a license
|
||||
and the name of the license holder. Archive packs will include the license holders non-GPLv3 license in them and any
|
||||
linked code will be covered by GPLv3 under the name of the license holder. Be aware that the parts of your project
|
||||
licensed under GPLv3 must be available upon request.
|
||||
|
||||
  A release project will consist of an executable, a shared library for your code, an archive pak, and streamable assets.
|
||||
The executable and shared library are protected under the GPLv3 license, while the archive pak and streamable assets are
|
||||
protected under your license.
|
||||
The executable and shared library are under the GPLv3 license, while the archive pak and streamable assets are under your license.
|
||||
|
||||
It is to my discretion whether I enforce the terms of the license on a party.
|
||||
|
||||
|
||||
26
cmake/build.cmake
Normal file
26
cmake/build.cmake
Normal file
@@ -0,0 +1,26 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} FENNEC_BUILD_NAME)
|
||||
message(STATUS "Build: ${FENNEC_BUILD_NAME}")
|
||||
|
||||
if(${FENNEC_BUILD_NAME} MATCHES "debug")
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_RELEASE=false)
|
||||
else()
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_RELEASE=true)
|
||||
endif()
|
||||
24
cmake/compiler.cmake
Normal file
24
cmake/compiler.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER_GCC=0)
|
||||
|
||||
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||
set(FENNEC_COMPILER "GCC")
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/gcc.cmake")
|
||||
endif()
|
||||
23
cmake/gcc.cmake
Normal file
23
cmake/gcc.cmake
Normal file
@@ -0,0 +1,23 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
add_compile_options("-mxsave" "-Wall" "-Wextra" "-pedantic" "-Werror")
|
||||
|
||||
set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
|
||||
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER=FENNEC_COMPILER_GCC)
|
||||
63
cmake/libwayland.cmake
Normal file
63
cmake/libwayland.cmake
Normal file
@@ -0,0 +1,63 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
|
||||
|
||||
macro(fennec_check_libwayland)
|
||||
set(WAYLAND_CLIENT_FOUND 0)
|
||||
|
||||
find_path(
|
||||
WAYLAND_CLIENT_INCLUDE_DIR
|
||||
NAMES wayland-client.h
|
||||
)
|
||||
|
||||
find_library(
|
||||
WAYLAND_CLIENT_LIBRARY
|
||||
NAMES wayland-client libwayland-client
|
||||
)
|
||||
get_filename_component(
|
||||
WAYLAND_CLIENT_LIBRARY
|
||||
${WAYLAND_CLIENT_LIBRARY}
|
||||
NAME
|
||||
)
|
||||
|
||||
if(WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY)
|
||||
set(WAYLAND_CLIENT_FOUND 1)
|
||||
add_library(wayland::client UNKNOWN IMPORTED)
|
||||
|
||||
set_target_properties(
|
||||
wayland::client PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${WAYLAND_CLIENT_INCLUDE_DIR}"
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||
IMPORTED_LOCATION "${WAYLAND_CLIENT_LIBRARY}"
|
||||
)
|
||||
|
||||
list(APPEND FENNEC_EXTRA_SOURCES
|
||||
# Dynamic Library Files
|
||||
include/fennec/platform/linux/wayland/lib/fwd.h
|
||||
include/fennec/platform/linux/wayland/lib/sym.h
|
||||
include/fennec/platform/linux/wayland/lib/sym_def.h
|
||||
include/fennec/platform/linux/wayland/lib/dyn.h source/platform/linux/wayland/lib/dyn.cpp
|
||||
|
||||
# Fennec Files
|
||||
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp
|
||||
)
|
||||
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}")
|
||||
endif()
|
||||
endmacro()
|
||||
37
cmake/linux.cmake
Normal file
37
cmake/linux.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
|
||||
macro(fennec_check_platform)
|
||||
# compile definitions
|
||||
list(APPEND FENNEC_COMPILE_DEFINITIONS
|
||||
FENNEC_PLATFORM_NAME="Linux"
|
||||
FENNEC_PLATFORM_LINUX=1
|
||||
)
|
||||
|
||||
# extra source files
|
||||
list(APPEND FENNEC_EXTRA_SOURCES
|
||||
include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp
|
||||
)
|
||||
|
||||
# includes
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/libwayland.cmake")
|
||||
|
||||
# tests
|
||||
fennec_check_libwayland()
|
||||
endmacro()
|
||||
25
cmake/platform.cmake
Normal file
25
cmake/platform.cmake
Normal file
@@ -0,0 +1,25 @@
|
||||
# ======================================================================================================================
|
||||
# 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/>.
|
||||
# ======================================================================================================================
|
||||
|
||||
message(STATUS "OS: ${CMAKE_SYSTEM_NAME}")
|
||||
|
||||
# Check for Linux
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(FENNEC_PLATFORM "Linux")
|
||||
include("${FENNEC_SOURCE_DIR}/cmake/linux.cmake")
|
||||
endif ()
|
||||
1
external/sdl
vendored
1
external/sdl
vendored
Submodule external/sdl deleted from d7939abf42
@@ -38,7 +38,7 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
template<class TypeT, class Alloc>
|
||||
template<class TypeT, class Alloc = allocator<TypeT>>
|
||||
class dynarray
|
||||
{
|
||||
public:
|
||||
@@ -129,7 +129,9 @@ public:
|
||||
void insert(size_t i, const TypeT& val) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) _grow();
|
||||
if(_size == capacity()) {
|
||||
_grow();
|
||||
}
|
||||
|
||||
// Move the data if we are not inserting at the end of the array
|
||||
if((i = min(i, _size)) < _size) {
|
||||
@@ -141,30 +143,36 @@ public:
|
||||
|
||||
// Insert the element
|
||||
fennec::construct(_alloc.data() + i, val);
|
||||
++_size;
|
||||
}
|
||||
|
||||
void insert(size_t i, TypeT&& val) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) _grow();
|
||||
if(_size == capacity()) {
|
||||
_grow();
|
||||
}
|
||||
|
||||
// Move the data if we are not inserting at the end of the array
|
||||
if((i = min(i, _size)) < _size) {
|
||||
fennec::memmove(
|
||||
_alloc.data() + i
|
||||
, _alloc.data() + i + 1
|
||||
_alloc.data() + i + 1
|
||||
, _alloc.data() + i
|
||||
, (_size - i) * sizeof(TypeT));
|
||||
}
|
||||
|
||||
// Insert the element
|
||||
fennec::construct(_alloc.data() + i, fennec::forward<TypeT>(val));
|
||||
++_size;
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
void emplace(size_t i, ArgsT&&...args) {
|
||||
|
||||
// Grow if the size has reached the capacity of the allocation
|
||||
if(_size == capacity()) _grow();
|
||||
if(_size == capacity()) {
|
||||
_grow();
|
||||
}
|
||||
|
||||
// Move the data if we are not inserting at the end of the array
|
||||
if((i = min(i, _size)) < _size) {
|
||||
@@ -176,6 +184,7 @@ public:
|
||||
|
||||
// Insert the element
|
||||
fennec::construct(_alloc.data() + i, fennec::forward<ArgsT>(args)...);
|
||||
++_size;
|
||||
}
|
||||
|
||||
void push_back(const TypeT& val) {
|
||||
@@ -190,8 +199,14 @@ public:
|
||||
dynarray::emplace(_size, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
void resize(size_t n) {
|
||||
_alloc.reallocate(n);
|
||||
}
|
||||
|
||||
private:
|
||||
void _grow() const { _alloc.reallocate(_alloc.capacity() * 2); }
|
||||
void _grow() {
|
||||
_alloc.reallocate(_alloc.capacity() * 2);
|
||||
}
|
||||
|
||||
allocation<element_t, alloc_t> _alloc;
|
||||
size_t _size;
|
||||
|
||||
50
include/fennec/containers/map.h
Normal file
50
include/fennec/containers/map.h
Normal file
@@ -0,0 +1,50 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_MAP_H
|
||||
#define FENNEC_CONTAINERS_MAP_H
|
||||
|
||||
#include <fennec/containers/pair.h>
|
||||
#include <fennec/containers/set.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// TODO: Document
|
||||
|
||||
template<typename KeyT, typename ValueT, typename Hash = hash<KeyT>, typename Alloc = allocator<pair<KeyT, ValueT>>>
|
||||
struct map {
|
||||
public:
|
||||
using key_t = KeyT;
|
||||
using value_t = ValueT;
|
||||
using elem_t = pair<KeyT, ValueT>;
|
||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>;
|
||||
using hash_t = Hash;
|
||||
|
||||
map() = default;
|
||||
~map() = default;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
set<elem_t, hash_t, alloc_t> _set;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_MAP_H
|
||||
247
include/fennec/containers/optional.h
Normal file
247
include/fennec/containers/optional.h
Normal file
@@ -0,0 +1,247 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_OPTIONAL_H
|
||||
#define FENNEC_CONTAINERS_OPTIONAL_H
|
||||
|
||||
#include <fennec/lang/utility.h>
|
||||
#include <fennec/memory/new.h>
|
||||
|
||||
#include <fennec/lang/assert.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
struct nullopt_t {};
|
||||
constexpr nullopt_t nullopt_v = {};
|
||||
|
||||
#define nullopt nullopt_v
|
||||
|
||||
///
|
||||
/// \brief Structure to hold an optional value.
|
||||
/// \tparam T
|
||||
template<typename T>
|
||||
struct optional {
|
||||
public:
|
||||
// Constructors ========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Default Constructor
|
||||
constexpr optional()
|
||||
: _root(0)
|
||||
, _set(false) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Default Constructor
|
||||
constexpr optional(nullopt_t)
|
||||
: _root(0)
|
||||
, _set(false) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Fundamental Type Constructor
|
||||
/// \param val the value to initialize the underlying object with
|
||||
constexpr optional(T val) requires is_fundamental_v<T>
|
||||
: _val(val)
|
||||
, _set(true) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Type Copy Constructor
|
||||
/// \param val the value to initialize the underlying object with
|
||||
constexpr optional(const T& val)
|
||||
: _val(val)
|
||||
, _set(true) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Constructor
|
||||
/// \param opt the optional to copy
|
||||
constexpr optional(const optional& opt) requires is_copy_assignable_v<T>
|
||||
: optional() {
|
||||
_set = opt._set;
|
||||
if (_set) {
|
||||
_val = opt._val;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Constructor
|
||||
/// \param opt the optional to move
|
||||
constexpr optional(optional&& opt) noexcept requires is_move_assignable_v<T>
|
||||
: optional() {
|
||||
_set = opt._set;
|
||||
if (_set) {
|
||||
_val = fennec::move(opt._val);
|
||||
}
|
||||
opt = nullopt;
|
||||
}
|
||||
|
||||
constexpr ~optional() {
|
||||
if constexpr(is_fundamental_v<T>) {
|
||||
return;
|
||||
}
|
||||
if (_set) {
|
||||
_val.~T();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Assignment Operators ================================================================================================
|
||||
|
||||
///
|
||||
/// \brief Fundamental Type Assignment
|
||||
/// \val The value to set with
|
||||
constexpr optional& operator=(nullopt_t) {
|
||||
if constexpr(not is_fundamental_v<T>) {
|
||||
if (_set) {
|
||||
_val.~T();
|
||||
}
|
||||
}
|
||||
_root = '\0';
|
||||
_set = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Type Copy Assignment
|
||||
/// \val The value to set with
|
||||
constexpr optional& operator=(const T& val) requires is_copy_constructible_v<T> and is_copy_assignable_v<T> {
|
||||
if (_set) {
|
||||
_val = val;
|
||||
} else {
|
||||
fennec::construct(&_val, val);
|
||||
_set = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Type Move Assignment
|
||||
/// \val The value to set with
|
||||
constexpr optional& operator=(T&& val) requires is_move_constructible_v<T> and is_move_assignable_v<T> {
|
||||
if (_set) {
|
||||
_val = fennec::move(val);
|
||||
} else {
|
||||
fennec::construct(&_val, fennec::move(val));
|
||||
_set = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Assignment
|
||||
/// \val The optional to copy
|
||||
constexpr optional& operator=(const optional& opt) requires is_copy_constructible_v<T> and is_copy_assignable_v<T> {
|
||||
if (_set != opt._set) {
|
||||
_set = opt._set;
|
||||
if (_set) { // Construct
|
||||
fennec::construct(&_val, opt._val);
|
||||
} else { // Destruct
|
||||
_val.~T();
|
||||
_root = 0;
|
||||
}
|
||||
} else if (_set) { // Copy Assignment
|
||||
_val = opt._val;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Assignment
|
||||
/// \val The optional to move
|
||||
constexpr optional& operator=(optional&& opt) noexcept requires is_move_constructible_v<T> and is_move_assignable_v<T> {
|
||||
if (_set != opt._set) {
|
||||
_set = opt._set;
|
||||
if (_set) { // Construct
|
||||
fennec::construct(&_val, fennec::move(opt._val));
|
||||
} else { // Destruct
|
||||
_val.~T();
|
||||
_root = 0;
|
||||
}
|
||||
} else if (_set) { // Copy Assignment
|
||||
_val = fennec::move(opt._val);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr T& emplace(ArgsT&&...args) {
|
||||
if (_set) {
|
||||
_val = T(fennec::forward<ArgsT>(args)...);
|
||||
} else {
|
||||
fennec::construct(&_val, fennec::forward<ArgsT>(args)...);
|
||||
_set = true;
|
||||
}
|
||||
return _val;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->operator=(nullopt);
|
||||
}
|
||||
|
||||
|
||||
// Operators ===========================================================================================================
|
||||
|
||||
constexpr operator bool() const {
|
||||
return _set;
|
||||
}
|
||||
|
||||
constexpr T* operator->() noexcept {
|
||||
return _set ? &_val : nullptr;
|
||||
}
|
||||
|
||||
constexpr const T* operator->() const noexcept {
|
||||
return _set ? &_val : nullptr;
|
||||
}
|
||||
|
||||
constexpr T& operator*() & noexcept {
|
||||
assertd(_set, "Attempted to reference the value of an unset optional");
|
||||
return _val;
|
||||
}
|
||||
|
||||
constexpr const T& operator*() const& noexcept {
|
||||
assertd(_set, "Attempted to reference the value of an unset optional");
|
||||
return _val;
|
||||
}
|
||||
|
||||
constexpr T&& operator*() && noexcept {
|
||||
assertd(_set, "Attempted to reference the value of an unset optional");
|
||||
return _val;
|
||||
}
|
||||
|
||||
constexpr const T&& operator*() const&& noexcept {
|
||||
assertd(_set, "Attempted to reference the value of an unset optional");
|
||||
return _val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
union {
|
||||
char _root;
|
||||
T _val;
|
||||
};
|
||||
bool _set;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_OPTIONAL_H
|
||||
91
include/fennec/containers/pair.h
Normal file
91
include/fennec/containers/pair.h
Normal file
@@ -0,0 +1,91 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_PAIR_H
|
||||
#define FENNEC_CONTAINERS_PAIR_H
|
||||
|
||||
#include <fennec/lang/hashing.h>
|
||||
#include <fennec/lang/utility.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// TODO: Document
|
||||
|
||||
template<typename T0, typename T1>
|
||||
struct pair {
|
||||
constexpr pair() = default;
|
||||
constexpr ~pair() = default;
|
||||
|
||||
constexpr pair(const T0& x, const T1& y)
|
||||
: first(x)
|
||||
, second(y) {
|
||||
}
|
||||
|
||||
constexpr pair(T0&& x, T1&& y) noexcept
|
||||
: first(fennec::forward<T0>(x))
|
||||
, second(fennec::forward<T1>(y)) {
|
||||
}
|
||||
|
||||
constexpr pair(const pair&) = default;
|
||||
constexpr pair(pair&&) noexcept = default;
|
||||
|
||||
pair& operator=(const pair&) = default;
|
||||
pair& operator=(pair&&) noexcept = default;
|
||||
|
||||
bool operator==(const pair& p) const {
|
||||
return first == p.first and second == p.second;
|
||||
}
|
||||
|
||||
bool operator!=(const pair& p) const {
|
||||
return first != p.first or second != p.second;
|
||||
}
|
||||
|
||||
bool operator<(const pair& p) const {
|
||||
return first < p.first or (first == p.first and second < p.second);
|
||||
}
|
||||
|
||||
bool operator<=(const pair& p) const {
|
||||
return first < p.first or (first == p.first and second <= p.second);
|
||||
}
|
||||
|
||||
bool operator>(const pair& p) const {
|
||||
return first > p.first or (first == p.first and second > p.second);
|
||||
}
|
||||
|
||||
bool operator>=(const pair& p) const {
|
||||
return first > p.first or (first == p.first and second >= p.second);
|
||||
}
|
||||
|
||||
T0 first;
|
||||
T1 second;
|
||||
};
|
||||
|
||||
template<typename T0, typename T1>
|
||||
struct hash<pair<T0, T1>> : hash<T0>, hash<T1> {
|
||||
constexpr size_t operator()(const pair<T0, T1>& p) const {
|
||||
return fennec::pair_hash( // pair the hashes of both elements
|
||||
hash<T0>::operator()(p.first),
|
||||
hash<T1>::operator()(p.second)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_PAIR_H
|
||||
297
include/fennec/containers/set.h
Normal file
297
include/fennec/containers/set.h
Normal file
@@ -0,0 +1,297 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_CONTAINERS_SET_H
|
||||
#define FENNEC_CONTAINERS_SET_H
|
||||
|
||||
// https://programming.guide/robin-hood-hashing.html
|
||||
|
||||
#include <fennec/containers/optional.h>
|
||||
#include <fennec/math/ext/primes.h>
|
||||
#include <fennec/memory/allocator.h>
|
||||
#include <fennec/lang/hashing.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// TODO: Document
|
||||
|
||||
template<typename T, class Hash = hash<T>, class Alloc = allocator<T>>
|
||||
struct set {
|
||||
public:
|
||||
using alloc_t = typename allocator_traits<Alloc>::template rebind<T>;
|
||||
using hash_t = Hash;
|
||||
using elem_t = T;
|
||||
|
||||
class iterator;
|
||||
static constexpr size_t npos = -1;
|
||||
|
||||
private:
|
||||
struct node {
|
||||
optional<elem_t> value;
|
||||
int psl;
|
||||
|
||||
constexpr node() = default;
|
||||
constexpr ~node() = default;
|
||||
};
|
||||
|
||||
public:
|
||||
constexpr set()
|
||||
: _alloc()
|
||||
, _hash()
|
||||
, _size(0) {
|
||||
};
|
||||
|
||||
constexpr set(const hash_t& hash)
|
||||
: _alloc()
|
||||
, _hash(hash)
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(hash_t&& hash) noexcept
|
||||
: _alloc()
|
||||
, _hash(hash)
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(const alloc_t& alloc)
|
||||
: _alloc(alloc)
|
||||
, _hash()
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash()
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(const hash_t& hash, const alloc_t& alloc)
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(const hash_t& hash, alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(hash_t&& hash, alloc_t&& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0) {
|
||||
}
|
||||
|
||||
constexpr set(hash_t&& hash, const alloc_t& alloc) noexcept
|
||||
: _alloc(alloc)
|
||||
, _hash(hash)
|
||||
, _size(0) {}
|
||||
|
||||
constexpr set(const set& set)
|
||||
: _alloc(set._alloc)
|
||||
, _hash(set._hash)
|
||||
, _size(set._size) {
|
||||
}
|
||||
|
||||
constexpr set(set&& set) noexcept
|
||||
: _alloc(fennec::move(set._alloc))
|
||||
, _hash(fennec::move(set._hash))
|
||||
, _size(fennec::move(set._size)) {
|
||||
}
|
||||
|
||||
constexpr ~set() = default;
|
||||
|
||||
constexpr size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
constexpr size_t capacity() const {
|
||||
return _alloc.capacity();
|
||||
}
|
||||
|
||||
constexpr void insert(elem_t&& val) {
|
||||
if (_size >= capacity()) { // expand when full
|
||||
_expand();
|
||||
}
|
||||
|
||||
elem_t value = fennec::forward<elem_t>(val);
|
||||
size_t i = _hash(value) % capacity(); // Initial search index
|
||||
int psl = 0;
|
||||
while (_alloc[i].value) { // Search for empty cell
|
||||
if (*_alloc[i].value == val) { // Check to see if this element is already inserted
|
||||
return;
|
||||
}
|
||||
if (psl >= _alloc[i].psl) { // When psl is higher, swap
|
||||
fennec::swap(*_alloc[i].value, value);
|
||||
fennec::swap(_alloc[i].psl, psl);
|
||||
}
|
||||
i = (i + 1) % capacity(); ++psl;
|
||||
}
|
||||
_alloc[i].value = fennec::move(value);
|
||||
_alloc[i].psl = psl;
|
||||
++_size;
|
||||
}
|
||||
|
||||
constexpr void insert(const elem_t& val) {
|
||||
elem_t value = val; // Copy Constructor invoked here
|
||||
this->insert(fennec::move(value)); // Only invokes moves
|
||||
}
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr void emplace(ArgsT&&...args) {
|
||||
elem_t value = elem_t(fennec::forward<ArgsT>(args)...); // Constructor invoked here
|
||||
this->insert(fennec::move(value)); // Only invokes moves
|
||||
}
|
||||
|
||||
constexpr iterator find(const elem_t& val) const {
|
||||
size_t i = _hash(val) % capacity(); // Initial search index
|
||||
int psl = 0;
|
||||
|
||||
// Loop while there is a value and its psl is greater than our probe
|
||||
while (_alloc[i].value && _alloc[i].psl > psl) {
|
||||
if (*_alloc[i].value == val) {
|
||||
return iterator(this, i);
|
||||
}
|
||||
i = (i + 1) % capacity(); ++psl;
|
||||
}
|
||||
|
||||
return iterator(this, npos);
|
||||
}
|
||||
|
||||
constexpr bool contains(const elem_t& val) const {
|
||||
return this->find(val) != end();
|
||||
}
|
||||
|
||||
constexpr void erase(iterator it) {
|
||||
size_t i = it._i;
|
||||
if (i >= capacity()) {
|
||||
return;
|
||||
} // These are separated due to compilers being inconsistent
|
||||
if (not _alloc[i].value) {
|
||||
return;
|
||||
}
|
||||
|
||||
_alloc[i].value = nullopt;
|
||||
--_size;
|
||||
size_t p = i;
|
||||
while (_alloc[i = (i + 1) % capacity()].value) {
|
||||
size_t psl = _alloc[i].psl;
|
||||
if (psl == 0) break;
|
||||
|
||||
fennec::swap(_alloc[i - 1].value, _alloc[i].value);
|
||||
_alloc[p].psl = psl - 1;
|
||||
p = i;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void erase(const elem_t& val) {
|
||||
this->erase(this->find(val));
|
||||
}
|
||||
|
||||
|
||||
// ITERATOR ============================================================================================================
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
constexpr iterator(const set* set, size_t i)
|
||||
: _set(set)
|
||||
, _i(i) {
|
||||
}
|
||||
|
||||
constexpr ~iterator() {
|
||||
_set = nullptr;
|
||||
}
|
||||
|
||||
// prefix operator
|
||||
constexpr friend iterator& operator++(iterator& rhs) {
|
||||
while (++rhs._i < capacity()) {
|
||||
if (rhs._set->_alloc[rhs._i]) {
|
||||
return rhs;
|
||||
}
|
||||
}
|
||||
rhs._i = npos;
|
||||
return rhs;
|
||||
}
|
||||
|
||||
constexpr friend iterator operator++(iterator& lhs, int) {
|
||||
iterator prev = lhs;
|
||||
++lhs;
|
||||
return prev;
|
||||
}
|
||||
|
||||
constexpr const elem_t& operator*() const {
|
||||
return *_set->_alloc[_i].value;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator& it) {
|
||||
return _set == it._set and _i == it._i;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const iterator& it) {
|
||||
return _set != it._set or _i != it._i;
|
||||
}
|
||||
|
||||
private:
|
||||
const set* _set;
|
||||
size_t _i;
|
||||
};
|
||||
|
||||
constexpr iterator begin() const {
|
||||
iterator it(this, 0);
|
||||
if (not _alloc[it._i].value) {
|
||||
++it;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
constexpr iterator end() const {
|
||||
return iterator(this, npos);
|
||||
}
|
||||
|
||||
|
||||
// PRIVATE =============================================================================================================
|
||||
|
||||
private:
|
||||
constexpr void _expand() {
|
||||
set cpy; // Create a new set
|
||||
cpy._alloc.allocate(
|
||||
fennec::next_prime2(_alloc.capacity())
|
||||
);
|
||||
fennec::memset(cpy._alloc.data(), 0, cpy._alloc.size());
|
||||
|
||||
// rehash
|
||||
for (size_t i = 0; i < capacity(); ++i) {
|
||||
if (_alloc[i].value) {
|
||||
cpy.insert(fennec::move(*_alloc[i].value));
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
fennec::swap(_alloc, cpy._alloc);
|
||||
}
|
||||
|
||||
allocation<node, alloc_t> _alloc;
|
||||
hash_t _hash;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_CONTAINERS_SET_H
|
||||
@@ -99,7 +99,8 @@ public:
|
||||
/// \details adds additional character for null termination. Ignores whether str is null-terminated.
|
||||
/// This constructor makes the assumption that `n` is the intended number of characters.
|
||||
constexpr _string(const char* str, size_t n)
|
||||
: _str(str, n + 1) {
|
||||
: _str(n + 1) {
|
||||
fennec::memcpy(_str.data(), str, n);
|
||||
_str[n] = '\0';
|
||||
}
|
||||
|
||||
@@ -318,7 +319,7 @@ public:
|
||||
constexpr void resize(size_t n) {
|
||||
size_t i = size();
|
||||
_str.reallocate(n + 1);
|
||||
if (n > i) fennec::memset(_str.data() + i, '\0', n - i);
|
||||
if (n > i) fennec::memset(_str.data() + i, '\0', n + 1 - i);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -387,6 +388,10 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
friend constexpr _string operator+(char c, _string& str) {
|
||||
return _string(c, 1) + str;
|
||||
}
|
||||
|
||||
constexpr _string operator+(const cstring& str) const {
|
||||
_string res(size() + str.size()); // Make a new string with the size of this + str
|
||||
fennec::memcpy(&res[0], _str.data(), size()); // Copy the contents of this
|
||||
|
||||
@@ -46,7 +46,12 @@
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assert(expr, desc)
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`.
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`. Only halts in debug mode.
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assertf(expr, desc)
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// Make an assertion with expression `expr` and provide a description `desc`. Always halts.
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// assertd(expr, desc)
|
||||
@@ -65,15 +70,20 @@
|
||||
|
||||
using assert_handler = void (*)(const char *, const char *, int , const char *);
|
||||
|
||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc);
|
||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* desc, bool halt);
|
||||
|
||||
// flagged unlikely to optimize branch prediction
|
||||
#define assert(expression, description) \
|
||||
if(not(expression)) [[unlikely]] { \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description); \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, not FENNEC_RELEASE); \
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define assertf(expression, description) \
|
||||
if(not(expression)) [[unlikely]] { \
|
||||
__assert_impl(#expression, __FILE__, __LINE__, __PRETTY_FUNCTION__, description, true); \
|
||||
}
|
||||
|
||||
#if FENNEC_RELEASE
|
||||
#define assertd(expression, description) (0)
|
||||
#else
|
||||
#define assertd(expression, description) assert(expression, description)
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#ifndef FENNEC_LANG_CONDITIONAL_TYPES_H
|
||||
#define FENNEC_LANG_CONDITIONAL_TYPES_H
|
||||
|
||||
#include <fennec/lang/type_identity.h>
|
||||
|
||||
///
|
||||
/// \page fennec_lang_conditional_types Conditional Types
|
||||
///
|
||||
@@ -64,8 +66,6 @@
|
||||
///
|
||||
///
|
||||
|
||||
#include <fennec/lang/type_transforms.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
@@ -92,12 +92,12 @@ using conditional_t
|
||||
|
||||
// specialization of fennec::conditional for `true` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<true, T, F> : type_transform<T>{};
|
||||
struct conditional<true, T, F> : type_identity<T>{};
|
||||
|
||||
|
||||
// specialization of fennec::conditional for `false` case
|
||||
template<typename T, typename F>
|
||||
struct conditional<false, T, F> : type_transform<F>{};
|
||||
struct conditional<false, T, F> : type_identity<F>{};
|
||||
|
||||
|
||||
// fennec::detect ======================================================================================================
|
||||
|
||||
@@ -28,34 +28,34 @@ namespace fennec
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename> struct __make_unsigned : type_transform<undefined_t> {};
|
||||
template<typename> struct __make_unsigned : type_identity<undefined_t> {};
|
||||
|
||||
template<> struct __make_unsigned<char_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<uchar_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<schar_t> : type_transform<uchar_t> {};
|
||||
template<> struct __make_unsigned<short_t> : type_transform<ushort_t> {};
|
||||
template<> struct __make_unsigned<ushort_t> : type_transform<ushort_t> {};
|
||||
template<> struct __make_unsigned<uint_t> : type_transform<uint_t> {};
|
||||
template<> struct __make_unsigned<int_t> : type_transform<uint_t> {};
|
||||
template<> struct __make_unsigned<long_t> : type_transform<ulong_t> {};
|
||||
template<> struct __make_unsigned<ulong_t> : type_transform<ulong_t> {};
|
||||
template<> struct __make_unsigned<llong_t> : type_transform<ullong_t> {};
|
||||
template<> struct __make_unsigned<ullong_t> : type_transform<ullong_t> {};
|
||||
template<> struct __make_unsigned<char_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<uchar_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<schar_t> : type_identity<uchar_t> {};
|
||||
template<> struct __make_unsigned<short_t> : type_identity<ushort_t> {};
|
||||
template<> struct __make_unsigned<ushort_t> : type_identity<ushort_t> {};
|
||||
template<> struct __make_unsigned<uint_t> : type_identity<uint_t> {};
|
||||
template<> struct __make_unsigned<int_t> : type_identity<uint_t> {};
|
||||
template<> struct __make_unsigned<long_t> : type_identity<ulong_t> {};
|
||||
template<> struct __make_unsigned<ulong_t> : type_identity<ulong_t> {};
|
||||
template<> struct __make_unsigned<llong_t> : type_identity<ullong_t> {};
|
||||
template<> struct __make_unsigned<ullong_t> : type_identity<ullong_t> {};
|
||||
|
||||
|
||||
template<typename> struct __make_signed : type_transform<undefined_t> {};
|
||||
template<typename> struct __make_signed : type_identity<undefined_t> {};
|
||||
|
||||
template<> struct __make_signed<char_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<uchar_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<schar_t> : type_transform<schar_t> {};
|
||||
template<> struct __make_signed<short_t> : type_transform<short_t> {};
|
||||
template<> struct __make_signed<ushort_t> : type_transform<short_t> {};
|
||||
template<> struct __make_signed<uint_t> : type_transform<int_t> {};
|
||||
template<> struct __make_signed<int_t> : type_transform<int_t> {};
|
||||
template<> struct __make_signed<long_t> : type_transform<long_t> {};
|
||||
template<> struct __make_signed<ulong_t> : type_transform<long_t> {};
|
||||
template<> struct __make_signed<llong_t> : type_transform<llong_t> {};
|
||||
template<> struct __make_signed<ullong_t> : type_transform<llong_t> {};
|
||||
template<> struct __make_signed<char_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<uchar_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<schar_t> : type_identity<schar_t> {};
|
||||
template<> struct __make_signed<short_t> : type_identity<short_t> {};
|
||||
template<> struct __make_signed<ushort_t> : type_identity<short_t> {};
|
||||
template<> struct __make_signed<uint_t> : type_identity<int_t> {};
|
||||
template<> struct __make_signed<int_t> : type_identity<int_t> {};
|
||||
template<> struct __make_signed<long_t> : type_identity<long_t> {};
|
||||
template<> struct __make_signed<ulong_t> : type_identity<long_t> {};
|
||||
template<> struct __make_signed<llong_t> : type_identity<llong_t> {};
|
||||
template<> struct __make_signed<ullong_t> : type_identity<llong_t> {};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace fennec
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename FirstT, typename... RestT> struct __first_element : type_transform<FirstT>{};
|
||||
template<typename FirstT, typename... RestT> struct __first_element : type_identity<FirstT>{};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ template<typename> struct __is_floating_point : false_type {};
|
||||
template<> struct __is_floating_point<float_t> : true_type {};
|
||||
template<> struct __is_floating_point<double_t> : true_type {};
|
||||
|
||||
template<typename> struct __is_pointer : false_type {};
|
||||
template<typename T> struct __is_pointer<T*> : true_type {};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
55
include/fennec/lang/detail/__type_transforms.h
Normal file
55
include/fennec/lang/detail/__type_transforms.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
#define FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename _Tp, typename = void>
|
||||
struct __add_lvalue_reference {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __add_lvalue_reference<_Tp, void_t<_Tp&>> {
|
||||
using type = _Tp&;
|
||||
};
|
||||
|
||||
|
||||
template<typename _Tp, typename = void>
|
||||
struct __add_rvalue_reference {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __add_rvalue_reference<_Tp, void_t<_Tp&&>> {
|
||||
using type = _Tp&&;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_DETAIL_TYPE_TRANSFORMS_H
|
||||
89
include/fennec/lang/hashing.h
Normal file
89
include/fennec/lang/hashing.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_LANG_HASHING_H
|
||||
#define FENNEC_LANG_HASHING_H
|
||||
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/lang/type_traits.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Struct for hashing types, there is no default hashing function
|
||||
/// \tparam Key The type to hash
|
||||
template<typename Key> struct hash;
|
||||
|
||||
// Murmur3 Hash for 64-bit ints
|
||||
template<>
|
||||
struct hash<uint64_t> {
|
||||
using type_t = uint64_t;
|
||||
constexpr size_t operator()(uint64_t x) const {
|
||||
// Murmur3
|
||||
x ^= x >> 33U;
|
||||
x *= 0xff51afd7ed558ccd;
|
||||
x ^= x >> 33U;
|
||||
x *= 0xc4ceb9fe1a85ec53;
|
||||
x ^= x >> 33U;
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
// Wrapper for casting ints
|
||||
template<typename IntT>
|
||||
requires is_integral_v<IntT>
|
||||
struct hash<IntT> : hash<uint64_t> {
|
||||
using type_t = IntT;
|
||||
};
|
||||
|
||||
// Wrapper for pointers
|
||||
template<typename PtrT>
|
||||
requires is_pointer_v<PtrT>
|
||||
struct hash<PtrT> : hash<uintptr_t> {
|
||||
};
|
||||
|
||||
// Float
|
||||
template<>
|
||||
struct hash<float> : hash<uint32_t> {
|
||||
constexpr size_t operator()(float x) const {
|
||||
return hash<uint32_t>::operator()(bit_cast<uint32_t>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<double> : hash<uint64_t> {
|
||||
constexpr size_t operator()(double x) const {
|
||||
return hash<uint64_t>::operator()(bit_cast<uint64_t>(x));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// \brief Pairs two hashes
|
||||
/// \param x first hash
|
||||
/// \param y second hash
|
||||
/// \returns a pairing of the two hashes
|
||||
constexpr size_t pair_hash(size_t x, size_t y) {
|
||||
// Szudzik Pairing
|
||||
return (x >= y ? (x * x) + x + y : (y * y) + x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_HASHING_H
|
||||
@@ -142,14 +142,44 @@
|
||||
# define FENNEC_HAS_BUILTIN_IS_CLASS
|
||||
#endif
|
||||
|
||||
// CONSTRUCTORS ========================================================================================================
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_constructible)
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(type, ...) __is_constructible(type, __VA_ARGS__)
|
||||
# define FENNEC_BUILTIN_IS_CONSTRUCTIBLE(type, ...) __is_constructible(type __VA_OPT__(,) __VA_ARGS__)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_CONSTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_trivially_constructible)
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(type) __is_trivially_constructible(type)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__has_trivial_destructor)
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 1
|
||||
# define FENNEC_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE(type) __has_trivial_destructor(type)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE 0
|
||||
#endif
|
||||
|
||||
|
||||
// ASSIGNMENTS =========================================================================================================
|
||||
|
||||
// Difficult and Inconsistent without intrinsics
|
||||
#if __has_builtin(__is_assignable)
|
||||
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 1
|
||||
# define FENNEC_BUILTIN_IS_ASSIGNABLE(a, b) __is_assignable(a, b)
|
||||
#else
|
||||
# define FENNEC_HAS_BUILTIN_IS_ASSIGNABLE 0
|
||||
#endif
|
||||
|
||||
|
||||
// Type Traits
|
||||
// can_convert is also very difficult to implement without intrinsics
|
||||
#if __has_builtin(__is_convertible)
|
||||
|
||||
57
include/fennec/lang/type_identity.h
Normal file
57
include/fennec/lang/type_identity.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_LANG_TYPE_IDENTITY_H
|
||||
#define FENNEC_LANG_TYPE_IDENTITY_H
|
||||
|
||||
///
|
||||
/// \page fennec_lang_type_identity Type Identity
|
||||
///
|
||||
/// \brief Part of the fennec metaprogramming library. This header defines structures for copying types with different traits
|
||||
/// or rather, transform them, at compile time.
|
||||
///
|
||||
/// \code #include <fennec/lang/type_identity.h> \endcode
|
||||
///
|
||||
///
|
||||
/// <table width="100%" class="fieldtable" id="table_fennec_lang_type_identity">
|
||||
/// <tr><th style="vertical-align: top">Syntax
|
||||
/// <th style="vertical-align: top">Description
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::type_identity "type_identity<TypeT>::type"<br>
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydetails fennec::type_identity
|
||||
/// </table>
|
||||
///
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Base Class for Type Transformations
|
||||
///
|
||||
/// \details resembles a transformation from one type to T, the result is stored in the member type_transform::type
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct type_identity {
|
||||
|
||||
/// \brief the type to transform into
|
||||
using type = T;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_TYPE_IDENTITY_H
|
||||
@@ -272,6 +272,22 @@ template<typename T> struct is_floating_point
|
||||
template<typename T> constexpr bool_t is_floating_point_v = is_floating_point<T> {};
|
||||
|
||||
|
||||
// Pointer Types =======================================================================================================
|
||||
|
||||
///
|
||||
/// \brief check if \p T is of a floating point type
|
||||
///
|
||||
/// \details Checks if type `T` is a floating point type and store it in `is_same::value`.
|
||||
/// \tparam T type to check
|
||||
template<typename T> struct is_pointer
|
||||
: detail::__is_pointer<remove_cvr_t<T>>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for ```is_floating_point<T>::value```
|
||||
/// \tparam T type to check
|
||||
template<typename T> constexpr bool_t is_pointer_v = is_pointer<T> {};
|
||||
|
||||
|
||||
|
||||
// Arithmetic Types ====================================================================================================
|
||||
|
||||
@@ -339,7 +355,7 @@ template<typename FromT, typename ToT> struct is_convertible
|
||||
template<typename FromT, typename ToT> constexpr bool_t is_convertible_v = is_convertible<FromT, ToT>{};
|
||||
|
||||
|
||||
// fennec::is_constructible ===============================================================================================
|
||||
// fennec::is_constructible ============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`.
|
||||
@@ -354,7 +370,106 @@ template<typename ClassT, typename...ArgsT> struct is_constructible
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_constructible_v = is_constructible<ClassT, ArgsT...>{};
|
||||
|
||||
|
||||
// fennec::
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is default constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_default_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT,)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_default_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_default_constructible_v = is_default_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_copy_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT, add_lvalue_reference_t<const ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_copy_constructible_v = is_copy_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_move_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_CONSTRUCTIBLE(ClassT, add_rvalue_reference_t<ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_constructible<ClassT>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_move_constructible_v = is_move_constructible<ClassT>{};
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is trivially constructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_trivially_constructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_CONSTRUCTIBLE(ClassT)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_trivially_constructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT> constexpr bool_t is_trivially_constructible_v = is_trivially_constructible<ClassT>{};
|
||||
|
||||
|
||||
// fennec::is_trivially_destructible ===================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is trivially destructible
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_trivially_destructible
|
||||
: bool_constant<FENNEC_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE(ClassT)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_trivially_destructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT> constexpr bool_t is_trivially_destructible_v = is_trivially_destructible<ClassT>{};
|
||||
|
||||
|
||||
// fennec::is_assignable ===============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` can be constructed with `ArgsT,` i.e. `ClassT(ArgsT...)`.
|
||||
/// This may be read as "is `ClassT` constructible with `ArgsT`"
|
||||
/// \tparam ClassAT The class type to test
|
||||
/// \tparam ClassBT The arguments for the specific constructor
|
||||
template<typename ClassAT, typename ClassBT> struct is_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(ClassAT, ClassBT)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_constructible<ClassT, ArgsT...>::value`
|
||||
template<typename ClassT, typename...ArgsT> constexpr bool_t is_assignable_v = is_assignable<ClassT, ArgsT...>{};
|
||||
|
||||
|
||||
// fennec::is_copy_assignable ==========================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is copy assignable
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_copy_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(add_lvalue_reference_t<ClassT>, add_lvalue_reference_t<const ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_copy_assignable<ClassT>::value`
|
||||
template<typename ClassT> constexpr bool_t is_copy_assignable_v = is_copy_assignable<ClassT>{};
|
||||
|
||||
|
||||
// fennec::is_move_assignable ==========================================================================================
|
||||
|
||||
///
|
||||
/// \brief Check if `ClassT` is move assignable
|
||||
/// \tparam ClassT The class type to test
|
||||
template<typename ClassT> struct is_move_assignable
|
||||
: bool_constant<FENNEC_BUILTIN_IS_ASSIGNABLE(add_lvalue_reference_t<ClassT>, add_rvalue_reference_t<ClassT>)> {};
|
||||
|
||||
///
|
||||
/// \brief Shorthand for `is_move_assignable<ClassT>::value`
|
||||
template<typename ClassT> constexpr bool_t is_move_assignable_v = is_move_assignable<ClassT>{};
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#ifndef FENNEC_LANG_TYPE_TRANSFORMS_H
|
||||
#define FENNEC_LANG_TYPE_TRANSFORMS_H
|
||||
|
||||
#include <fennec/lang/type_identity.h>
|
||||
#include <fennec/lang/detail/__type_transforms.h>
|
||||
|
||||
///
|
||||
/// \page fennec_lang_type_transforms Type Transforms
|
||||
///
|
||||
@@ -44,11 +47,6 @@
|
||||
/// <tr><th style="vertical-align: top">Syntax
|
||||
/// <th style="vertical-align: top">Description
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::type_transform "type_transform<TypeT>::type"<br>
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
/// \copydetails fennec::type_transform
|
||||
///
|
||||
/// <tr><td width="50%" style="vertical-align: top"> <br>
|
||||
/// \ref fennec::add_pointer "add_pointer<TypeT>::type"<br>
|
||||
/// \ref fennec::add_pointer_t "add_pointer_t<TypeT>"
|
||||
/// <td width="50%" style="vertical-align: top">
|
||||
@@ -127,22 +125,6 @@
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
// fennec::type_transform ==============================================================================================
|
||||
|
||||
///
|
||||
/// \brief Base Class for Type Transformations
|
||||
///
|
||||
/// \details resembles a transformation from one type to T, the result is stored in the member type_transform::type
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct type_transform {
|
||||
|
||||
///
|
||||
/// \brief the type to transform into
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Pointer Conversions =================================================================================================
|
||||
|
||||
///
|
||||
@@ -150,7 +132,7 @@ template<typename T> struct type_transform {
|
||||
///
|
||||
/// \details adds a pointer to the provided type such that `T` becomes `T*`
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct add_pointer : type_transform<T*>{};
|
||||
template<typename T> struct add_pointer : type_identity<T*>{};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_pointer<T>::type`
|
||||
@@ -162,10 +144,10 @@ template<typename T> using add_pointer_t = typename add_pointer<T>::type;
|
||||
///
|
||||
/// \details removes a pointer from the provided type such that `T*` becomes `T`
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct remove_pointer : type_transform<T> {};
|
||||
template<typename T> struct remove_pointer : type_identity<T> {};
|
||||
|
||||
// specialization for T*
|
||||
template<typename T> struct remove_pointer<T*> : type_transform<T> {};
|
||||
template<typename T> struct remove_pointer<T*> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_pointer<T>::type`
|
||||
@@ -180,7 +162,7 @@ template<typename T> using remove_pointer_t = typename remove_pointer<T>::type;
|
||||
///
|
||||
/// \details adds a pointer to the provided type such that `T` becomes `T&`
|
||||
/// \tparam T Resultant Type
|
||||
template<typename T> struct add_reference : type_transform<T&> {};
|
||||
template<typename T> struct add_reference : type_identity<T&> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_reference<T>::type`
|
||||
@@ -192,19 +174,43 @@ template<typename T> using add_reference_t = typename add_reference<T>::type;
|
||||
///
|
||||
/// \details removes references from the provided type such that `T&` and `T&&` become `T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_reference : type_transform<T> {};
|
||||
template<typename T> struct remove_reference : type_identity<T> {};
|
||||
|
||||
// specialization for `T&`
|
||||
template<typename T> struct remove_reference<T&> : type_transform<T> {};
|
||||
template<typename T> struct remove_reference<T&> : type_identity<T> {};
|
||||
|
||||
// specialization for `T&&`
|
||||
template<typename T> struct remove_reference<T&&> : type_transform<T> {};
|
||||
template<typename T> struct remove_reference<T&&> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
|
||||
///
|
||||
/// \brief add a lvalue reference to \p T
|
||||
///
|
||||
/// \details adds a lvalue reference to the provided type such that 'T' becomes 'T&'
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_lvalue_reference : detail::__add_lvalue_reference<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
|
||||
|
||||
|
||||
///
|
||||
/// \brief add a rvalue reference to \p T
|
||||
///
|
||||
/// \details adds a rvalue reference to the provided type such that 'T' becomes 'T&&'
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_rvalue_reference : detail::__add_rvalue_reference<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_reference<T>::type`
|
||||
template<typename T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
|
||||
|
||||
|
||||
|
||||
// Const & Volatile Conversions ========================================================================================
|
||||
|
||||
@@ -213,14 +219,14 @@ template<typename T> using remove_reference_t = typename remove_reference<T>::t
|
||||
///
|
||||
/// \details adds const qualification to the provided type such that `T` becomes `const T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_const : type_transform<const T> {};
|
||||
template<typename T> struct add_const : type_identity<const T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_const<T>::type`
|
||||
template<typename T> using add_const_t = typename add_const<T>::type;
|
||||
|
||||
// specialization for const types
|
||||
template<typename T> struct add_const<const T> : type_transform<const T> {};
|
||||
template<typename T> struct add_const<const T> : type_identity<const T> {};
|
||||
|
||||
|
||||
///
|
||||
@@ -228,14 +234,14 @@ template<typename T> struct add_const<const T> : type_transform<const T> {};
|
||||
///
|
||||
/// \details removes const qualification from the provided type such that `const T` becomes `T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_const : type_transform<T> {};
|
||||
template<typename T> struct remove_const : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_const<T>::type`
|
||||
template<typename T> using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
// specialization for const types
|
||||
template<typename T> struct remove_const<const T> : type_transform<T> {};
|
||||
template<typename T> struct remove_const<const T> : type_identity<T> {};
|
||||
|
||||
|
||||
|
||||
@@ -244,14 +250,14 @@ template<typename T> struct remove_const<const T> : type_transform<T> {};
|
||||
///
|
||||
/// \details removes references from the provided type such that `T` becomes `volatile T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_volatile : type_transform<volatile T> {};
|
||||
template<typename T> struct add_volatile : type_identity<volatile T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_volatile<T>::type`
|
||||
template<typename T> using add_volatile_t = typename add_volatile<T>::type;
|
||||
|
||||
// specialization for volatile types
|
||||
template<typename T> struct add_volatile<volatile T> : type_transform<volatile T> {};
|
||||
template<typename T> struct add_volatile<volatile T> : type_identity<volatile T> {};
|
||||
|
||||
|
||||
///
|
||||
@@ -259,14 +265,14 @@ template<typename T> struct add_volatile<volatile T> : type_transform<volatile T
|
||||
///
|
||||
/// \details removes references from the provided type such that `volatile T` becomes `T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_volatile : type_transform<T> {};
|
||||
template<typename T> struct remove_volatile : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_volatile<T>::type`
|
||||
template<typename T> using remove_volatile_t = typename remove_volatile<T>::type;
|
||||
|
||||
// specialization for volatile types
|
||||
template<typename T> struct remove_volatile<volatile T> : type_transform<T> {};
|
||||
template<typename T> struct remove_volatile<volatile T> : type_identity<T> {};
|
||||
|
||||
|
||||
|
||||
@@ -276,20 +282,20 @@ template<typename T> struct remove_volatile<volatile T> : type_transform<T> {};
|
||||
/// \details removes references from the provided type such that `T`, `const T`, and `volatile T` become
|
||||
/// `const volatile T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_cv : type_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv : type_identity<const volatile T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_cv<T>::type`
|
||||
template<typename T> using add_cv_t = typename add_cv<T>::type;
|
||||
|
||||
// specialization for const types
|
||||
template<typename T> struct add_cv<const T> : type_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv<const T> : type_identity<const volatile T> {};
|
||||
|
||||
// specialization for volatile types
|
||||
template<typename T> struct add_cv<volatile T> : type_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv<volatile T> : type_identity<const volatile T> {};
|
||||
|
||||
// specialization for const volatile types
|
||||
template<typename T> struct add_cv<const volatile T> : type_transform<const volatile T> {};
|
||||
template<typename T> struct add_cv<const volatile T> : type_identity<const volatile T> {};
|
||||
|
||||
|
||||
|
||||
@@ -299,16 +305,16 @@ template<typename T> struct add_cv<const volatile T> : type_transform<const vola
|
||||
/// \details removes const and volatile from the provided type such that `const T`, `volatile T`, and
|
||||
/// `const volatile T` become `T`
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_cv : type_transform<T> {};
|
||||
template<typename T> struct remove_cv : type_identity<T> {};
|
||||
|
||||
// specialization for const types
|
||||
template<typename T> struct remove_cv<const T> : type_transform<T> {};
|
||||
template<typename T> struct remove_cv<const T> : type_identity<T> {};
|
||||
|
||||
// specialization for volatile types
|
||||
template<typename T> struct remove_cv<volatile T> : type_transform<T> {};
|
||||
template<typename T> struct remove_cv<volatile T> : type_identity<T> {};
|
||||
|
||||
// specialization for const volatile types
|
||||
template<typename T> struct remove_cv<const volatile T> : type_transform<T> {};
|
||||
template<typename T> struct remove_cv<const volatile T> : type_identity<T> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename remove_cv<T>::type`
|
||||
@@ -321,7 +327,7 @@ template<typename T> using remove_cv_t = typename remove_cv<T>::type;
|
||||
///
|
||||
/// \details adds references and const volatile qualifiers to the provided type.
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct add_cvr : type_transform<add_reference_t<add_cv_t<T>>> {};
|
||||
template<typename T> struct add_cvr : type_identity<add_reference_t<add_cv_t<T>>> {};
|
||||
|
||||
///
|
||||
/// \brief shorthand for `typename add_cvr<T>::type`
|
||||
@@ -334,7 +340,7 @@ template<typename T> using add_cvr_t = typename add_cvr<T>::type;
|
||||
///
|
||||
/// \details removes const and volatile from the provided type such that
|
||||
/// \tparam T Reference Type
|
||||
template<typename T> struct remove_cvr : type_transform<remove_cv_t<remove_reference_t<T>>> {};
|
||||
template<typename T> struct remove_cvr : type_identity<remove_cv_t<remove_reference_t<T>>> {};
|
||||
|
||||
|
||||
///
|
||||
|
||||
@@ -242,7 +242,6 @@ namespace fennec
|
||||
/// \name Special Types
|
||||
/// @{
|
||||
|
||||
|
||||
using nullptr_t = decltype(nullptr); ///< \brief Null Pointer Type
|
||||
using intptr_t = intptr_t; ///< \brief Signed Integer Capable of Holding a Pointer to void
|
||||
using uintptr_t = uintptr_t; ///< \brief Unsigned Integer Capable of Holding a Pointer to void
|
||||
@@ -251,6 +250,7 @@ namespace fennec
|
||||
using size_t = size_t; ///< \brief Unsigned Integer Type Returned By `sizeof`, `sizeof...`, and `alignof`
|
||||
using ptrdiff_t = __PTRDIFF_TYPE__; ///< \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
||||
|
||||
|
||||
class undefined_t; ///< \brief undefined class for SFINAE
|
||||
template<typename...> using void_t = void; ///< \brief Void type used for SFINAE
|
||||
|
||||
@@ -266,12 +266,12 @@ namespace fennec
|
||||
using int8_t = schar_t; ///< \brief Signed 8-bit integer
|
||||
using int16_t = short_t; ///< \brief Signed 16-bit integer
|
||||
using int32_t = conditional_t<sizeof(int_t) == 4, int_t, long_t>; ///< \brief Signed 32-bit integer
|
||||
using int64_t = llong_t; ///< \brief Signed 64-bit integer
|
||||
using int64_t = conditional_t<sizeof(long_t) == 8, long_t, llong_t>; ///< \brief Signed 64-bit integer
|
||||
|
||||
using uint8_t = uchar_t; ///< \brief Unsigned 8-bit integer
|
||||
using uint16_t = ushort_t; ///< \brief Unsigned 16-bit integer
|
||||
using uint32_t = conditional_t<sizeof(uint_t) == 4, uint_t, ulong_t>; ///< \brief Unsigned 32-bit integer
|
||||
using uint64_t = ullong_t; ///< \brief Unsigned 64-bit integer
|
||||
using uint64_t = conditional_t<sizeof(ulong_t) == 8, ulong_t, ullong_t>; ///< \brief Unsigned 64-bit integer
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
///
|
||||
|
||||
#include <fennec/lang/type_transforms.h>
|
||||
#include <fennec/lang/type_traits.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
@@ -104,6 +105,29 @@ template<typename T> constexpr const remove_reference_t<T>& copy(T&& x) noexcept
|
||||
return x;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Swaps x and y
|
||||
/// \tparam T the fundamental type
|
||||
/// \param x first value
|
||||
/// \param y second value
|
||||
template<typename T> requires is_fundamental_v<T>
|
||||
constexpr void swap(T& x, T& y) noexcept {
|
||||
T a = x;
|
||||
x = y;
|
||||
y = a;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Swaps x and y without invoking destructor
|
||||
/// \tparam T the type
|
||||
/// \param x first value
|
||||
/// \param y second value
|
||||
template<typename T> constexpr void swap(T& x, T& y) noexcept {
|
||||
T a = fennec::move(x);
|
||||
x = fennec::move(y);
|
||||
y = fennec::move(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_UTILITY_H
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
///
|
||||
|
||||
#include <fennec/math/detail/__math.h>
|
||||
#include <fennec/math/vector.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
107
include/fennec/math/ext/primes.h
Normal file
107
include/fennec/math/ext/primes.h
Normal file
@@ -0,0 +1,107 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_MATH_EXT_PRIMES_H
|
||||
#define FENNEC_MATH_EXT_PRIMES_H
|
||||
|
||||
#include <fennec/math/exponential.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
template<typename genType>
|
||||
constexpr bool is_prime(genType x) {
|
||||
// Base Cases Covers
|
||||
if (x <= 1) return false; // Eliminates 0 and 1
|
||||
if (x <= 3) return true; // Eliminates 2 and 3
|
||||
if (x % 2 == 0 or x % 3 == 0) return false; // Eliminates even numbers and numbers divisible by 3
|
||||
// 4, 6, 8, 9, 10, 12, 14, 15
|
||||
if (x < 15) return true; // Covers 5, 7, 11, 13
|
||||
|
||||
// Due to the property of 15 being divisible by 5 and the nature of primes
|
||||
// All prime numbers must end in 1, 3, 7, 9
|
||||
// when x/15 is even, x%15 must be odd
|
||||
// and when x/15 is odd, x%15 must be even
|
||||
// To explain, when x/15 is even, 15*x/15 ends in 0, and when odd, ends in 5
|
||||
// Thus when x/15 is even, 15*x/15 ends in 0, and the results are 1, 3, 7, 11, 13
|
||||
// And when x/15 is even, 15*x/15 ends in 5, and the results are 2, 4, 8, 14
|
||||
genType mod15 = x % 15;
|
||||
genType mod15e = mod15 % 2;
|
||||
genType div15e = (x / 15) % 2;
|
||||
if (mod15e == div15e) return false;
|
||||
|
||||
// Iterate
|
||||
genType limit = sqrt(x);
|
||||
for (genType i = 5; i <= limit; i += 6) {
|
||||
if (x % i == 0 || x % (i + 2) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
constexpr genType next_prime(genType x) {
|
||||
genType n = (x + 1) / 6 + 1;
|
||||
|
||||
while (true) {
|
||||
x = (n++ * 6) - 1;
|
||||
if (fennec::is_prime(x)) return x;
|
||||
if (fennec::is_prime(x += 2)) return x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
constexpr genType next_prime2(genType x) {
|
||||
genType n = (x + 1) / 6;
|
||||
n *= 2;
|
||||
|
||||
while (true) {
|
||||
x = (n++ * 6) - 1;
|
||||
if (fennec::is_prime(x)) return x;
|
||||
if (fennec::is_prime(x += 2)) return x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
constexpr genType prev_prime(genType x) {
|
||||
genType n = (x + 1) / 6 - 1;
|
||||
|
||||
while (true) {
|
||||
x = (n-- * 6) - 1;
|
||||
if (fennec::is_prime(x)) return x;
|
||||
if (fennec::is_prime(x += 2)) return x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename genType>
|
||||
constexpr genType prev_prime2(genType x) {
|
||||
genType n = (x + 1) / 6;
|
||||
n /= 2;
|
||||
|
||||
while (true) {
|
||||
x = (n-- * 6) - 1;
|
||||
if (fennec::is_prime(x)) return x;
|
||||
if (fennec::is_prime(x += 2)) return x;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_MATH_EXT_PRIMES_H
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
///
|
||||
/// \brief Component Constructor
|
||||
/// \param w The real component
|
||||
/// \param w The scalar component
|
||||
/// \param x The coefficient of the `i` component
|
||||
/// \param y The coefficient of the `j` component
|
||||
/// \param z The coefficient of the `k` component
|
||||
@@ -113,10 +113,18 @@ public:
|
||||
data = { x, y, z, w };
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Component Constructor
|
||||
/// \param s The scalar component
|
||||
/// \param v The vector component
|
||||
constexpr quaternion(scalar_t s, vec3_t v) {
|
||||
data = { v.x, v.y, v.z, s };
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Vector Constructor
|
||||
/// \param v A 4d vector
|
||||
constexpr quaternion(const vec<scalar_t, 4>& v) {
|
||||
constexpr quaternion(const vec4_t& v) {
|
||||
data = v.data;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ constexpr qua<genType> rotation(const vec<genType, 3>& axis, genType angle) {
|
||||
vec<genType, 3> a = fennec::normalize(axis);
|
||||
const genType s = fennec::sin(angle);
|
||||
|
||||
return qua<genType>(fennec::cos(angle * genType(0.5)), s * a.x, s * a.y, s * a.z);
|
||||
return qua<genType>(fennec::cos(angle * genType(0.5)), s * a);
|
||||
}
|
||||
|
||||
/// \brief enum to denote the unit-axis of rotation
|
||||
|
||||
@@ -457,14 +457,11 @@ public:
|
||||
/// \param alloc the allocation to copy
|
||||
/// \returns a reference to `this`
|
||||
constexpr allocation& operator=(allocation&& alloc) noexcept {
|
||||
// Copy contents
|
||||
_alloc = alloc._alloc;
|
||||
_data = alloc._data;
|
||||
_capacity = alloc._capacity;
|
||||
|
||||
// Cleanup alloc
|
||||
alloc._data = nullptr;
|
||||
alloc._capacity = 0;
|
||||
// Copy contents
|
||||
fennec::swap(_alloc, alloc._alloc);
|
||||
fennec::swap(_data, alloc._data);
|
||||
fennec::swap(_capacity, alloc._capacity);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -525,6 +522,11 @@ public:
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
constexpr value_t operator[](size_t i) const requires is_fundamental_v<value_t> {
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
constexpr const value_t& operator[](size_t i) const {
|
||||
assertd(i < size(), "Array Out of Bounds");
|
||||
return _data[i];
|
||||
|
||||
188
include/fennec/memory/bytes.h
Normal file
188
include/fennec/memory/bytes.h
Normal file
@@ -0,0 +1,188 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_LANG_BYTES_H
|
||||
#define FENNEC_LANG_BYTES_H
|
||||
|
||||
#include <fennec/lang/assert.h>
|
||||
#include <fennec/lang/types.h>
|
||||
#include <fennec/lang/hashing.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
/// \brief byte type
|
||||
using byte_t = uint8_t;
|
||||
|
||||
///
|
||||
/// \brief container for handling byte arrays
|
||||
struct byte_array {
|
||||
public:
|
||||
|
||||
///
|
||||
/// \brief Default Constructor
|
||||
constexpr byte_array()
|
||||
: _carr(nullptr)
|
||||
, _size(0)
|
||||
, _const(true) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Constructor
|
||||
/// \param arr the buffer to wrap
|
||||
/// \param n the size of the buffer in bytes
|
||||
constexpr byte_array(void* arr, size_t n)
|
||||
: _arr(static_cast<byte_t*>(arr))
|
||||
, _size(n)
|
||||
, _const(false) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const Buffer Constructor
|
||||
/// \param arr the buffer to wrap
|
||||
/// \param n the size of the buffer in bytes
|
||||
constexpr byte_array(const void* arr, size_t n)
|
||||
: _carr(static_cast<const byte_t*>(arr))
|
||||
, _size(n)
|
||||
, _const(true) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Buffer Constructor
|
||||
/// \param arr the buffer to wrap
|
||||
/// \tparam n the size of the buffer in elements
|
||||
template<typename T, size_t n>
|
||||
constexpr byte_array(T arr[n])
|
||||
: byte_array(arr, n * sizeof(T)) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const Buffer Constructor
|
||||
/// \param arr the buffer to wrap
|
||||
/// \tparam n the size of the buffer in elements
|
||||
template<typename T, size_t n>
|
||||
constexpr byte_array(const T arr[n])
|
||||
: byte_array(arr, n * sizeof(T)) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns The size of the array in bytes
|
||||
constexpr size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a reference to the byte at `i`
|
||||
constexpr byte_t& operator[](int i) {
|
||||
assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
|
||||
assertd(i < _size, "Array Out of Bounds");
|
||||
return _arr[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const Array Access Operator
|
||||
/// \param i the index to access
|
||||
/// \returns a copy of the byte at `i`
|
||||
constexpr byte_t operator[](int i) const {
|
||||
assertd(not _const, "Attempted to Access Const-Qualified Memory as Non-Const");
|
||||
assertd(i < _size, "Array Out of Bounds");
|
||||
return _carr[i];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Cast Function
|
||||
/// \tparam T type to cast to
|
||||
/// \returns a pointer to the underlying buffer interpreted as an array of `T`
|
||||
template<typename T>
|
||||
constexpr T* cast() {
|
||||
void* temp = _arr;
|
||||
return static_cast<T*>(temp);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Const Cast Function
|
||||
/// \tparam T type to cast to
|
||||
/// \returns a pointer to the underlying buffer interpreted as an array of `T`
|
||||
template<typename T>
|
||||
constexpr const T* cast() const {
|
||||
const void* temp = _carr;
|
||||
return static_cast<T*>(temp);
|
||||
}
|
||||
|
||||
private:
|
||||
union { // hack to allow both const qualified and non-const strings
|
||||
byte_t* _arr;
|
||||
const byte_t* _carr;
|
||||
};
|
||||
size_t _size;
|
||||
bool _const;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Byte Array Hash Function
|
||||
template<>
|
||||
struct hash<byte_array> {
|
||||
size_t operator()(const byte_array& bytes) {
|
||||
|
||||
// Murmur2
|
||||
static constexpr uint64_t m = 0xc6a4a7935bd1e995;
|
||||
static constexpr uint64_t s = 0xff51afd7ed558ccd;
|
||||
static constexpr uint64_t r = 47;
|
||||
const uint64_t n = bytes.size();
|
||||
|
||||
uint64_t h = s ^ (n * m);
|
||||
const uint64_t* x = bytes.cast<>();
|
||||
const uint64_t* y = x + (n / sizeof(uint64_t));
|
||||
|
||||
while (x != y) {
|
||||
uint64_t k = *x++;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h ^= k;
|
||||
h *= m;
|
||||
}
|
||||
|
||||
const uint8_t* b = (const uint8_t*)x;
|
||||
switch (n & 7) {
|
||||
case 7: h ^= uint64_t(b[6]) << 48;
|
||||
case 6: h ^= uint64_t(b[5]) << 40;
|
||||
case 5: h ^= uint64_t(b[4]) << 32;
|
||||
case 4: h ^= uint64_t(b[3]) << 24;
|
||||
case 3: h ^= uint64_t(b[2]) << 16;
|
||||
case 2: h ^= uint64_t(b[1]) << 8;
|
||||
case 1: h ^= uint64_t(b[0]);
|
||||
h *= m;
|
||||
default:
|
||||
}
|
||||
|
||||
h ^= h >> r;
|
||||
h *= m;
|
||||
h ^= h >> r;
|
||||
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_LANG_BYTES_H
|
||||
@@ -71,7 +71,7 @@ private:
|
||||
using __diff_t = typename TypeT::diff_t; // Helper to prevent substitution issues with detecting the difference type
|
||||
|
||||
template<typename BaseT, typename OElemT> // Helper to prevent substitution issues with detecting a defined rebind
|
||||
using __rebind_helper = type_transform<typename BaseT::template rebind<OElemT>>;
|
||||
using __rebind_helper = type_identity<typename BaseT::template rebind<OElemT>>;
|
||||
|
||||
public:
|
||||
using pointer_t = ClassT;
|
||||
|
||||
@@ -54,19 +54,19 @@ struct nothrow_t
|
||||
size_t pagesize();
|
||||
|
||||
template<typename TypeT> void construct(TypeT* ptr) {
|
||||
ptr->TypeT();
|
||||
new(ptr) TypeT();
|
||||
}
|
||||
|
||||
template<typename TypeT> void construct(TypeT* ptr, const TypeT& val) {
|
||||
ptr->TypeT(val);
|
||||
new(ptr) TypeT(val);
|
||||
}
|
||||
|
||||
template<typename TypeT> void construct(TypeT* ptr, TypeT&& val) {
|
||||
ptr->TypeT(fennec::forward<TypeT>(val));
|
||||
new(ptr) TypeT(fennec::forward<TypeT>(val));
|
||||
}
|
||||
|
||||
template<typename TypeT, typename...ArgsT> void construct(TypeT* ptr, ArgsT...args) {
|
||||
ptr->TypeT(fennec::forward<TypeT>(args)...);
|
||||
template<typename TypeT, typename...ArgsT> void construct(TypeT* ptr, ArgsT&&...args) {
|
||||
new(ptr) TypeT(fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
|
||||
template<typename TypeT> void destruct(TypeT* ptr) {
|
||||
|
||||
22
include/fennec/platform/interface/dialog.h
Normal file
22
include/fennec/platform/interface/dialog.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_INTERFACE_DIALOG_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_DIALOG_H
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_DIALOG_H
|
||||
47
include/fennec/platform/interface/display.h
Normal file
47
include/fennec/platform/interface/display.h
Normal file
@@ -0,0 +1,47 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_INTERFACE_DISPLAY_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_DISPLAY_H
|
||||
|
||||
#include <fennec/platform/interface/fwd.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief Interface for display management
|
||||
class display
|
||||
{
|
||||
public:
|
||||
struct config {
|
||||
|
||||
};
|
||||
|
||||
virtual bool connected() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~display() = default;
|
||||
|
||||
private:
|
||||
config _config;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_H
|
||||
30
include/fennec/platform/interface/fwd.h
Normal file
30
include/fennec/platform/interface/fwd.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_INTERFACE_FORWARD_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_FORWARD_H
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class window;
|
||||
class display;
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_FORWARD_H
|
||||
74
include/fennec/platform/interface/platform.h
Normal file
74
include/fennec/platform/interface/platform.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_INTERFACE_PLATFORM_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_PLATFORM_H
|
||||
|
||||
#include <fennec/fproc/strings/string.h>
|
||||
#include <fennec/platform/interface/fwd.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class platform {
|
||||
public:
|
||||
using shared_object = struct shared_object;
|
||||
using function_pointer = void (*)(void);
|
||||
|
||||
struct shared_lib {
|
||||
shared_object* _lib;
|
||||
const cstring _name;
|
||||
};
|
||||
|
||||
enum class user {
|
||||
client,
|
||||
server
|
||||
};
|
||||
|
||||
struct config {
|
||||
user type;
|
||||
};
|
||||
|
||||
// Functions with default implementations
|
||||
|
||||
virtual string get_environment_variable(const cstring& var);
|
||||
|
||||
|
||||
|
||||
// Pure Virtual Functions
|
||||
|
||||
virtual display* get_display() = 0;
|
||||
|
||||
virtual shared_object* load_object(const cstring& file) = 0;
|
||||
virtual void unload_object(shared_object* obj) = 0;
|
||||
|
||||
virtual function_pointer find_symbol(shared_object* hndl, const cstring& name) = 0;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
platform(user t);
|
||||
virtual ~platform() = default;
|
||||
|
||||
private:
|
||||
config _config;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_PLATFORM_H
|
||||
137
include/fennec/platform/interface/window.h
Normal file
137
include/fennec/platform/interface/window.h
Normal file
@@ -0,0 +1,137 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_INTERFACE_WINDOW_H
|
||||
#define FENNEC_PLATFORM_INTERFACE_WINDOW_H
|
||||
|
||||
#include <fennec/fproc/strings/string.h>
|
||||
#include <fennec/platform/interface/fwd.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
///
|
||||
/// \brief interface for handling windows
|
||||
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
|
||||
class window {
|
||||
public:
|
||||
enum class fullscreen_mode {
|
||||
windowed = 0,
|
||||
borderless,
|
||||
fullscreen
|
||||
};
|
||||
|
||||
enum flags_ : uint32_t {
|
||||
flags_none = 0,
|
||||
flags_child = 0x1 << 0,
|
||||
flags_modal = 0x1 << 1,
|
||||
flags_grab_mouse = 0x1 << 2,
|
||||
flags_grab_keyboard = 0x1 << 3,
|
||||
flags_block_screensaver = 0x1 << 4,
|
||||
};
|
||||
|
||||
union bits {
|
||||
uint32_t depth;
|
||||
uint8_t r, g, b, a;
|
||||
};
|
||||
|
||||
struct config {
|
||||
string title;
|
||||
uint32_t flags;
|
||||
size_t width, height;
|
||||
fullscreen_mode fullscreen;
|
||||
bits bit_depth;
|
||||
};
|
||||
|
||||
virtual bool set_title(const cstring& title) = 0;
|
||||
virtual bool set_title(const string& title) = 0;
|
||||
|
||||
virtual bool set_width(size_t w) = 0;
|
||||
virtual bool set_height(size_t h) = 0;
|
||||
virtual bool set_size(size_t w, size_t h) = 0;
|
||||
|
||||
virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;
|
||||
|
||||
virtual bool set_resizable(bool e) = 0;
|
||||
|
||||
virtual bool grab_keyboard(bool e) = 0;
|
||||
virtual bool grab_mouse(bool e) = 0;
|
||||
virtual bool block_screensaver(bool e) = 0;
|
||||
|
||||
bool is_child() const {
|
||||
return _config.flags & flags_child;
|
||||
}
|
||||
|
||||
bool is_modal() const {
|
||||
return _config.flags & flags_modal;
|
||||
}
|
||||
|
||||
display* get_display() {
|
||||
return _display;
|
||||
}
|
||||
|
||||
const display* get_display() const {
|
||||
return _display;
|
||||
}
|
||||
|
||||
|
||||
const string& get_title() const {
|
||||
return _config.title;
|
||||
}
|
||||
|
||||
|
||||
size_t get_width() const {
|
||||
return _config.width;
|
||||
}
|
||||
|
||||
size_t get_height() const {
|
||||
return _config.height;
|
||||
}
|
||||
|
||||
|
||||
fullscreen_mode get_fullscreen_mode() const {
|
||||
return _config.fullscreen;
|
||||
}
|
||||
|
||||
|
||||
bool is_keyboard_grabbed() const {
|
||||
return _config.flags & flags_grab_keyboard;
|
||||
}
|
||||
|
||||
bool is_mouse_grabbed() const {
|
||||
return _config.flags & flags_grab_mouse;
|
||||
}
|
||||
|
||||
bool is_screensaver_blocked() const {
|
||||
return _config.flags & flags_block_screensaver;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~window() = default;
|
||||
window(display* display, window* parent, bool modal);
|
||||
|
||||
display* _display;
|
||||
window* _parent;
|
||||
config _config;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_INTERFACE_WINDOW_H
|
||||
59
include/fennec/platform/linux/platform.h
Normal file
59
include/fennec/platform/linux/platform.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_PLATFORM_H
|
||||
#define FENNEC_PLATFORM_LINUX_PLATFORM_H
|
||||
|
||||
#include <fennec/containers/set.h>
|
||||
#include <fennec/platform/interface/display.h>
|
||||
#include <fennec/platform/interface/platform.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
class linux_platform : public platform {
|
||||
public:
|
||||
enum display_ : int_t {
|
||||
display_none = -1,
|
||||
display_x11 = 0,
|
||||
display_wayland,
|
||||
};
|
||||
|
||||
linux_platform(user type);
|
||||
~linux_platform() override;
|
||||
|
||||
shared_object* load_object(const cstring& file) override;
|
||||
void unload_object(shared_object* obj) override;
|
||||
function_pointer find_symbol(shared_object* hndl, const cstring& name) override;
|
||||
|
||||
display* get_display() override;
|
||||
|
||||
|
||||
private:
|
||||
display* _display;
|
||||
int_t _display_driver;
|
||||
|
||||
void _runtime_client_checks();
|
||||
void _find_display_driver();
|
||||
|
||||
void _runtime_server_checks();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_PLATFORM_H
|
||||
51
include/fennec/platform/linux/wayland/display.h
Normal file
51
include/fennec/platform/linux/wayland/display.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
||||
|
||||
#include <fennec/fproc/strings/cstring.h>
|
||||
#include <fennec/platform/interface/display.h>
|
||||
|
||||
#include <fennec/platform/linux/platform.h>
|
||||
#include <fennec/platform/linux/wayland/lib/fwd.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
class wayland_display : public display {
|
||||
public:
|
||||
wayland_display(linux_platform* platform);
|
||||
wayland_display(linux_platform* platform, const cstring& drv);
|
||||
~wayland_display() override;
|
||||
|
||||
bool connected() const override;
|
||||
|
||||
private:
|
||||
struct wl_display* _handle;
|
||||
linux_platform* _platform;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_H
|
||||
37
include/fennec/platform/linux/wayland/lib/dyn.h
Normal file
37
include/fennec/platform/linux/wayland/lib/dyn.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
|
||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
|
||||
|
||||
#include <fennec/platform/linux/platform.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
bool load_symbols(linux_platform* platform);
|
||||
void unload_symbols(linux_platform* platform);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DYN_H
|
||||
24
include/fennec/platform/linux/wayland/lib/fwd.h
Normal file
24
include/fennec/platform/linux/wayland/lib/fwd.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
|
||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
|
||||
|
||||
struct wl_display;
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_FWD_H
|
||||
37
include/fennec/platform/linux/wayland/lib/sym.h
Normal file
37
include/fennec/platform/linux/wayland/lib/sym.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <fennec/platform/linux/wayland/lib/fwd.h>
|
||||
|
||||
#ifndef FENNEC_LIB
|
||||
#define FENNEC_LIB(...)
|
||||
#endif
|
||||
|
||||
#ifndef FENNEC_SYMBOL
|
||||
#define FENNEC_SYMBOL(...)
|
||||
#endif
|
||||
|
||||
FENNEC_LIB(WAYLAND);
|
||||
|
||||
FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char* name);
|
||||
FENNEC_SYMBOL(void, wl_display_disconnect, wl_display* name);
|
||||
|
||||
#undef FENNEC_LIB
|
||||
#undef FENNEC_SYMBOL
|
||||
|
||||
|
||||
27
include/fennec/platform/linux/wayland/lib/sym_def.h
Normal file
27
include/fennec/platform/linux/wayland/lib/sym_def.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H
|
||||
#define FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H
|
||||
|
||||
#define FENNEC_LIB(name) inline bool FENNEC_HAS_LIB_##name = false;
|
||||
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \
|
||||
inline sym_##fn fn = nullptr;
|
||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||
|
||||
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_SYM_DEF_H
|
||||
@@ -17,7 +17,7 @@
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
//#include <cpptrace/cpptrace.hpp>
|
||||
#include <cpptrace/cpptrace.hpp>
|
||||
|
||||
void __assert_callback(const char* expression, const char* file, int line, const char* function, const char* description)
|
||||
{
|
||||
@@ -28,5 +28,5 @@ void __assert_callback(const char* expression, const char* file, int line, const
|
||||
"At %s:%d in %s \n"
|
||||
"Description: %s \n",
|
||||
expression, file, line, function, description);
|
||||
// cpptrace::generate_trace(2).print();
|
||||
cpptrace::generate_trace(2).print();
|
||||
}
|
||||
@@ -22,12 +22,11 @@ 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)
|
||||
void __assert_impl(const char* expression, const char* file, int line, const char* function, const char* description, bool halt)
|
||||
{
|
||||
__assert_callback(expression, file, line, function, description);
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
if (halt) {
|
||||
::abort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
34
source/platform/interface/platform.cpp
Normal file
34
source/platform/interface/platform.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
#include <fennec/platform/interface/platform.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
string platform::get_environment_variable(const cstring& var) {
|
||||
const char* val = getenv(var);
|
||||
return string(val, strlen(val));
|
||||
}
|
||||
|
||||
platform::platform(user t) {
|
||||
_config.type = t;
|
||||
}
|
||||
|
||||
}
|
||||
36
source/platform/interface/window.cpp
Normal file
36
source/platform/interface/window.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <fennec/platform/interface/window.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
window::window(display* display, window* parent, bool modal)
|
||||
: _display(display)
|
||||
, _parent(parent)
|
||||
, _config() {
|
||||
|
||||
bool child = parent != nullptr;
|
||||
assert(!modal || child, "Attempted to create non-child modal window.");
|
||||
_config.flags |= child ? flags_child : flags_none;
|
||||
_config.flags |= modal ? flags_modal : flags_none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
98
source/platform/linux/platform.cpp
Normal file
98
source/platform/linux/platform.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <fennec/platform/linux/platform.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef FENNEC_LIB_WAYLAND
|
||||
#include <fennec/platform/linux/wayland/lib/dyn.h>
|
||||
#include <fennec/platform/linux/wayland/display.h>
|
||||
#endif
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
using namespace wayland;
|
||||
|
||||
linux_platform::linux_platform(user _type)
|
||||
: platform(_type)
|
||||
, _display_driver(display_none) {
|
||||
switch (_type) {
|
||||
case user::client: {
|
||||
_runtime_client_checks();
|
||||
return;
|
||||
}
|
||||
case user::server: {
|
||||
_runtime_server_checks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
linux_platform::~linux_platform() {
|
||||
|
||||
}
|
||||
|
||||
shared_object* linux_platform::load_object(const cstring& file) {
|
||||
void* handle = dlopen(file, RTLD_NOW | RTLD_LOCAL);
|
||||
const char* load_error = dlerror();
|
||||
assert(handle != nullptr, load_error);
|
||||
return static_cast<shared_object*>(handle);
|
||||
}
|
||||
|
||||
void linux_platform::unload_object(shared_object* obj) {
|
||||
if (obj) {
|
||||
dlclose(obj);
|
||||
}
|
||||
}
|
||||
|
||||
platform::function_pointer linux_platform::find_symbol(shared_object* hndl, const cstring& name) {
|
||||
string _name = name;
|
||||
void* symbol = dlsym(hndl, _name);
|
||||
if (symbol == nullptr) {
|
||||
_name = '_' + _name;
|
||||
symbol = dlsym(hndl, _name);
|
||||
}
|
||||
return (function_pointer)symbol;
|
||||
}
|
||||
|
||||
display* linux_platform::get_display() {
|
||||
return _display;
|
||||
}
|
||||
|
||||
void linux_platform::_runtime_client_checks() {
|
||||
#ifdef FENNEC_LIB_WAYLAND
|
||||
if (wayland::load_symbols(this)) {
|
||||
_display_driver = display_wayland;
|
||||
_display = new wayland_display(this);
|
||||
wayland::unload_symbols(this); // Doesn't actually unload symbols, just resets ref counter to only consider
|
||||
// the created display
|
||||
}
|
||||
#endif
|
||||
assertf(_display != nullptr, "failed to find suitable display driver");
|
||||
}
|
||||
|
||||
void linux_platform::_find_display_driver() {
|
||||
|
||||
}
|
||||
|
||||
void linux_platform::_runtime_server_checks() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
58
source/platform/linux/wayland/display.cpp
Normal file
58
source/platform/linux/wayland/display.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <fennec/platform/linux/wayland/display.h>
|
||||
#include <fennec/platform/linux/wayland/lib/sym_def.h>
|
||||
#include <fennec/platform/linux/wayland/lib/dyn.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
wayland_display::wayland_display(linux_platform* platform)
|
||||
: display()
|
||||
, _handle()
|
||||
, _platform(platform) {
|
||||
load_symbols(_platform);
|
||||
_handle = wl_display_connect(nullptr);
|
||||
}
|
||||
|
||||
wayland_display::wayland_display(linux_platform* platform, const cstring& drv)
|
||||
: display()
|
||||
, _handle()
|
||||
, _platform(platform) {
|
||||
load_symbols(_platform);
|
||||
_handle = wl_display_connect(nullptr);
|
||||
}
|
||||
|
||||
wayland_display::~wayland_display() {
|
||||
wl_display_disconnect(_handle);
|
||||
unload_symbols(_platform);
|
||||
_handle = nullptr;
|
||||
_platform = nullptr;
|
||||
}
|
||||
|
||||
bool wayland_display::connected() const {
|
||||
return _handle != nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
69
source/platform/linux/wayland/lib/dyn.cpp
Normal file
69
source/platform/linux/wayland/lib/dyn.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// =====================================================================================================================
|
||||
// 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/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#include <fennec/platform/linux/wayland/lib/sym_def.h>
|
||||
#include <fennec/platform/linux/wayland/lib/dyn.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace wayland
|
||||
{
|
||||
|
||||
using shared_lib = platform::shared_lib;
|
||||
|
||||
static int _load_count = 0;
|
||||
|
||||
// Create private variables
|
||||
#define FENNEC_LIB(lib) static shared_lib _FENNEC_LIB_##lib = { nullptr, FENNEC_LIB_##lib };
|
||||
#define FENNEC_SYMBOL(...)
|
||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||
|
||||
bool load_symbols(linux_platform* platform) {
|
||||
if (_load_count++ != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define FENNEC_LIB(lib) _FENNEC_LIB_##lib._lib = platform->load_object(_FENNEC_LIB_##lib._name); \
|
||||
FENNEC_HAS_LIB_##lib = _FENNEC_LIB_##lib._lib != nullptr; \
|
||||
if(not FENNEC_HAS_LIB_##lib) { \
|
||||
unload_symbols(platform); \
|
||||
return false; \
|
||||
} \
|
||||
shared_lib& current_lib = _FENNEC_LIB_##lib;
|
||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib._lib, #fn));
|
||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void unload_symbols(linux_platform* platform) {
|
||||
if (--_load_count != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib._lib); \
|
||||
_FENNEC_LIB_##lib._lib = nullptr;
|
||||
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr;
|
||||
#include <fennec/platform/linux/wayland/lib/sym.h>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,12 @@ add_executable(fennec-test main.cpp
|
||||
printing.h
|
||||
tests/math/test_ext.h
|
||||
tests/math/ext/test_quaternion.h
|
||||
tests/platform/linux/test_wayland.h
|
||||
tests/platform/test_linux.h
|
||||
tests/test_platform.h
|
||||
tests/lang/test_hashing.h
|
||||
tests/containers/test_array.h
|
||||
tests/containers/test_set.h
|
||||
)
|
||||
|
||||
target_compile_definitions(fennec-test PUBLIC FENNEC_TEST_CWD="${CMAKE_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME}"
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include "tests/test_memory.h"
|
||||
|
||||
#include "test.h"
|
||||
#include "tests/test_containers.h"
|
||||
#include "tests/test_fproc.h"
|
||||
#include "tests/test_platform.h"
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
@@ -37,6 +39,11 @@ int main(int, char **)
|
||||
fennec::test::fennec_test_lang();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_header("containers library");
|
||||
fennec_test_spacer(2);
|
||||
fennec::test::fennec_test_containers();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_header("math library");
|
||||
fennec_test_spacer(2);
|
||||
fennec::test::fennec_test_math();
|
||||
@@ -47,5 +54,10 @@ int main(int, char **)
|
||||
fennec::test::fennec_test_fproc();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_header("platform library");
|
||||
fennec_test_spacer(2);
|
||||
fennec::test::fennec_test_platform();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ inline void __fennec_test_run(const std::string& expression, const ResultT& resu
|
||||
std::cout << std::endl;
|
||||
|
||||
// Assert to halt and get some debug info
|
||||
assert(passed, "Test Failed");
|
||||
assertf(passed, "Test Failed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
49
test/tests/containers/test_array.h
Normal file
49
test/tests/containers/test_array.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_CONTAINERS_ARRAY_H
|
||||
#define FENNEC_TEST_CONTAINERS_ARRAY_H
|
||||
|
||||
#include "../../test.h"
|
||||
|
||||
#include <fennec/containers/array.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_containers_array() {
|
||||
|
||||
const char string[] = "Hello World!";
|
||||
array<char, sizeof(string)> arr1;
|
||||
array<char, sizeof(string)> arr2;
|
||||
strcpy(&arr1[0], string);
|
||||
strcpy(&arr2[0], string);
|
||||
|
||||
fennec_test_run(strcmp(&arr1[0], string), 0);
|
||||
fennec_test_run(strcmp(&arr2[0], string), 0);
|
||||
fennec_test_run(arr1 == arr2, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_CONTAINERS_ARRAY_H
|
||||
55
test/tests/containers/test_dynarray.h
Normal file
55
test/tests/containers/test_dynarray.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_CONTAINERS_DYNARRAY_H
|
||||
#define FENNEC_TEST_CONTAINERS_DYNARRAY_H
|
||||
|
||||
#include "../../test.h"
|
||||
|
||||
#include <fennec/containers/dynarray.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_containers_dynarray() {
|
||||
|
||||
dynarray<int> test1;
|
||||
dynarray<int> test2;
|
||||
|
||||
int n = 10000;
|
||||
test1.resize(n); test2.resize(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
test1.push_back(i);
|
||||
test2.push_back(n - i - 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
assertf(test1[i] == test2[n - i - 1], "Failed dynarray::push_back");
|
||||
}
|
||||
|
||||
std::cout << "passed" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_CONTAINERS_DYNARRAY_H
|
||||
124
test/tests/containers/test_optional.h
Normal file
124
test/tests/containers/test_optional.h
Normal file
@@ -0,0 +1,124 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_CONTAINERS_OPTIONAL_H
|
||||
#define FENNEC_TEST_CONTAINERS_OPTIONAL_H
|
||||
|
||||
#include "../../test.h"
|
||||
|
||||
#include <fennec/containers/optional.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
enum opt_test_ : uint8_t {
|
||||
opt_test_none = 0x1 << 0,
|
||||
opt_test_default_constructor = 0x1 << 1,
|
||||
opt_test_destructor = 0x1 << 2,
|
||||
opt_test_copy_constructor = 0x1 << 3,
|
||||
opt_test_move_constructor = 0x1 << 4,
|
||||
opt_test_copy_assignment = 0x1 << 5,
|
||||
opt_test_move_assignment = 0x1 << 6,
|
||||
};
|
||||
|
||||
struct optional_helper {
|
||||
|
||||
inline static uint8_t test = opt_test_none;
|
||||
|
||||
optional_helper() : i(0) {
|
||||
fennec_test_run(bool(test & opt_test_default_constructor), true);
|
||||
}
|
||||
|
||||
~optional_helper() {
|
||||
fennec_test_run(bool(test & opt_test_destructor), true);
|
||||
}
|
||||
|
||||
optional_helper(const optional_helper&) : i(0) {
|
||||
fennec_test_run(bool(test & opt_test_copy_constructor), true);
|
||||
}
|
||||
|
||||
optional_helper(optional_helper&&) noexcept : i(0) {
|
||||
fennec_test_run(bool(test & opt_test_move_constructor), true);
|
||||
}
|
||||
|
||||
optional_helper& operator=(const optional_helper&) {
|
||||
fennec_test_run(bool(test & opt_test_copy_assignment), true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
optional_helper& operator=(optional_helper&&) noexcept {
|
||||
fennec_test_run(bool(test & opt_test_move_assignment), true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int i;
|
||||
};
|
||||
|
||||
inline void fennec_test_containers_optional() {
|
||||
static_assert(
|
||||
is_default_constructible_v<optional_helper>
|
||||
and is_copy_constructible_v<optional_helper>
|
||||
and is_move_constructible_v<optional_helper>
|
||||
and is_copy_assignable_v<optional_helper>
|
||||
and is_move_assignable_v<optional_helper>
|
||||
);
|
||||
|
||||
optional<optional_helper> opt = optional<optional_helper>();
|
||||
|
||||
optional_helper::test = opt_test_default_constructor;
|
||||
opt.emplace();
|
||||
|
||||
optional_helper::test = opt_test_destructor;
|
||||
opt.reset();
|
||||
|
||||
optional_helper::test = opt_test_default_constructor | opt_test_copy_constructor | opt_test_destructor;
|
||||
opt = copy(optional_helper());
|
||||
|
||||
optional_helper::test = opt_test_destructor;
|
||||
opt.reset();
|
||||
|
||||
optional_helper::test = opt_test_default_constructor | opt_test_move_constructor | opt_test_destructor;
|
||||
opt = optional_helper();
|
||||
|
||||
optional_helper::test = opt_test_destructor;
|
||||
opt.reset();
|
||||
|
||||
optional_helper::test = opt_test_default_constructor;
|
||||
opt.emplace();
|
||||
|
||||
optional_helper::test = opt_test_default_constructor | opt_test_copy_assignment | opt_test_destructor;
|
||||
opt = copy(optional_helper());
|
||||
|
||||
optional_helper::test = opt_test_default_constructor | opt_test_move_assignment | opt_test_destructor;
|
||||
opt = optional_helper();
|
||||
|
||||
optional_helper::test = opt_test_destructor;
|
||||
opt.reset();
|
||||
|
||||
std::cout << opt << std::endl;
|
||||
std::cout << "passed" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_CONTAINERS_OPTIONAL_H
|
||||
58
test/tests/containers/test_set.h
Normal file
58
test/tests/containers/test_set.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_CONTAINERS_SET_H
|
||||
#define FENNEC_TEST_CONTAINERS_SET_H
|
||||
|
||||
#include "../../test.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <unordered_set>
|
||||
#include <fennec/containers/set.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_containers_set() {
|
||||
|
||||
using type_t = decltype(rand());
|
||||
std::unordered_set<type_t> ref;
|
||||
set<type_t> test;
|
||||
|
||||
srand(0);
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
type_t v = rand();
|
||||
ref.insert(v);
|
||||
test.insert(v);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
assertf(ref.contains(i) == test.contains(i), "set test failed");
|
||||
}
|
||||
|
||||
std::cout << "passed" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_CONTAINERS_SET_H
|
||||
@@ -47,8 +47,6 @@ inline void fennec_test_fproc_strings_cstring()
|
||||
fennec_test_run(str.rfind('o'), static_cast<size_t>(7));
|
||||
fennec_test_run(str.rfind("World"), static_cast<size_t>(6));
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -88,8 +88,6 @@ inline void fennec_test_fproc_io() {
|
||||
fennec_test_run(file::cout().write("Hello World!"), sizeof("Hello World!"));
|
||||
fennec_test_run(file::cerr().write("Hello World!"), sizeof("Hello World!"));
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ inline void fennec_test_fproc_strings()
|
||||
fennec_test_fproc_strings_cstring();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace fennec
|
||||
namespace test
|
||||
{
|
||||
|
||||
void fennec_test_lang_bits()
|
||||
inline void fennec_test_lang_bits()
|
||||
{
|
||||
int a = 0x48ef13ad;
|
||||
int b = 0x23e5ab9c;
|
||||
|
||||
57
test/tests/lang/test_hashing.h
Normal file
57
test/tests/lang/test_hashing.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_LANG_HASHING_H
|
||||
#define FENNEC_TEST_LANG_HASHING_H
|
||||
|
||||
#include <fennec/lang/hashing.h>
|
||||
#include "../../test.h"
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_lang_hashing() {
|
||||
|
||||
size_t num = 61;
|
||||
float_t numf = bit_cast<float>((uint32_t)num);
|
||||
double_t numd = bit_cast<double>(num);
|
||||
size_t exp = hash<size_t>()(num);
|
||||
|
||||
fennec_test_run(hash<int8_t>()(num), exp);
|
||||
fennec_test_run(hash<uint8_t>()(num), exp);
|
||||
fennec_test_run(hash<int16_t>()(num), exp);
|
||||
fennec_test_run(hash<uint16_t>()(num), exp);
|
||||
fennec_test_run(hash<int32_t>()(num), exp);
|
||||
fennec_test_run(hash<uint32_t>()(num), exp);
|
||||
fennec_test_run(hash<int64_t>()(num), exp);
|
||||
fennec_test_run(hash<uint64_t>()(num), exp);
|
||||
|
||||
fennec_test_spacer(1);
|
||||
|
||||
fennec_test_run(hash<float_t>()(numf), exp);
|
||||
fennec_test_run(hash<double_t>()(numd), exp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_LANG_HASHING_H
|
||||
@@ -32,6 +32,8 @@ inline void test_sequences()
|
||||
static_assert(fennec::is_same_v<make_index_sequence_t<2>, index_sequence<0, 1>>);
|
||||
static_assert(fennec::is_same_v<make_index_sequence_t<3>, index_sequence<0, 1, 2>>);
|
||||
static_assert(fennec::is_same_v<make_index_sequence_t<4>, index_sequence<0, 1, 2, 3>>);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ inline void fennec_test_math_quaternion() {
|
||||
fennec_test_run(quat(), quat(1, 0, 0, 0));
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -208,9 +208,6 @@ inline void fennec_test_math_common()
|
||||
|
||||
fennec_test_run(mix(0.0f, 1.0f, false), 0.0f);
|
||||
fennec_test_run(mix(0.0f, 1.0f, true), 1.0f);
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,9 +75,6 @@ inline void fennec_test_math_exponential()
|
||||
fennec_test_run(fennec::inversesqrt(1.0f), 1.0f / 1.0f);
|
||||
fennec_test_run(fennec::inversesqrt(4.0f), 1.0f / 2.0f);
|
||||
fennec_test_run(fennec::inversesqrt(9.0f), 1.0f / 3.0f);
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ inline void fennec_test_math_ext() {
|
||||
fennec_test_math_quaternion();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,9 +77,6 @@ inline void fennec_test_math_geometric()
|
||||
|
||||
fennec_test_run(fennec::reflect(vec2(1, -1), vec2(0, 1)), vec2(1, 1));
|
||||
fennec_test_run(fennec::refract(vec2(1, -1), vec2(0, 1), 1/1.33f), vec2(0.7518797, -1));
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -320,8 +320,6 @@ inline void fennec_test_math_matrix()
|
||||
fennec_test_run(fennec::inverse(mat2(1, 2, 3, 4)), mat2(-2, 1, 1.5, -0.5));
|
||||
fennec_test_run(fennec::inverse(mat3(1, 2, 3, 0, 1, 4, 5, 6, 0)), mat3(-24, 18, 5, 20, -15, -4, -5, 4, 1));
|
||||
fennec_test_run(fennec::inverse(mat4(2, 1, -3, 4, -1, 0, 2, 5, 3, 2, 1, 0, 4, -2, 3, 1)), (1.0f / 414.0f) * mat4(36, -39, 33, 51, -18, 31, 133, -83, -72, 55, 49, 13, 36, 53, -13, 5));
|
||||
|
||||
fennec_test_spacer(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ inline void fennec_test_math_relational()
|
||||
|
||||
fennec_test_run(not(bvec3(true, false, true)), bvec3(false, true, false));
|
||||
fennec_test_run(fennec::all(bvec3(true, true, true)), true);
|
||||
|
||||
fennec_test_spacer(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -112,11 +112,6 @@ inline void fennec_test_math_trigonometric()
|
||||
fennec_test_run(fennec::asinh((fennec::e<float>() - fennec::one_over_e<float>()) / 2.0f), 1.0f);
|
||||
fennec_test_run(fennec::acosh((fennec::e<float>() + fennec::one_over_e<float>()) / 2.0f), 1.0f);
|
||||
fennec_test_run(fennec::atanh(((fennec::e_raised_two<float>() - 1) / (fennec::e_raised_two<float>() + 1))), 1.0f);
|
||||
|
||||
|
||||
fennec_test_spacer(2);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -594,8 +594,6 @@ inline void fennec_test_math_vector()
|
||||
fennec_test_run(([]() -> ivec2 { ivec2 v(0x2A1E, 0x7BF3); return v >>= ivec2(4, 8); }()), ivec2(0x2A1, 0x7B));
|
||||
fennec_test_run(([]() -> ivec3 { ivec3 v(0x2A1E, 0x7BF3, 0x3927); return v >>= ivec3(4, 8, 12); }()), ivec3(0x2A1, 0x7B, 0x3));
|
||||
fennec_test_run(([]() -> ivec4 { ivec4 v(0x2A1E, 0x7BF3, 0x3927, 0x237C); return v >>= ivec4(4, 8, 12, 16); }()), ivec4(0x2A1, 0x7B, 0x3, 0x0));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
43
test/tests/platform/linux/test_wayland.h
Normal file
43
test/tests/platform/linux/test_wayland.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_PLATFORM_LINUX_WAYLAND_H
|
||||
#define FENNEC_TEST_PLATFORM_LINUX_WAYLAND_H
|
||||
|
||||
#include "../../../test.h"
|
||||
#include <fennec/platform/linux/wayland/display.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
using namespace wayland;
|
||||
|
||||
inline void fennec_test_platform_linux_wayland(linux_platform& platform) {
|
||||
|
||||
wayland_display* display = static_cast<wayland_display*>(platform.get_display());
|
||||
fennec_test_run(display != nullptr, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_PLATFORM_LINUX_WAYLAND_H
|
||||
51
test/tests/platform/test_linux.h
Normal file
51
test/tests/platform/test_linux.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_PLATFORM_LINUX_H
|
||||
#define FENNEC_TEST_PLATFORM_LINUX_H
|
||||
#include "../../test.h"
|
||||
|
||||
#ifdef FENNEC_LIB_WAYLAND
|
||||
#include "linux/test_wayland.h"
|
||||
#endif
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_platform_linux() {
|
||||
|
||||
linux_platform platform(platform::user::client);
|
||||
|
||||
#ifdef FENNEC_LIB_WAYLAND
|
||||
fennec_test_section("wayland tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_platform_linux_wayland(platform);
|
||||
fennec_test_spacer(3);
|
||||
#endif
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_PLATFORM_LINUX_H
|
||||
61
test/tests/test_containers.h
Normal file
61
test/tests/test_containers.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// =====================================================================================================================
|
||||
// fennec-test, a program to execute unit tests for fennec
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_CONTAINERS_H
|
||||
#define FENNEC_TEST_CONTAINERS_H
|
||||
|
||||
#include "containers/test_array.h"
|
||||
#include "containers/test_dynarray.h"
|
||||
#include "containers/test_optional.h"
|
||||
#include "containers/test_set.h"
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_containers()
|
||||
{
|
||||
fennec_test_subheader("optional tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_containers_optional();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_subheader("array tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_containers_array();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_subheader("dynarray tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_containers_dynarray();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_subheader("set tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_containers_set();
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_CONTAINERS_H
|
||||
@@ -40,6 +40,8 @@ inline void fennec_test_fproc() {
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_fproc_io();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "lang/test_bits.h"
|
||||
#include "lang/test_conditional_types.h"
|
||||
#include "lang/test_hashing.h"
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
@@ -34,6 +35,12 @@ inline void fennec_test_lang()
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_lang_bits();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
fennec_test_subheader("hashing tests");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_lang_hashing();
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ inline void fennec_test_math()
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_math_ext();
|
||||
fennec_test_spacer(3);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,4 +19,6 @@
|
||||
#ifndef FENNEC_TEST_MEMORY_H
|
||||
#define FENNEC_TEST_MEMORY_H
|
||||
|
||||
// TODO
|
||||
|
||||
#endif // FENNEC_TEST_MEMORY_H
|
||||
|
||||
46
test/tests/test_platform.h
Normal file
46
test/tests/test_platform.h
Normal file
@@ -0,0 +1,46 @@
|
||||
// =====================================================================================================================
|
||||
// fennec, a free and open source game engine
|
||||
// Copyright © 2025 Medusa Slockbower
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_TEST_PLATFORM_H
|
||||
#define FENNEC_TEST_PLATFORM_H
|
||||
#include "../test.h"
|
||||
|
||||
#if FENNEC_PLATFORM_LINUX
|
||||
#include "./platform/test_linux.h"
|
||||
#endif
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
inline void fennec_test_platform() {
|
||||
#if FENNEC_PLATFORM_LINUX
|
||||
fennec_test_subheader("linux");
|
||||
fennec_test_spacer(2);
|
||||
fennec_test_platform_linux();
|
||||
fennec_test_spacer(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_TEST_PLATFORM_H
|
||||
Reference in New Issue
Block a user