Compare commits

...

2 Commits

Author SHA1 Message Date
cbcd699ab0 - Decided to remove boost due to extensive dependencies
- Huge refactor on Wayland loading to support retrieval of Protocol headers
 - Setup EGL to create surfaces for Wayland windows
2025-08-22 02:15:57 -04:00
ff27caab4f - Fixed some variable naming with graph and it's PrettyPrinter
- Added boost-atomic and boost-thread as dependencies for concurrency support
2025-08-21 06:44:22 -04:00
50 changed files with 10644 additions and 2528 deletions

View File

@@ -20,14 +20,29 @@ cmake_minimum_required(VERSION 3.30)
project(fennec) project(fennec)
# External dependencies should be loaded here # External dependencies should be loaded here
# CppTrace is a dependency of the project, added as a git submodule
add_subdirectory(external/cpptrace) add_subdirectory(external/cpptrace)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(FENNEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(fennec-dependencies
COMMAND ${CMAKE_COMMAND} -E echo "Running dependencies."
COMMENT "Running dependencies."
)
macro(fennec_add_sources)
list(APPEND FENNEC_EXTRA_SOURCES ${ARGN})
endmacro()
macro(fennec_add_definitions)
list(APPEND FENNEC_COMPILE_DEFINITIONS ${ARGN})
endmacro()
macro(fennec_add_link_libraries)
list(APPEND FENNEC_LINK_LIBRARIES ${ARGN})
endmacro()
# include scripts # include scripts
include("${FENNEC_SOURCE_DIR}/cmake/version.cmake") include("${FENNEC_SOURCE_DIR}/cmake/version.cmake")
include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake") include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake")
@@ -85,6 +100,7 @@ add_library(fennec STATIC
include/fennec/containers/set.h include/fennec/containers/set.h
include/fennec/containers/traversal.h include/fennec/containers/traversal.h
include/fennec/containers/tuple.h include/fennec/containers/tuple.h
include/fennec/containers/variant.h
include/fennec/containers/detail/_tuple.h include/fennec/containers/detail/_tuple.h
@@ -138,11 +154,6 @@ add_library(fennec STATIC
include/fennec/memory/detail/_ptr_traits.h include/fennec/memory/detail/_ptr_traits.h
# CONCURRENCY ==========================================================================================================
include/fennec/concurrency/thread.h
include/fennec/concurrency/mutex.h
include/fennec/concurrency/atomic.h
# DEBUG ================================================================================================================ # DEBUG ================================================================================================================
source/debug/assert_impl.cpp source/debug/assert_impl.cpp
@@ -203,15 +214,15 @@ add_library(fennec STATIC
include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp include/fennec/platform/interface/platform.h source/platform/interface/platform.cpp
include/fennec/platform/interface/display.h source/platform/interface/display.cpp include/fennec/platform/interface/display.h source/platform/interface/display.cpp
include/fennec/platform/interface/gfxcontext.h include/fennec/platform/interface/gfxcontext.h
include/fennec/platform/interface/gfxsurface.h
# EXTRA SOURCES ======================================================================================================== # EXTRA SOURCES ========================================================================================================
${FENNEC_EXTRA_SOURCES} ${FENNEC_EXTRA_SOURCES}
include/fennec/containers/variant.h
) )
add_dependencies(fennec metaprogramming) add_dependencies(fennec metaprogramming fennec-dependencies)
target_compile_definitions(fennec PUBLIC target_compile_definitions(fennec PUBLIC
${FENNEC_COMPILE_DEFINITIONS} ${FENNEC_COMPILE_DEFINITIONS}
@@ -223,8 +234,9 @@ target_link_options(fennec PRIVATE ${FENNEC_PRIVATE_LINK_OPTIONS}) # Do not comp
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated # This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
target_link_libraries(fennec PRIVATE target_link_libraries(fennec PRIVATE
cpptrace::cpptrace
${FENNEC_LINK_LIBRARIES} ${FENNEC_LINK_LIBRARIES}
cpptrace::cpptrace
) )

View File

@@ -22,4 +22,4 @@ add_compile_options("-mxsave" "-Wall" "-Wextra" "-pedantic" "-Werror")
set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates") set(FENNEC_PRIVATE_LINK_OPTIONS "-nostdlib" "-fno-exceptions" "-fno-rtti" "-fdiagnostics-all-candidates")
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]]) list(APPEND FENNEC_COMPILE_DEFINITIONS _GLIBCXX_INCLUDE_NEXT_C_HEADERS FENNEC_COMPILER_GCC=1 FENNEC_NO_INLINE=[[gnu::noinline]])

View File

@@ -23,13 +23,13 @@ macro(fennec_check_platform)
include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake") include("${FENNEC_SOURCE_DIR}/cmake/unix.cmake")
# compile definitions # compile definitions
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_PLATFORM_NAME="Linux" FENNEC_PLATFORM_NAME="Linux"
FENNEC_PLATFORM_LINUX=1 FENNEC_PLATFORM_LINUX=1
) )
# extra source files # extra source files
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp include/fennec/platform/linux/platform.h source/platform/linux/platform.cpp
) )

View File

@@ -27,8 +27,8 @@ endif()
if(TARGET OpenGL::GL AND TARGET GLEW::GLEW) if(TARGET OpenGL::GL AND TARGET GLEW::GLEW)
message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}") message(STATUS "Found OpenGL: ${OPENGL_gl_LIBRARY}")
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL GLEW::GLEW) fennec_add_link_libraries(OpenGL::GL GLEW::GLEW)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1) fennec_add_definitions(FENNEC_GRAPHICS_OPENGL=1)
else() else()
message(FATAL_ERROR "No Suitable OpenGL implementation found.") message(FATAL_ERROR "No Suitable OpenGL implementation found.")
endif() endif()
@@ -39,15 +39,19 @@ if(FENNEC_GRAPHICS_WANT_EGL)
endif() endif()
message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}") message(STATUS "Found EGL: ${OPENGL_egl_LIBRARY}")
list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL)
list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1) fennec_add_link_libraries(OpenGL::EGL)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_definitions(FENNEC_GRAPHICS_EGL=1)
fennec_add_sources(
include/fennec/platform/opengl/lib/fwd.h include/fennec/platform/opengl/lib/fwd.h
include/fennec/platform/opengl/lib/enum.h include/fennec/platform/opengl/lib/enum.h
include/fennec/platform/opengl/lib/buffer.h include/fennec/platform/opengl/lib/buffer.h
include/fennec/platform/opengl/lib/texture.h include/fennec/platform/opengl/lib/texture.h
include/fennec/platform/opengl/lib/vertex_array.h include/fennec/platform/opengl/lib/vertex_array.h
include/fennec/platform/opengl/egl/fwd.h
include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp
include/fennec/platform/opengl/egl/surface.h source/platform/opengl/egl/surface.cpp
) )
endif() endif()

View File

@@ -19,11 +19,11 @@
# generic unix functionality # generic unix functionality
# compile definitions # compile definitions
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_PLATFORM_UNIX=1 FENNEC_PLATFORM_UNIX=1
) )
# extra source files # extra source files
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp include/fennec/platform/unix/platform.h source/platform/unix/platform.cpp
) )

View File

@@ -19,6 +19,20 @@
# https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a # https://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a
# this script finds libwayland and dependencies # this script finds libwayland and dependencies
# some of this code is based on SDL3's use of wayland-scanner
macro(fennec_wayland_get_header _SCANNER _XML _FILE)
set(_WAYLAND_PROT_H_CODE "${WAYLAND_HEADERS_DIR}/${_FILE}-client-protocols.h")
add_custom_command(
TARGET fennec-dependencies PRE_BUILD
COMMAND ${_SCANNER}
ARGS client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}"
)
fennec_add_sources(${_WAYLAND_PROT_H_CODE})
endmacro()
macro(fennec_check_wayland) macro(fennec_check_wayland)
set(WAYLAND_CLIENT_FOUND 0) set(WAYLAND_CLIENT_FOUND 0)
@@ -30,6 +44,7 @@ macro(fennec_check_wayland)
WAYLAND_CLIENT_LIBRARY WAYLAND_CLIENT_LIBRARY
NAMES wayland-client libwayland-client NAMES wayland-client libwayland-client
) )
find_program(WAYLAND_SCANNER NAMES wayland-scanner)
# EGL is required # EGL is required
find_path( find_path(
@@ -41,13 +56,29 @@ macro(fennec_check_wayland)
NAMES wayland-egl libwayland-egl NAMES wayland-egl libwayland-egl
) )
if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY) if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY AND WAYLAND_SCANNER)
AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY)) AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_LIBRARY))
message(STATUS "Found Wayland: ${WAYLAND_CLIENT_LIBRARY}") message(STATUS "Found Wayland: ${WAYLAND_CLIENT_LIBRARY}")
set(WAYLAND_PROTOCOLS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/protocols)
set(WAYLAND_HEADERS_DIR ${FENNEC_SOURCE_DIR}/include/fennec/platform/linux/wayland/lib/headers)
# Search for base protocol xml
find_file(WAYLAND_PROTOCOL NAMES wayland.xml PATHS /usr/share/wayland /usr/share/wayland-protocols)
file(COPY ${WAYLAND_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR})
# include sub-dependencies
include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake") include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake")
fennec_check_xkb() fennec_check_xkb()
# generate protocols, based on SDL3
file(GLOB WAYLAND_PROTOCOLS_XML RELATIVE "${WAYLAND_PROTOCOLS_DIR}" "${WAYLAND_PROTOCOLS_DIR}/*.xml")
foreach(_XML IN LISTS WAYLAND_PROTOCOLS_XML)
get_filename_component(_FILE ${_XML} NAME_WLE)
fennec_wayland_get_header("${WAYLAND_SCANNER}" "${WAYLAND_PROTOCOLS_DIR}/${_XML}" "${_FILE}")
endforeach()
# Add sources and libraries
get_filename_component( get_filename_component(
WAYLAND_CLIENT_LIBRARY WAYLAND_CLIENT_LIBRARY
${WAYLAND_CLIENT_LIBRARY} ${WAYLAND_CLIENT_LIBRARY}
@@ -63,19 +94,19 @@ macro(fennec_check_wayland)
set(WAYLAND_EGL_FOUND 1) set(WAYLAND_EGL_FOUND 1)
set(FENNEC_GRAPHICS_WANT_EGL 1) set(FENNEC_GRAPHICS_WANT_EGL 1)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
# Dynamic Library Files # Dynamic Library Files
include/fennec/platform/linux/wayland/lib/fwd.h include/fennec/platform/linux/wayland/lib/fwd.h
include/fennec/platform/linux/wayland/lib/sym.h include/fennec/platform/linux/wayland/lib/sym.h
include/fennec/platform/linux/wayland/lib/wayland-client.h include/fennec/platform/linux/wayland/lib/wayland.h
include/fennec/platform/linux/wayland/lib/wayland-util.h
include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp
# Fennec Files # Fennec Files
include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp include/fennec/platform/linux/wayland/display.h source/platform/linux/wayland/display.cpp
include/fennec/platform/linux/wayland/window.h source/platform/linux/wayland/window.cpp
) )
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_HAS_WAYLAND=1 FENNEC_HAS_WAYLAND=1
FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}" FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}"
FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}" FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}"

View File

@@ -41,7 +41,7 @@ macro(fennec_check_xkb)
set(XKB_FOUND 1) set(XKB_FOUND 1)
list(APPEND FENNEC_EXTRA_SOURCES fennec_add_sources(
# Dynamic Library Files # Dynamic Library Files
include/fennec/platform/linux/xkb/lib/fwd.h include/fennec/platform/linux/xkb/lib/fwd.h
include/fennec/platform/linux/xkb/lib/sym.h include/fennec/platform/linux/xkb/lib/sym.h
@@ -51,7 +51,7 @@ macro(fennec_check_xkb)
# Fennec files # Fennec files
) )
list(APPEND FENNEC_COMPILE_DEFINITIONS fennec_add_definitions(
FENNEC_HAS_XKB=1 FENNEC_HAS_XKB=1
FENNEC_LIB_XKB="${XKB_LIBRARY}" FENNEC_LIB_XKB="${XKB_LIBRARY}"
) )

View File

@@ -396,10 +396,10 @@ class GraphPrinter:
class Iterator: class Iterator:
def __init__(self, val): def __init__(self, val):
self.node_pool = val['_node_pool']['_table']['_alloc']['_data'] self.node_pool = val['_vertex_pool']['_table']['_alloc']['_data']
self.max_nodes = val['_node_pool']['_table']['_alloc']['_capacity'] self.max_nodes = val['_vertex_pool']['_table']['_alloc']['_capacity']
self.conn_map = val['_conn_map']['_alloc']['_data'] self.conn_map = val['_edge_map']['_alloc']['_data']
self.max_conn = val['_conn_map']['_size'] self.max_conn = val['_edge_map']['_size']
self.index = 0 self.index = 0
def __iter__(self): def __iter__(self):
@@ -447,7 +447,7 @@ class GraphPrinter:
def __init__(self, val): def __init__(self, val):
self.val = val self.val = val
self.size = val['_node_pool']['_size'] self.size = val['_vertex_pool']['_size']
def to_string(self): def to_string(self):
if self.size == 0: if self.size == 0:

View File

@@ -1,22 +0,0 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_CONCURRENCY_THREAD_H
#define FENNEC_CONCURRENCY_THREAD_H
#endif // FENNEC_CONCURRENCY_THREAD_H

View File

@@ -149,7 +149,7 @@ public:
/// ///
/// \returns The number of edges in the graph /// \returns The number of edges in the graph
constexpr size_t num_edges() const { constexpr size_t num_edges() const {
return _conn_pool.size(); return _edge_pool.size();
} }
/// ///
@@ -170,7 +170,7 @@ public:
/// \param b The second vertex /// \param b The second vertex
/// \returns `true` if the edge exists, `false` otherwise /// \returns `true` if the edge exists, `false` otherwise
constexpr bool exists(size_t a, size_t b) const { constexpr bool exists(size_t a, size_t b) const {
return _conn_map[a][b] != nullptr; return _edge_map[a][b] != nullptr;
} }
/// ///
@@ -189,8 +189,8 @@ public:
/// \param b The second vertex /// \param b The second vertex
/// \returns `true` if both edges exist, `false` otherwise /// \returns `true` if both edges exist, `false` otherwise
constexpr bool is_undirected(size_t a, size_t b) const { constexpr bool is_undirected(size_t a, size_t b) const {
const auto* e0 = _conn_map[a][b]; const auto* e0 = _edge_map[a][b];
const auto* e1 = _conn_map[b][a]; const auto* e1 = _edge_map[b][a];
if (not (e0 != nullptr && e1 != nullptr)) { if (not (e0 != nullptr && e1 != nullptr)) {
return false; return false;
} }
@@ -232,9 +232,9 @@ public:
if (empty()) { if (empty()) {
return nullptr; return nullptr;
} }
edge_t* it = _conn_map[a][b]; edge_t* it = _edge_map[a][b];
if (it) { if (it) {
return _conn_pool[*it]; return _edge_pool[*it];
} }
return nullptr; return nullptr;
} }
@@ -248,9 +248,9 @@ public:
if (empty()) { if (empty()) {
return nullptr; return nullptr;
} }
const edge_t* it = _conn_map[a][b]; const edge_t* it = _edge_map[a][b];
if (it) { if (it) {
return _conn_pool[*it]; return _edge_pool[*it];
} }
return nullptr; return nullptr;
} }
@@ -261,10 +261,10 @@ public:
/// \returns A list containing all vertices `x` with edges from `vertex` to `x...` /// \returns A list containing all vertices `x` with edges from `vertex` to `x...`
list<size_t> outgoing(size_t vertex) { list<size_t> outgoing(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
res.push_back(it.first); res.push_back(it.first);
} }
return res; return res;
@@ -276,11 +276,11 @@ public:
/// \returns A list containing all vertices `x` with edges from `x...` to `vertex` /// \returns A list containing all vertices `x` with edges from `x...` to `vertex`
list<size_t> incoming(size_t vertex) { list<size_t> incoming(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (size_t n = 0; n < _conn_map.size(); ++n) { for (size_t n = 0; n < _edge_map.size(); ++n) {
if (_conn_map[n][vertex]) { if (_edge_map[n][vertex]) {
res.push_back(n); res.push_back(n);
} }
} }
@@ -293,11 +293,11 @@ public:
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex` /// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
list<size_t> symmetric(size_t vertex) { list<size_t> symmetric(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
if (_conn_map[it.first][vertex]) { if (_edge_map[it.first][vertex]) {
res.push_back(it.first); res.push_back(it.first);
} }
} }
@@ -314,11 +314,11 @@ public:
/// \returns A list containing all vertices `x` that have symmetric edges with `vertex` /// \returns A list containing all vertices `x` that have symmetric edges with `vertex`
list<size_t> undirected(size_t vertex) { list<size_t> undirected(size_t vertex) {
list<size_t> res; list<size_t> res;
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return res; return res;
} }
for (const auto& it : _conn_map[vertex]) { for (const auto& it : _edge_map[vertex]) {
const auto* at = _conn_map[it.first][vertex]; const auto* at = _edge_map[it.first][vertex];
if (at != nullptr && *at == it.second) { if (at != nullptr && *at == it.second) {
res.push_back(it.first); res.push_back(it.first);
} }
@@ -332,10 +332,10 @@ public:
/// \param vertex The id of the vertex /// \param vertex The id of the vertex
/// \returns A pointer to a map containing edges mapped from this vertex /// \returns A pointer to a map containing edges mapped from this vertex
const auto* edges(size_t vertex) { const auto* edges(size_t vertex) {
if (empty() || vertex >= _conn_map.size()) { if (empty() || vertex >= _edge_map.size()) {
return nullptr; return nullptr;
} }
return &_conn_map[vertex]; return &_edge_map[vertex];
} }
/// @} /// @}
@@ -392,19 +392,19 @@ public:
return; return;
} }
if (_conn_map.size() < _vertex_pool.capacity()) { if (_edge_map.size() < _vertex_pool.capacity()) {
_conn_map.resize(_vertex_pool.capacity()); _edge_map.resize(_vertex_pool.capacity());
} }
auto it = _conn_map[a][b]; auto it = _edge_map[a][b];
size_t conn; size_t conn;
if (it != nullptr) { if (it != nullptr) {
conn = *it; conn = *it;
_conn_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...); _edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
} else { } else {
conn = _conn_pool.emplace(fennec::forward<ArgsT>(args)...); conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
} }
_conn_map[a].emplace(b, conn); _edge_map[a].emplace(b, conn);
} }
/// ///
@@ -419,21 +419,21 @@ public:
return; return;
} }
if (_conn_map.size() < _vertex_pool.capacity()) { if (_edge_map.size() < _vertex_pool.capacity()) {
_conn_map.resize(_vertex_pool.capacity()); _edge_map.resize(_vertex_pool.capacity());
} }
auto it = _conn_map[a][b]; auto it = _edge_map[a][b];
size_t conn; size_t conn;
if (it != nullptr) { if (it != nullptr) {
conn = *it; conn = *it;
_conn_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...); _edge_pool[conn] = vertex_t(fennec::forward<ArgsT>(args)...);
} else { } else {
conn = _conn_pool.emplace(fennec::forward<ArgsT>(args)...); conn = _edge_pool.emplace(fennec::forward<ArgsT>(args)...);
} }
_conn_map[a].emplace(b, conn); _edge_map[a].emplace(b, conn);
_conn_map[b].emplace(a, conn); _edge_map[b].emplace(a, conn);
} }
/// ///
@@ -443,20 +443,20 @@ public:
constexpr void cut_edge(size_t a, size_t b) { constexpr void cut_edge(size_t a, size_t b) {
// Find the edge object // Find the edge object
const auto* it = _conn_map[a][b]; const auto* it = _edge_map[a][b];
if (not it) { if (not it) {
return; return;
} }
size_t c = *it; size_t c = *it;
// Check if undirected // Check if undirected
const auto* at = _conn_map[b][a]; const auto* at = _edge_map[b][a];
if (not at || *at != c) { if (not at || *at != c) {
_conn_pool.erase(c); _edge_pool.erase(c);
} }
// Erase the edge mapping // Erase the edge mapping
_conn_map[a].erase(b); _edge_map[a].erase(b);
} }
/// ///
@@ -464,15 +464,15 @@ public:
/// \param a The first vertex id /// \param a The first vertex id
/// \param b The second vertex id /// \param b The second vertex id
constexpr void cut_edge2(size_t a, size_t b) { constexpr void cut_edge2(size_t a, size_t b) {
const auto* ita = _conn_map[a][b]; const auto* ita = _edge_map[a][b];
const auto* itb = _conn_map[a][b]; const auto* itb = _edge_map[a][b];
if (not (ita || itb)) { if (not (ita || itb)) {
return; return;
} }
if (ita) _conn_pool.erase(*ita); if (ita) _edge_pool.erase(*ita);
if (itb) _conn_pool.erase(*itb); if (itb) _edge_pool.erase(*itb);
_conn_map[a].erase(b); _edge_map[a].erase(b);
_conn_map[b].erase(a); _edge_map[b].erase(a);
} }
/// ///
@@ -491,8 +491,8 @@ public:
/// \brief Clear the graph, destructing all vertices and edges. /// \brief Clear the graph, destructing all vertices and edges.
void clear() { void clear() {
_vertex_pool.clear(); _vertex_pool.clear();
_conn_pool.clear(); _edge_pool.clear();
_conn_map.clear(); _edge_map.clear();
} }
/// @} /// @}
@@ -503,8 +503,8 @@ public:
private: private:
vertex_pool_t _vertex_pool; vertex_pool_t _vertex_pool;
edge_pool_t _conn_pool; edge_pool_t _edge_pool;
edge_map_t _conn_map; edge_map_t _edge_map;
template<typename...ArgsT> template<typename...ArgsT>
size_t _insert(ArgsT&&...args) { size_t _insert(ArgsT&&...args) {

View File

@@ -42,6 +42,22 @@ FENNEC_NO_INLINE uint64_t typeuuid() {
return id = detail::_typeuuid<RootT>(); return id = detail::_typeuuid<RootT>();
} }
template<typename RootT = void>
struct typed {
public:
const uint64_t type;
template<typename TypeT>
bool is_type() const {
return type == typeuuid<TypeT, RootT>();
}
template<typename TypeT>
typed(TypeT*)
: type(typeuuid<TypeT, RootT>()) {
}
};
} }
#endif // FENNEC_LANG_TYPEUUID_H #endif // FENNEC_LANG_TYPEUUID_H

View File

@@ -55,7 +55,7 @@ public:
/// \param str the cstring to convert /// \param str the cstring to convert
path(const cstring& str) path(const cstring& str)
: _str(str) { : _str(str) {
while (not _str.empty() && _str[_str.size() - 1] == '/') { if (str.size() > 2 && str[str.size() - 1] == '/') {
_str = _str.substring(0, str.size() - 1); _str = _str.substring(0, str.size() - 1);
} }
} }
@@ -65,7 +65,7 @@ public:
/// \param str the string to convert /// \param str the string to convert
path(const string& str) path(const string& str)
: _str(str) { : _str(str) {
while (_str[_str.size() - 1] == '/') { if (str.size() > 2 && str[str.size() - 1] == '/') {
_str = _str.substring(0, str.size() - 1); _str = _str.substring(0, str.size() - 1);
} }
} }
@@ -85,6 +85,16 @@ public:
// Assignment Operators ================================================================================================ // Assignment Operators ================================================================================================
///
/// \brief C-String Assignment Operator
/// \param str the cstring to assign
/// \returns a reference to `this` after assigning `p`
template<size_t n>
path& operator=(const char (&str)[n]) {
_str = str;
return *this;
}
/// ///
/// \brief C-String Assignment Operator /// \brief C-String Assignment Operator
/// \param p the cstring to assign /// \param p the cstring to assign
@@ -177,7 +187,7 @@ public:
#else #else
size_t start = _str.size() - 1; size_t start = _str.size() - 1;
start = _str[start] == '/' ? start - 1 : start; start = _str[start] == '/' ? start - 1 : start;
return _str.substring(0, _str.rfind('/', start)); return path(_str.substring(0, _str.rfind('/', start)));
#endif #endif
} }

View File

@@ -27,7 +27,7 @@
namespace fennec namespace fennec
{ {
class display class display : public typed<display>
{ {
public: public:
struct pixel_format { struct pixel_format {
@@ -42,7 +42,7 @@ public:
virtual bool connected() const = 0; virtual bool connected() const = 0;
virtual ~display(); virtual ~display();
virtual window* create_window() = 0; virtual window* create_window(window* parent) = 0;
const pixel_format& get_color_format() const { const pixel_format& get_color_format() const {
return _config.format; return _config.format;
@@ -55,7 +55,6 @@ public:
gfxcontext* get_context() { return _context; } gfxcontext* get_context() { return _context; }
const string name; const string name;
const uint64_t uuid;
protected: protected:
platform* _platform; platform* _platform;
@@ -63,9 +62,9 @@ protected:
config _config; config _config;
template<typename DisplayT> template<typename DisplayT>
explicit display(platform* platform, const cstring& name, DisplayT*) explicit display(platform* platform, const cstring& name, DisplayT* type)
: name(name) : typed(type)
, uuid(typeuuid<DisplayT>()) , name(name)
, _platform(platform) , _platform(platform)
, _context(nullptr) , _context(nullptr)
, _config { , _config {

View File

@@ -22,33 +22,39 @@
#include <fennec/langproc/strings/string.h> #include <fennec/langproc/strings/string.h>
#include <fennec/lang/typeuuid.h> #include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h> #include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec namespace fennec
{ {
class gfxcontext { class gfxcontext : public typed<gfxcontext> {
public: public:
const string name; const string name;
const uint64_t uuid;
virtual bool connected() = 0; virtual bool connected() = 0;
virtual const cstring& get_name() = 0;
virtual int32_t get_version_major() = 0; virtual int32_t get_version_major() = 0;
virtual int32_t get_version_minor() = 0; virtual int32_t get_version_minor() = 0;
virtual int32_t get_context_version() = 0; virtual int32_t get_version() = 0;
virtual const cstring& get_context_name() = 0;
virtual bool check_extension(const cstring& ext) = 0; virtual bool check_extension(const cstring& ext) = 0;
virtual void make_current(gfxsurface* surface) = 0; virtual void make_current(gfxsurface* surface) = 0;
virtual gfxsurface* create_surface(window* window) = 0;
virtual ~gfxcontext() = default; virtual ~gfxcontext() = default;
display* get_display() {
return _display;
}
protected: protected:
display* _display; display* _display;
template<typename ContextT> template<typename ContextT>
gfxcontext(display* display, const cstring& name, ContextT*) gfxcontext(display* display, const cstring& name, ContextT* type)
: name(name) : typed(type)
, uuid(typeuuid<ContextT>()) , name(name)
, _display(display) { , _display(display) {
} }
}; };

View File

@@ -0,0 +1,76 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file gfxsurface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#define FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H
#include <fennec/lang/types.h>
#include <fennec/lang/typeuuid.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
namespace fennec
{
class gfxsurface : public typed<gfxsurface> {
public:
virtual ~gfxsurface() = default;
virtual void resize(size_t width, size_t height) {
_width = width;
_height = height;
}
gfxcontext* get_context() {
return _context;
}
window* get_window() {
return _window;
}
protected:
gfxcontext* _context;
window* _window;
size_t _width, _height;
template<typename SurfaceT>
gfxsurface(gfxcontext* ctx, window* window, SurfaceT* type)
: typed(type)
, _context(ctx)
, _window(window)
, _width(window->get_width()), _height(window->get_height()) {
}
};
}
#endif // FENNEC_PLATFORM_INTERFACE_GFXSURFACE_H

View File

@@ -59,13 +59,12 @@
namespace fennec namespace fennec
{ {
class platform { class platform : public typed<platform> {
public: public:
using shared_object = struct shared_object; using shared_object = struct shared_object;
using symbol = void*; using symbol = void*;
const string name; const string name;
const uint64_t uuid;
virtual ~platform() = default; virtual ~platform() = default;
@@ -81,9 +80,9 @@ public:
protected: protected:
template<typename PlatformT> template<typename PlatformT>
explicit platform(const cstring& name, PlatformT*) explicit platform(const cstring& name, PlatformT* type)
: name(name) : typed(type)
, uuid(typeuuid<PlatformT>()) { , name(name) {
auto& globals = _get_globals(); auto& globals = _get_globals();
assertf(globals.singleton == nullptr, "Conflicting Platform Definitions."); assertf(globals.singleton == nullptr, "Conflicting Platform Definitions.");
globals.singleton = this; globals.singleton = this;

View File

@@ -22,6 +22,7 @@
#include <fennec/containers/optional.h> #include <fennec/containers/optional.h>
#include <fennec/langproc/strings/string.h> #include <fennec/langproc/strings/string.h>
#include <fennec/platform/interface/fwd.h> #include <fennec/platform/interface/fwd.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec namespace fennec
{ {
@@ -29,7 +30,7 @@ namespace fennec
/// ///
/// \brief interface for handling windows /// \brief interface for handling windows
/// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation. /// \details the interface makes no guarantees about the bit-depth and is completely dependent on the implementation.
class window { class window : public typed<window> {
public: public:
enum class fullscreen_mode { enum class fullscreen_mode {
windowed = 0, windowed = 0,
@@ -53,6 +54,8 @@ public:
fullscreen_mode fullscreen; fullscreen_mode fullscreen;
}; };
virtual ~window() = default;
virtual bool running() = 0; virtual bool running() = 0;
virtual void configure(const config& config) = 0; virtual void configure(const config& config) = 0;
virtual bool initialize(bool modal) = 0; virtual bool initialize(bool modal) = 0;
@@ -63,7 +66,7 @@ public:
virtual bool set_width(size_t w) = 0; virtual bool set_width(size_t w) = 0;
virtual bool set_height(size_t h) = 0; virtual bool set_height(size_t h) = 0;
virtual bool set_size(size_t w, size_t h) = 0; virtual bool resize(size_t w, size_t h) = 0;
virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0; virtual bool set_fullscreen_mode(fullscreen_mode mode) = 0;
@@ -73,6 +76,8 @@ public:
virtual bool grab_mouse(bool e) = 0; virtual bool grab_mouse(bool e) = 0;
virtual bool block_screensaver(bool e) = 0; virtual bool block_screensaver(bool e) = 0;
virtual struct wl_surface* get_native_handle() = 0;
bool is_child() const { bool is_child() const {
if (not _config) return false; if (not _config) return false;
return _config->flags & flags_child; return _config->flags & flags_child;
@@ -91,9 +96,13 @@ public:
return _display; return _display;
} }
const config& get_config() const {
return *_config;
}
const string& get_title() const { const string& get_title() const {
static const string _null = { "null" }; static const string _null{"null"};
if (not _config) return _null; if (not _config) return _null;
return _config->title; return _config->title;
} }
@@ -137,13 +146,20 @@ public:
} }
protected: protected:
virtual ~window() = default; template<typename TypeT>
window(display* display, window* parent); window(display* display, window* parent, TypeT* type)
: typed(type)
, _display(display)
, _parent(parent)
, _surface(nullptr) {
}
display* _display; display* _display;
window* _parent; window* _parent;
optional<config> _config; optional<config> _config;
gfxsurface* _context; gfxsurface* _surface;
private:
private: private:
}; };

View File

@@ -33,13 +33,28 @@ public:
bool connected() const override; bool connected() const override;
void* get_native_handle() override { return _handle; } void* get_native_handle() override { return _handle; }
window* create_window() override; window* create_window(window* parent) override;
wl_registry* get_registry() { return _registry; }
const wl_registry* get_registry() const { return _registry; }
wl_compositor* get_compositor() { return _compositor; }
const wl_compositor* get_compositor() const { return _compositor; }
// xdg_wm_base* get_shell() { return _shell; }
//const xdg_wm_base* get_shell() const { return _shell; }
wl_seat* get_seat() { return _seat; }
const wl_seat* get_seat() const { return _seat; }
wl_shm* get_shm() { return _shm; }
const wl_shm* get_shm() const { return _shm; }
private: private:
wl_display* _handle; wl_display* _handle;
wl_registry* _registry; wl_registry* _registry;
wl_compositor* _compositor; wl_compositor* _compositor;
wl_shell* _shell; //xdg_wm_base* _shell;
wl_seat* _seat; wl_seat* _seat;
wl_shm* _shm; wl_shm* _shm;
bool _fifo; bool _fifo;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -60,7 +60,7 @@
FENNEC_LIB(WAYLAND); FENNEC_LIB(WAYLAND);
FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...); FENNEC_SYMBOL(void, wl_proxy_marshal, struct wl_proxy*, uint32_t, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, ...); FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_flags, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, uint32_t, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*); FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_create, struct wl_proxy*, const struct wl_interface*);
FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*); FENNEC_SYMBOL(void, wl_proxy_destroy, struct wl_proxy*);
FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*); FENNEC_SYMBOL(int, wl_proxy_add_listener, struct wl_proxy*, void (**)(void), void*);
@@ -72,6 +72,11 @@ FENNEC_SYMBOL(const char*, wl_proxy_get_class, st
FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*); FENNEC_SYMBOL(void, wl_proxy_set_queue, struct wl_proxy*, struct wl_event_queue*);
FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*); FENNEC_SYMBOL(void*, wl_proxy_create_wrapper, void*);
FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*); FENNEC_SYMBOL(void, wl_proxy_wrapper_destroy, void*);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t, const struct wl_interface*, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*, uint32_t, const struct wl_interface*, uint32_t, ...);
FENNEC_SYMBOL(void, wl_proxy_set_tag, struct wl_proxy*, const char* const*);
FENNEC_SYMBOL(const char* const*, wl_proxy_get_tag, struct wl_proxy*);
FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*); FENNEC_SYMBOL(struct wl_display*, wl_display_connect, const char*);
FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int); FENNEC_SYMBOL(struct wl_display*, wl_display_connect_to_fd, int);
FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*); FENNEC_SYMBOL(void, wl_display_disconnect, struct wl_display*);
@@ -88,6 +93,7 @@ FENNEC_SYMBOL(int, wl_display_get_error, st
FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*); FENNEC_SYMBOL(int, wl_display_flush, struct wl_display*);
FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*); FENNEC_SYMBOL(int, wl_display_roundtrip, struct wl_display*);
FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*); FENNEC_SYMBOL(struct wl_event_queue*, wl_display_create_queue, struct wl_display*);
FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*); FENNEC_SYMBOL(void, wl_event_queue_destroy, struct wl_event_queue*);
FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t); FENNEC_SYMBOL(void, wl_log_set_handler_client, wl_log_func_t);
FENNEC_SYMBOL(void, wl_list_init, struct wl_list*); FENNEC_SYMBOL(void, wl_list_init, struct wl_list*);
@@ -96,10 +102,6 @@ FENNEC_SYMBOL(void, wl_list_remove, st
FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*); FENNEC_SYMBOL(int, wl_list_length, const struct wl_list*);
FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*); FENNEC_SYMBOL(int, wl_list_empty, const struct wl_list*);
FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*); FENNEC_SYMBOL(void, wl_list_insert_list, struct wl_list*, struct wl_list*);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor, struct wl_proxy*, uint32_t opcode, const struct wl_interface*interface, ...);
FENNEC_SYMBOL(struct wl_proxy*, wl_proxy_marshal_constructor_versioned, struct wl_proxy*proxy, uint32_t opcode, const struct wl_interface*interface, uint32_t version, ...);
FENNEC_SYMBOL(void, wl_proxy_set_tag, struct wl_proxy*, const char* const*);
FENNEC_SYMBOL(const char* const*, wl_proxy_get_tag, struct wl_proxy*);
FENNEC_GLOBAL(const struct wl_interface, wl_display_interface); FENNEC_GLOBAL(const struct wl_interface, wl_display_interface);
FENNEC_GLOBAL(const struct wl_interface, wl_registry_interface); FENNEC_GLOBAL(const struct wl_interface, wl_registry_interface);

File diff suppressed because it is too large Load Diff

View File

@@ -1,198 +0,0 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H
/*
* Copyright © 2008 Kristian Høgsberg
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stddef.h>
#include <inttypes.h>
#include <stdarg.h>
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_EXPORT __attribute__ ((visibility("default")))
#else
#define WL_EXPORT
#endif
#if __STDC_VERSION__ >= 202311L
#define WL_DEPRECATED [[deprecated]]
#elif defined(__GNUC__) && __GNUC__ >= 4
#define WL_DEPRECATED __attribute__ ((deprecated))
#else
#define WL_DEPRECATED
#endif
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
#else
#define WL_PRINTF(x, y)
#endif
#if __STDC_VERSION__ >= 202311L
#define WL_TYPEOF(expr) typeof(expr)
#else
#define WL_TYPEOF(expr) __typeof__(expr)
#endif
struct wl_message {
const char *name;
const char *signature;
const struct wl_interface **types;
};
struct wl_interface {
const char *name;
int version;
int method_count;
const struct wl_message *methods;
int event_count;
const struct wl_message *events;
};
struct wl_list {
struct wl_list *prev;
struct wl_list *next;
};
#define wl_container_of(ptr, sample, member) \
(WL_TYPEOF(sample))((char *)(ptr) - \
offsetof(WL_TYPEOF(*sample), member))
#define wl_list_for_each(pos, head, member) \
for (pos = wl_container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.next, pos, member))
#define wl_list_for_each_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->next, pos, member), \
tmp = wl_container_of((pos)->member.next, tmp, member); \
&pos->member != (head); \
pos = tmp, \
tmp = wl_container_of(pos->member.next, tmp, member))
#define wl_list_for_each_reverse(pos, head, member) \
for (pos = wl_container_of((head)->prev, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.prev, pos, member))
#define wl_list_for_each_reverse_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->prev, pos, member), \
tmp = wl_container_of((pos)->member.prev, tmp, member); \
&pos->member != (head); \
pos = tmp, \
tmp = wl_container_of(pos->member.prev, tmp, member))
struct wl_array {
size_t size;
size_t alloc;
void *data;
};
void
wl_array_init(struct wl_array *array);
void
wl_array_release(struct wl_array *array);
void *
wl_array_add(struct wl_array *array, size_t size);
int
wl_array_copy(struct wl_array *array, struct wl_array *source);
#define wl_array_for_each(pos, array) \
for (pos = (array)->data; \
(array)->size != 0 && \
(const char *) pos < ((const char *) (array)->data + (array)->size); \
(pos)++)
typedef int32_t wl_fixed_t;
static inline double
wl_fixed_to_double(wl_fixed_t f)
{
return f / 256.0;
}
static inline wl_fixed_t
wl_fixed_from_double(double d)
{
return (wl_fixed_t) (d * 256.0);
}
static inline int
wl_fixed_to_int(wl_fixed_t f)
{
return f / 256;
}
static inline wl_fixed_t
wl_fixed_from_int(int i)
{
return i * 256;
}
union wl_argument {
int32_t i;
uint32_t u;
wl_fixed_t f;
const char *s;
struct wl_object *o;
uint32_t n;
struct wl_array *a;
int32_t h;
};
typedef int (*wl_dispatcher_func_t)(const void *user_data, void *target,
uint32_t opcode, const struct wl_message *msg,
union wl_argument *args);
typedef void (*wl_log_func_t)(const char *fmt, va_list args) WL_PRINTF(1, 0);
enum wl_iterator_result {
WL_ITERATOR_STOP,
WL_ITERATOR_CONTINUE
};
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_UTIL_H

View 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/>.
// =====================================================================================================================
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H
#define FENNEC_LIB(name) extern "C" bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
extern "C" WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) extern "C" type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h>
#include <wayland-client-core.h>
#define wl_proxy_marshal WAYLAND_wl_proxy_marshal
#define wl_proxy_marshal_flags WAYLAND_wl_proxy_marshal_flags
#define wl_proxy_create WAYLAND_wl_proxy_create
#define wl_proxy_destroy WAYLAND_wl_proxy_destroy
#define wl_proxy_add_listener WAYLAND_wl_proxy_add_listener
#define wl_proxy_set_user_data WAYLAND_wl_proxy_set_user_data
#define wl_proxy_get_user_data WAYLAND_wl_proxy_get_user_data
#define wl_proxy_get_version WAYLAND_wl_proxy_get_version
#define wl_proxy_get_id WAYLAND_wl_proxy_get_id
#define wl_proxy_get_class WAYLAND_wl_proxy_get_class
#define wl_proxy_set_queue WAYLAND_wl_proxy_set_queue
#define wl_proxy_create_wrapper WAYLAND_wl_proxy_create_wrapper
#define wl_proxy_wrapper_destroy WAYLAND_wl_proxy_wrapper_destroy
#define wl_proxy_marshal_constructor WAYLAND_wl_proxy_marshal_constructor
#define wl_proxy_marshal_constructor_versioned WAYLAND_wl_proxy_marshal_constructor_versioned
#define wl_proxy_set_tag WAYLAND_wl_proxy_set_tag
#define wl_proxy_get_tag WAYLAND_wl_proxy_get_tag
#define wl_event_queue_destroy WAYLAND_wl_event_queue_destroy
#define wl_log_set_handler_client WAYLAND_wl_log_set_handler_client
#define wl_list_init WAYLAND_wl_list_init
#define wl_list_insert WAYLAND_wl_list_insert
#define wl_list_remove WAYLAND_wl_list_remove
#define wl_list_length WAYLAND_wl_list_length
#define wl_list_empty WAYLAND_wl_list_empty
#define wl_list_insert_list WAYLAND_wl_list_insert_list
#define wl_display_connect WAYLAND_wl_display_connect
#define wl_display_connect_to_fd WAYLAND_wl_display_connect_to_fd
#define wl_display_reconnect WAYLAND_wl_display_reconnect
#define wl_display_disconnect WAYLAND_wl_display_disconnect
#define wl_display_get_fd WAYLAND_wl_display_get_fd
#define wl_display_dispatch WAYLAND_wl_display_dispatch
#define wl_display_dispatch_queue WAYLAND_wl_display_dispatch_queue
#define wl_display_dispatch_queue_pending WAYLAND_wl_display_dispatch_queue_pending
#define wl_display_dispatch_pending WAYLAND_wl_display_dispatch_pending
#define wl_display_prepare_read WAYLAND_wl_display_prepare_read
#define wl_display_prepare_read_queue WAYLAND_wl_display_prepare_read_queue
#define wl_display_read_events WAYLAND_wl_display_read_events
#define wl_display_cancel_read WAYLAND_wl_display_cancel_read
#define wl_display_get_error WAYLAND_wl_display_get_error
#define wl_display_flush WAYLAND_wl_display_flush
#define wl_display_roundtrip WAYLAND_wl_display_roundtrip
#define wl_display_create_queue WAYLAND_wl_display_create_queue
#define wl_seat_interface *WAYLAND_wl_seat_interface
#define wl_surface_interface *WAYLAND_wl_surface_interface
#define wl_shm_pool_interface *WAYLAND_wl_shm_pool_interface
#define wl_buffer_interface *WAYLAND_wl_buffer_interface
#define wl_registry_interface *WAYLAND_wl_registry_interface
#define wl_region_interface *WAYLAND_wl_region_interface
#define wl_pointer_interface *WAYLAND_wl_pointer_interface
#define wl_keyboard_interface *WAYLAND_wl_keyboard_interface
#define wl_compositor_interface *WAYLAND_wl_compositor_interface
#define wl_output_interface *WAYLAND_wl_output_interface
#define wl_shm_interface *WAYLAND_wl_shm_interface
#define wl_data_device_interface *WAYLAND_wl_data_device_interface
#define wl_data_offer_interface *WAYLAND_wl_data_offer_interface
#define wl_data_source_interface *WAYLAND_wl_data_source_interface
#define wl_data_device_manager_interface *WAYLAND_wl_data_device_manager_interface
#define wl_egl_window_create WAYLAND_wl_egl_window_create
#define wl_egl_window_destroy WAYLAND_wl_egl_window_destroy
#define wl_egl_window_resize WAYLAND_wl_egl_window_resize
#define wl_egl_window_get_attached_size WAYLAND_wl_egl_window_get_attached_size
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_LIB_WAYLAND_CLIENT_H

View File

@@ -0,0 +1,83 @@
// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \file window.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H
#include <fennec/platform/interface/window.h>
#include <fennec/platform/linux/wayland/display.h>
namespace fennec
{
class wayland_window : public window {
public:
bool running() override;
void configure(const config& config) override;
bool initialize(bool modal) override;
bool shutdown() override;
bool set_title(const cstring& title) override;
bool set_title(const string& title) override;
bool set_width(size_t w) override;
bool set_height(size_t h) override;
bool resize(size_t w, size_t h) override;
bool set_resizable(bool e) override;
bool set_fullscreen_mode(fullscreen_mode mode) override;
bool grab_keyboard(bool e) override;
bool grab_mouse(bool e) override;
bool block_screensaver(bool e) override;
wayland_window(wayland_display* display, wayland_window* parent);
~wayland_window() override;
struct wl_surface* get_native_handle() override {
return _handle;
}
private:
wl_surface* _handle;
wl_shell_surface* _shell;
size_t _nfs_width, _nfs_height;
static void listen_ping(void*, wl_shell_surface*, uint32_t);
static void listen_configure(void*, wl_shell_surface*, uint32_t, int32_t, int32_t);
static void listen_popup_done(void*, wl_shell_surface*);
};
}
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_WINDOW_H

View File

@@ -21,6 +21,7 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <fennec/platform/interface/gfxcontext.h> #include <fennec/platform/interface/gfxcontext.h>
#include <fennec/platform/opengl/egl/fwd.h>
namespace fennec namespace fennec
{ {
@@ -34,12 +35,26 @@ public:
bool connected() override; bool connected() override;
int32_t get_version_major() override { return _eglvmajor; } int32_t get_version_major() override { return _eglvmajor; }
int32_t get_version_minor() override { return _eglvminor; } int32_t get_version_minor() override { return _eglvminor; }
int32_t get_context_version() override { return _eglctype; } int32_t get_version() override { return _eglctype; }
const cstring& get_context_name() override; const cstring& get_name() override;
bool check_extension(const cstring& ext) override; bool check_extension(const cstring& ext) override;
gfxsurface* create_surface(window* window) override;
void make_current(gfxsurface* surface) override; void make_current(gfxsurface* surface) override;
EGLDisplay get_egl_display() {
return _egldisplay;
}
EGLDisplay get_egl_context() {
return _eglcontext;
}
EGLDisplay get_egl_config() {
return _eglconfig;
}
private: private:
EGLDisplay _egldisplay; EGLDisplay _egldisplay;
EGLContext _eglcontext; EGLContext _eglcontext;

View File

@@ -16,7 +16,27 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_CONCURRENCY_ATOMIC_H ///
#define FENNEC_CONCURRENCY_ATOMIC_H /// \file fwd.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#endif // FENNEC_CONCURRENCY_ATOMIC_H #ifndef FENNEC_PLATFORM_OPENGL_EGL_FWD_H
#define FENNEC_PLATFORM_OPENGL_EGL_FWD_H
namespace fennec
{
class eglcontext;
class eglsurface;
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_FWD_H

View File

@@ -16,7 +16,45 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#ifndef FENNEC_CONCURRENCY_MUTEX_H ///
#define FENNEC_CONCURRENCY_MUTEX_H /// \file surface.h
/// \brief
///
///
/// \details
/// \author Medusa Slockbower
///
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
///
///
#endif // FENNEC_CONCURRENCY_MUTEX_H #ifndef FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#define FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H
#include <fennec/platform/interface/gfxsurface.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/opengl/egl/context.h>
namespace fennec
{
class eglsurface : public gfxsurface {
public:
~eglsurface() override;
void resize(size_t width, size_t height) override;
eglsurface(eglcontext* context, window* window);
EGLSurface get_egl_surface() {
return _surface;
}
private:
void* _handle;
EGLSurface _surface;
};
}
#endif // FENNEC_PLATFORM_OPENGL_EGL_SURFACE_H

View File

@@ -47,6 +47,14 @@ configurability and programmability within those systems and their stages. This
be achieved using events at different stages of those engines that are on-demand. be achieved using events at different stages of those engines that are on-demand.
## External Libraries
* `cpptrace`
* Walking the stack and retrieving information about the code is *very* platform
dependent, and it makes little sense spending days writing a library that will
be less effective.
## Definitions ## Definitions
&ensp; Many subpages of these documents will contain tables that use symbols to &ensp; Many subpages of these documents will contain tables that use symbols to
@@ -62,4 +70,7 @@ denote implementation and testing progress. The symbols are defined below.
## Libraries ## Libraries
- [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang) - [C++ Language Library](./CPP_LANGUAGE.md#c-language-library-lang)
- [Platform Support Library](./PLATFORM_SUPPORT.md#platform--api-support) - [Platform Support Library](./PLATFORM_SUPPORT.md#platform-support-library-platform)
- [Memory Library](./MEMORY.md#memory-library-memory)
- [Containers Library](./CONTAINERS.md#containers-library-containers)
- [Language Processing Library](./LANGUAGE_PROCESSING.md#language-processing-library-langproc)

View File

@@ -59,22 +59,22 @@ See:
| is_null_pointer | ✅ | ✅ | | is_null_pointer | ✅ | ✅ |
| is_integral | ✅ | ✅ | | is_integral | ✅ | ✅ |
| is_floating_point | ✅ | ✅ | | is_floating_point | ✅ | ✅ |
| is_array | ✅ | | | is_array | ✅ | 🚧 |
| is_enum | ⛔ | ⛔ | | is_enum | ⛔ | ⛔ |
| is_union | ⛔ | ⛔ | | is_union | ⛔ | ⛔ |
| is_class | ✅ | ✅ | | is_class | ✅ | ✅ |
| is_function | ⛔ | ⛔ | | is_function | ⛔ | ⛔ |
| is_pointer | ✅ | ✅ | | is_pointer | ✅ | ✅ |
| is_lvalue_reference | ✅ | ✅ | | is_lvalue_reference | ✅ | ✅ |
| is_rvalue_reference | | | | is_rvalue_reference | | |
| is_member_object_pointer | ⛔ | ⛔ | | is_member_object_pointer | ⛔ | ⛔ |
| is_member_function_pointer | ⛔ | ⛔ | | is_member_function_pointer | ⛔ | ⛔ |
### Composite Types ### Composite Types
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------|:-----------:|:------:| |:------------------|:-----------:|:------:|
| is_fundamental | | | | is_fundamental | | |
| is_arithmetic | | | | is_arithmetic | | |
| is_scalar | ⛔ | ⛔ | | is_scalar | ⛔ | ⛔ |
| is_object | ⛔ | ⛔ | | is_object | ⛔ | ⛔ |
| is_compound | ⛔ | ⛔ | | is_compound | ⛔ | ⛔ |
@@ -84,9 +84,9 @@ See:
### Type Properties ### Type Properties
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:----------------------------------|:-----------:|:------:| |:----------------------------------|:-----------:|:------:|
| is_const | | | | is_const | | |
| is_volatile | | | | is_volatile | | |
| is_trivially_copyable | | | | is_trivially_copyable | | |
| is_standard_layout | ⛔ | ⛔ | | is_standard_layout | ⛔ | ⛔ |
| has_unique_object_representations | ⛔ | ⛔ | | has_unique_object_representations | ⛔ | ⛔ |
| is_empty | ⛔ | ⛔ | | is_empty | ⛔ | ⛔ |
@@ -95,8 +95,8 @@ See:
| is_final | ⛔ | ⛔ | | is_final | ⛔ | ⛔ |
| is_aggregate | ⛔ | ⛔ | | is_aggregate | ⛔ | ⛔ |
| is_implicit_lifetime | ⛔ | ⛔ | | is_implicit_lifetime | ⛔ | ⛔ |
| is_signed | | | | is_signed | | |
| is_unsigned | | | | is_unsigned | | |
| is_bounded_array | ⛔ | ⛔ | | is_bounded_array | ⛔ | ⛔ |
| is_unbounded_array | ⛔ | ⛔ | | is_unbounded_array | ⛔ | ⛔ |
| is_scoped_enum | ⛔ | ⛔ | | is_scoped_enum | ⛔ | ⛔ |
@@ -104,16 +104,16 @@ See:
### Supported Operations ### Supported Operations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:| |:------------------------------------|:-----------:|:------:|
| is_constructible | | | | is_constructible | | |
| is_trivially_constructible | | | | is_trivially_constructible | | |
| is_nothrow_constructible | ⛔ | ⛔ | | is_nothrow_constructible | ⛔ | ⛔ |
| is_default_constructible | | | | is_default_constructible | | |
| is_trivially_default_constructible | ⛔ | ⛔ | | is_trivially_default_constructible | ⛔ | ⛔ |
| is_nothrow_default_constructible | ⛔ | ⛔ | | is_nothrow_default_constructible | ⛔ | ⛔ |
| is_copy_constructible | | | | is_copy_constructible | | |
| is_trivially_copy_constructible | ⛔ | ⛔ | | is_trivially_copy_constructible | ⛔ | ⛔ |
| is_nothrow_copy_constructible | ⛔ | ⛔ | | is_nothrow_copy_constructible | ⛔ | ⛔ |
| is_move_constructible | | | | is_move_constructible | | |
| is_trivially_move_constructible | ⛔ | ⛔ | | is_trivially_move_constructible | ⛔ | ⛔ |
| is_nothrow_move_constructible | ⛔ | ⛔ | | is_nothrow_move_constructible | ⛔ | ⛔ |
| is_destructible | ⛔ | ⛔ | | is_destructible | ⛔ | ⛔ |
@@ -137,10 +137,10 @@ See:
### Type Relationships ### Type Relationships
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:------------------------------------|:-----------:|:------:| |:------------------------------------|:-----------:|:------:|
| is_same | | | | is_same | | |
| is_base_of | ❌ | ❌ | | is_base_of | ❌ | ❌ |
| is_virtual_base_of | ❌ | ❌ | | is_virtual_base_of | ❌ | ❌ |
| is_convertible | | | | is_convertible | | |
| is_nothrow_convertible | ❌ | ❌ | | is_nothrow_convertible | ❌ | ❌ |
| is_layout_compatible | ❌ | ❌ | | is_layout_compatible | ❌ | ❌ |
| is_pointer_interconvertible_base_of | ❌ | ❌ | | is_pointer_interconvertible_base_of | ❌ | ❌ |
@@ -152,19 +152,19 @@ See:
### Type Transformations ### Type Transformations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:---------------------|:-----------:|:------:| |:---------------------|:-----------:|:------:|
| add_const | | | | add_const | | |
| add_volatile | | | | add_volatile | | |
| add_cv | | | | add_cv | | |
| remove_const | | | | remove_const | | |
| remove_volatile | | | | remove_volatile | | |
| remove_cv | | | | remove_cv | | |
| add_lvalue_reference | | | | add_lvalue_reference | | |
| add_rvalue_reference | | | | add_rvalue_reference | | |
| remove_reference | | | | remove_reference | | |
| add_pointer | | | | add_pointer | | |
| remove_pointer | | | | remove_pointer | | |
| make_signed | | | | make_signed | | |
| make_unsigned | | | | make_unsigned | | |
| remove_extent | ❌ | ❌ | | remove_extent | ❌ | ❌ |
| remove_all_extents | ❌ | ❌ | | remove_all_extents | ❌ | ❌ |
@@ -175,16 +175,16 @@ See:
| aligned_union | ❌ | ❌ | | aligned_union | ❌ | ❌ |
| aligned_union | ❌ | ❌ | | aligned_union | ❌ | ❌ |
| decay | 🚧 | 🚧 | | decay | 🚧 | 🚧 |
| remove_cvref | | | | remove_cvref | | |
| enable_if | | | | enable_if | | |
| conditional | | | | conditional | | |
| common_type | ❌ | ❌ | | common_type | ❌ | ❌ |
| common_reference | ❌ | ❌ | | common_reference | ❌ | ❌ |
| basic_common_reference | ❌ | ❌ | | basic_common_reference | ❌ | ❌ |
| underlying_type | ❌ | ❌ | | underlying_type | ❌ | ❌ |
| result_of | ❌ | ❌ | | result_of | ❌ | ❌ |
| invoke_result | ❌ | ❌ | | invoke_result | ❌ | ❌ |
| void_t | | | | void_t | | |
### Logical Operations ### Logical Operations
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
@@ -196,9 +196,9 @@ See:
### Sequences ### Sequences
| Symbol | Implemented | Passed | | Symbol | Implemented | Passed |
|:-------------------------------------------------|:-----------:|:------:| |:-------------------------------------------------|:-----------:|:------:|
| const_sequence | | | | const_sequence | | |
| const_integer_sequence (`std::integer_sequence`) | | | | const_integer_sequence (`std::integer_sequence`) | | |
| make_integer_sequence | | | | make_integer_sequence | | |
| const_index_sequence (`std::index_sequence`) | | | | const_index_sequence (`std::index_sequence`) | | |
| make_index_sequence | | | | make_index_sequence | | |
| concat_sequence | | | | concat_sequence | | |

View File

@@ -40,7 +40,7 @@ path path::current() {
path path::current() { path path::current() {
char cstr[PATH_MAX]; char cstr[PATH_MAX];
if (getcwd(cstr, sizeof(cstr)) == nullptr) { if (getcwd(cstr, sizeof(cstr)) == nullptr) {
return string(""); return path("");
} }
return path(cstring(cstr, strlen(cstr) + 1)); return path(cstring(cstr, strlen(cstr) + 1));
} }

View File

@@ -18,9 +18,11 @@
#include <fennec/platform/linux/wayland/display.h> #include <fennec/platform/linux/wayland/display.h>
#include <fennec/platform/linux/wayland/lib/loader.h> #include <fennec/platform/linux/wayland/lib/loader.h>
#include <fennec/platform/linux/wayland/lib/wayland-client.h> #include <fennec/platform/linux/wayland/lib/wayland.h>
#include <fennec/lang/startup.h> #include <fennec/lang/startup.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
namespace fennec namespace fennec
{ {
@@ -42,7 +44,6 @@ wayland_display::wayland_display(platform* platform)
, _handle(nullptr) , _handle(nullptr)
, _registry(nullptr) , _registry(nullptr)
, _compositor(nullptr) , _compositor(nullptr)
, _shell(nullptr)
, _seat(nullptr) , _seat(nullptr)
, _shm(nullptr) , _shm(nullptr)
, _fifo(false) { , _fifo(false) {
@@ -89,14 +90,13 @@ bool wayland_display::connected() const {
return _handle != nullptr; return _handle != nullptr;
} }
window* wayland_display::create_window() { window* wayland_display::create_window(window* parent) {
return nullptr; return new wayland_window(this, static_cast<wayland_window*>(parent));
} }
void wayland_display::cleanup() { void wayland_display::cleanup() {
// Cleanup members // Cleanup members
if (_shell) wl_shell_destroy(_shell);
if (_compositor) wl_compositor_destroy(_compositor); if (_compositor) wl_compositor_destroy(_compositor);
if (_registry) wl_registry_destroy(_registry); if (_registry) wl_registry_destroy(_registry);
if (_handle) { if (_handle) {
@@ -104,7 +104,6 @@ void wayland_display::cleanup() {
wl_display_disconnect(_handle); wl_display_disconnect(_handle);
} }
_shell = nullptr;
_compositor = nullptr; _compositor = nullptr;
_registry = nullptr; _registry = nullptr;
_handle = nullptr; _handle = nullptr;
@@ -121,11 +120,9 @@ void wayland_display::listen_global(void* data, wl_registry* registry, uint32_t
const cstring interface = cstring(itfc, strlen(itfc) + 1); const cstring interface = cstring(itfc, strlen(itfc) + 1);
if (interface == "wl_compositor") { if (interface == "wl_compositor") {
device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, wl_compositor_interface, version)); device->_compositor = static_cast<wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, version));
} else if (interface == "wl_shell") {
device->_shell = static_cast<wl_shell*>(wl_registry_bind(registry, name, wl_shell_interface, version));
} else if (interface == "wl_seat") { } else if (interface == "wl_seat") {
device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, wl_seat_interface, version)); device->_seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, &wl_seat_interface, version));
wl_seat_add_listener(device->_seat, &seat_listener, device); wl_seat_add_listener(device->_seat, &seat_listener, device);
} else if (interface == "wp_fifo_manager_v1") { } else if (interface == "wp_fifo_manager_v1") {
device->_fifo = true; device->_fifo = true;

View File

@@ -16,13 +16,13 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// ===================================================================================================================== // =====================================================================================================================
#include <fennec/platform/linux/wayland/lib/wayland-client.h> #include <fennec/platform/linux/wayland/lib/headers/wayland-client-protocols.h>
#include <fennec/platform/linux/wayland/lib/loader.h> #include <fennec/platform/linux/wayland/lib/loader.h>
#define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name; #define FENNEC_LIB(name) bool FENNEC_HAS_LIB_##name;
#define FENNEC_SYMBOL(ret, fn, ...) using sym_##fn = ret(*)(__VA_ARGS__); \ #define FENNEC_SYMBOL(ret, fn, ...) using WAYLAND_sym_##fn = ret(*)(__VA_ARGS__); \
sym_##fn fn; WAYLAND_sym_##fn WAYLAND_##fn;
#define FENNEC_GLOBAL(type, name) type* name; #define FENNEC_GLOBAL(type, name) type* WAYLAND_##name;
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
namespace fennec namespace fennec
@@ -57,10 +57,10 @@ bool load_symbols(platform* platform) {
return false; \ return false; \
} \ } \
current_lib = &_FENNEC_LIB_##lib; current_lib = &_FENNEC_LIB_##lib;
#define FENNEC_SYMBOL(ret, fn, ...) fn = (sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \ #define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = (WAYLAND_sym_##fn)(platform->find_symbol(current_lib->obj, #fn)); \
assertf(fn != nullptr, "Failed to find symbol: " #fn); assertf(WAYLAND_##fn != nullptr, "Failed to find symbol: " #fn);
#define FENNEC_GLOBAL(type, name) name = (type*)(platform->find_symbol(current_lib->obj, #name)); \ #define FENNEC_GLOBAL(type, name) WAYLAND_##name = (type*)(platform->find_symbol(current_lib->obj, #name)); \
assertf(name != nullptr, "Failed to find global: " #name); assertf(WAYLAND_##name != nullptr, "Failed to find global: " #name);
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
@@ -75,8 +75,8 @@ void unload_symbols(platform* platform) {
#define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \ #define FENNEC_LIB(lib) platform->unload_object(_FENNEC_LIB_##lib.obj); \
_FENNEC_LIB_##lib.obj = nullptr; _FENNEC_LIB_##lib.obj = nullptr;
#define FENNEC_SYMBOL(ret, fn, ...) fn = nullptr; #define FENNEC_SYMBOL(ret, fn, ...) WAYLAND_##fn = nullptr;
#define FENNEC_GLOBAL(type, name) name = nullptr; #define FENNEC_GLOBAL(type, name) WAYLAND_##name = nullptr;
#include <fennec/platform/linux/wayland/lib/sym.h> #include <fennec/platform/linux/wayland/lib/sym.h>
} }

View File

@@ -0,0 +1,139 @@
// =====================================================================================================================
// 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/gfxcontext.h>
#include <fennec/platform/interface/gfxsurface.h>
#include <fennec/platform/linux/wayland/window.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
bool wayland_window::running() {
return _surface != nullptr;
}
void wayland_window::configure(const config& config) {
_config = config;
}
bool wayland_window::initialize(bool) {
wayland_display* display = static_cast<wayland_display*>(_display);
_handle = wl_compositor_create_surface(display->get_compositor());
_surface = display->get_context()->create_surface(this);
return false;
}
bool wayland_window::shutdown() {
delete _surface;
wl_surface_destroy(_handle);
_display = nullptr;
_surface = nullptr;
_shell = nullptr;
_handle = nullptr;
return false;
}
bool wayland_window::set_title(const cstring& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_title(const string& title) {
if (not _config) {
return true;
}
_config->title = title;
wl_shell_surface_set_title(_shell, _config->title.cstr());
return false;
}
bool wayland_window::set_width(size_t w) {
if (not _config) {
return true;
}
_config->width = w;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_height(size_t h) {
if (not _config) {
return true;
}
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::resize(size_t w, size_t h) {
if (not _config) {
return true;
}
_config->width = w;
_config->height = h;
_surface->resize(_config->width, _config->height);
return false;
}
bool wayland_window::set_resizable(bool) {
return false; // TODO
}
bool wayland_window::set_fullscreen_mode(fullscreen_mode) {
return false; // TODO
}
bool wayland_window::grab_keyboard(bool) {
return false; // TODO
}
bool wayland_window::grab_mouse(bool) {
return false; // TODO
}
bool wayland_window::block_screensaver(bool) {
return false; // TODO
}
wayland_window::wayland_window(wayland_display* display, wayland_window* parent)
: window(display, parent, this)
, _handle()
, _shell()
, _nfs_width(0), _nfs_height(0) {
}
wayland_window::~wayland_window() {
wayland_window::shutdown();
}
}

View File

@@ -21,6 +21,7 @@
#include <fennec/platform/interface/display.h> #include <fennec/platform/interface/display.h>
#include <fennec/platform/interface/platform.h> #include <fennec/platform/interface/platform.h>
#include <fennec/platform/opengl/egl/context.h> #include <fennec/platform/opengl/egl/context.h>
#include <fennec/platform/opengl/egl/surface.h>
#include <GL/gl.h> #include <GL/gl.h>
@@ -40,7 +41,10 @@ STATIC_CONSTRUCTOR(_egl_init) {
} }
eglcontext::eglcontext(display* display) eglcontext::eglcontext(display* display)
: gfxcontext(display, "EGL", this) { : gfxcontext(display, "EGL", this)
, _egldisplay(nullptr), _eglcontext(nullptr)
, _eglconfig(), _eglvmajor(0), _eglvminor(0)
, _eglctype(0), _extensions(nullptr) {
// Get the display format // Get the display format
const display::pixel_format& fmt = _display->get_color_format(); const display::pixel_format& fmt = _display->get_color_format();
@@ -121,7 +125,7 @@ bool eglcontext::connected() {
return _eglcontext != nullptr; return _eglcontext != nullptr;
} }
const cstring& eglcontext::get_context_name() { const cstring& eglcontext::get_name() {
static constexpr cstring opengl = "OpenGL"; static constexpr cstring opengl = "OpenGL";
static constexpr cstring gles = "GLES"; static constexpr cstring gles = "GLES";
static constexpr cstring openvg = "OpenVG"; // this should never be used static constexpr cstring openvg = "OpenVG"; // this should never be used
@@ -137,8 +141,13 @@ bool eglcontext::check_extension(const cstring& ext) {
return _extensions.find(ext) != _extensions.size(); return _extensions.find(ext) != _extensions.size();
} }
void eglcontext::make_current(gfxsurface*) { gfxsurface* eglcontext::create_surface(window* window) {
return new eglsurface(this, window);
}
void eglcontext::make_current(gfxsurface* surface) {
eglsurface* eglsurface = static_cast<fennec::eglsurface*>(surface);
eglMakeCurrent(_egldisplay, eglsurface->get_egl_surface(), eglsurface->get_egl_surface(), _eglcontext);
} }
void eglcontext::cleanup() { void eglcontext::cleanup() {

View File

@@ -0,0 +1,66 @@
// =====================================================================================================================
// 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/opengl/egl/surface.h>
#include <fennec/platform/linux/wayland/lib/wayland.h>
namespace fennec
{
eglsurface::~eglsurface() {
if (_window->is_type<wayland_window>()) {
wl_egl_window_destroy(static_cast<wl_egl_window*>(_handle));
}
}
void eglsurface::resize(size_t width, size_t height) {
gfxsurface::resize(width, height);
if (_window->is_type<wayland_window>()) {
wl_egl_window_resize(static_cast<wl_egl_window*>(_handle), width, height, 0, 0);
}
}
eglsurface::eglsurface(eglcontext* context, window* window)
: gfxsurface(context, window, this)
, _handle(nullptr)
, _surface(nullptr) {
const window::config& config = window->get_config();
if (window->is_type<wayland_window>()) {
_handle = wl_egl_window_create(window->get_native_handle(), config.width, config.height);
}
assert(
_handle != nullptr,
"Failed to create egl window!"
);
eglCreateWindowSurface(
context->get_egl_display(),
context->get_egl_config(),
reinterpret_cast<EGLNativeWindowType>(_handle),
nullptr
);
assert(
EGL_TRUE == eglMakeCurrent(context->get_egl_display(), _surface, _surface, context->get_egl_context()),
"Failed to create egl window!"
);
}
}

View File

@@ -34,13 +34,33 @@ inline void fennec_test_platform() {
platform* instance = platform::instance(); platform* instance = platform::instance();
instance->initialize(); instance->initialize();
fennec_test_run(instance->get_display() != nullptr, true); display* display = instance->get_display();
fennec_test_run(instance->get_display()->get_context() != nullptr, true);
std::cout << instance->get_display()->get_context()->get_context_name() << " "; fennec_test_run(display != nullptr, true);
std::cout << instance->get_display()->get_context()->get_version_major() << "."; fennec_test_run(display->get_context() != nullptr, true);
std::cout << instance->get_display()->get_context()->get_version_minor() << std::endl;
gfxcontext* gfxcontext = display->get_context();
std::cout << gfxcontext->get_name() << " ";
std::cout << gfxcontext->get_version_major() << ".";
std::cout << gfxcontext->get_version_minor() << std::endl;
window::config winconfig = {
string{"fennec_test_platform"},
window::flags_none,
1280, 720,
window::fullscreen_mode::windowed
};
window* window = display->create_window(nullptr);
fennec_test_run(window != nullptr, true);
window->configure(winconfig);
window->initialize(false);
fennec_test_run(window->running(), true);
delete window;
instance->shutdown(); instance->shutdown();
} }