diff --git a/.gitmodules b/.gitmodules index f3bdc37..0a15db9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "external/cpptrace"] path = external/cpptrace url = https://github.com/jeremy-rifkin/cpptrace.git -[submodule "external/SDL"] - path = external/SDL - url = https://github.com/libsdl-org/SDL diff --git a/CMakeLists.txt b/CMakeLists.txt index cd46d65..07e1206 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,6 @@ endmacro() # External dependencies should be loaded here add_subdirectory(external/cpptrace) -include("${FENNEC_SOURCE_DIR}/cmake/sdl.cmake") set(CMAKE_CXX_STANDARD 23) set(CMAKE_C_STANDARD 23) @@ -144,7 +143,7 @@ add_library(fennec STATIC include/fennec/langcpp/limits.h include/fennec/langcpp/numeric_transforms.h include/fennec/langcpp/metasequences.h - include/fennec/langcpp/startup.h + include/fennec/langcpp/static_constructor.h include/fennec/langcpp/type_identity.h include/fennec/langcpp/type_operators.h include/fennec/langcpp/type_sequences.h @@ -266,6 +265,9 @@ add_library(fennec STATIC include/fennec/langcpp/declval.h include/fennec/langcpp/detail/_declval.h include/fennec/containers/bitfield.h + include/fennec/platform/interface/display_server.h + include/fennec/rtti/detail/_this_t.h + include/fennec/platform/linux/wayland/display_server.h ) add_dependencies(fennec metaprogramming fennec-dependencies) diff --git a/cmake/linux.cmake b/cmake/linux.cmake index 30bac9d..9335ad8 100644 --- a/cmake/linux.cmake +++ b/cmake/linux.cmake @@ -34,6 +34,9 @@ macro(fennec_check_platform) ) if(FENNEC_USER_CLIENT) + include("${FENNEC_SOURCE_DIR}/cmake/wayland.cmake") + + fennec_check_wayland() fennec_init_graphics() endif() diff --git a/cmake/sdl.cmake b/cmake/sdl.cmake deleted file mode 100644 index 8978848..0000000 --- a/cmake/sdl.cmake +++ /dev/null @@ -1,30 +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 . -# ====================================================================================================================== - -set(SDL_AUDIO OFF) -set(SDL_RENDER OFF) -add_subdirectory(${FENNEC_SOURCE_DIR}/external/SDL) - -fennec_add_sources( - include/fennec/platform/sdl/sdlwindow.h -) - -fennec_add_shared_libraries( - SDL3::SDL3-shared -) - diff --git a/cmake/wayland.cmake b/cmake/wayland.cmake new file mode 100644 index 0000000..5280e2c --- /dev/null +++ b/cmake/wayland.cmake @@ -0,0 +1,120 @@ +# ====================================================================================================================== +# 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://gist.github.com/mariobadr/acc3c8adf4b4e722705be38c3deac59a +# 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") + set(_WAYLAND_PROT_C_CODE "${WAYLAND_SOURCES_DIR}/${_FILE}-client.c") + + execute_process( + COMMAND ${_SCANNER} client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}" + ) + + execute_process( + COMMAND ${_SCANNER} private-code "${_XML}" "${_WAYLAND_PROT_C_CODE}" + ) + + fennec_add_sources(${_WAYLAND_PROT_C_CODE} ${_WAYLAND_PROT_H_CODE}) +endmacro() + +macro(fennec_check_wayland) + 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 + ) + find_program(WAYLAND_SCANNER NAMES wayland-scanner) + + # EGL is required + find_path( + WAYLAND_EGL_INCLUDE_DIR + NAMES wayland-egl.h + ) + find_library( + WAYLAND_EGL_LIBRARY + NAMES wayland-egl libwayland-egl + ) + + if( (WAYLAND_CLIENT_INCLUDE_DIR AND WAYLAND_CLIENT_LIBRARY AND WAYLAND_SCANNER) + AND (WAYLAND_EGL_INCLUDE_DIR AND WAYLAND_EGL_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) + set(WAYLAND_SOURCES_DIR ${FENNEC_SOURCE_DIR}/source/platform/linux/wayland/lib/sources) + + # 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}) + + # search for xdg protocols + find_file(XDG_SHELL_PROTOCOL NAMES xdg-shell.xml PATHS /usr/share/wayland-protocols/stable/xdg-shell) + file(COPY ${XDG_SHELL_PROTOCOL} DESTINATION ${WAYLAND_PROTOCOLS_DIR}) + + # include sub-dependencies + include("${FENNEC_SOURCE_DIR}/cmake/xkb.cmake") + 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( + WAYLAND_CLIENT_LIBRARY + ${WAYLAND_CLIENT_LIBRARY} + NAME + ) + get_filename_component( + WAYLAND_EGL_LIBRARY + ${WAYLAND_EGL_LIBRARY} + NAME + ) + + set(WAYLAND_CLIENT_FOUND 1) + set(WAYLAND_EGL_FOUND 1) + set(FENNEC_GRAPHICS_WANT_EGL 1) + + fennec_add_sources( + # Dynamic Library Files + include/fennec/platform/linux/wayland/lib/sym.h + include/fennec/platform/linux/wayland/lib/wayland.h + include/fennec/platform/linux/wayland/lib/loader.h source/platform/linux/wayland/lib/loader.cpp + + # Fennec Files + ) + + fennec_add_definitions( + FENNEC_HAS_WAYLAND=1 + FENNEC_LIB_WAYLAND="${WAYLAND_CLIENT_LIBRARY}" + FENNEC_LIB_WAYLAND_EGL="${WAYLAND_EGL_LIBRARY}" + ) + endif() +endmacro() \ No newline at end of file diff --git a/cmake/xkb.cmake b/cmake/xkb.cmake new file mode 100644 index 0000000..c53d3f2 --- /dev/null +++ b/cmake/xkb.cmake @@ -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 . +# ====================================================================================================================== + +# this script finds libxkbcommon and dependencies + +macro(fennec_check_xkb) + set(XKB_FOUND 0) + + find_path( + XKB_INCLUDE_DIR + NAMES xkbcommon/xkbcommon.h + ) + find_library( + XKB_LIBRARY + NAMES xkbcommon libxkbcommon + ) + + if(XKB_INCLUDE_DIR AND XKB_LIBRARY) + message(STATUS "Found XKB: ${XKB_LIBRARY}") + + get_filename_component( + XKB_LIBRARY + ${XKB_LIBRARY} + NAME + ) + + set(XKB_FOUND 1) + + fennec_add_sources( + # Dynamic Library Files + include/fennec/platform/linux/xkb/lib/sym.h + include/fennec/platform/linux/xkb/lib/xkb.h + include/fennec/platform/linux/xkb/lib/loader.h source/platform/linux/xkb/lib/loader.cpp + + # Fennec files + ) + + fennec_add_definitions( + FENNEC_HAS_XKB=1 + FENNEC_LIB_XKB="${XKB_LIBRARY}" + ) + endif() +endmacro() \ No newline at end of file diff --git a/external/SDL b/external/SDL deleted file mode 160000 index dee2414..0000000 --- a/external/SDL +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dee2414ee7759c709162eabad4e53cfe47c8cdd4 diff --git a/include/fennec/containers/bitfield.h b/include/fennec/containers/bitfield.h index 9c4ebc5..a91dd7a 100644 --- a/include/fennec/containers/bitfield.h +++ b/include/fennec/containers/bitfield.h @@ -55,6 +55,13 @@ public: } } + template + constexpr bitfield(const size_t (&arr)[I]) { + for (size_t i : arr) { + this->set(i); + } + } + template constexpr bitfield(ArgsT&&...args) { size_t i = 0; diff --git a/include/fennec/core/event.h b/include/fennec/core/event.h index cb51316..2fc9cc5 100644 --- a/include/fennec/core/event.h +++ b/include/fennec/core/event.h @@ -60,7 +60,9 @@ struct event { static void remove_listener(event_listener* listener); static void dispatch(event* event); - FENNEC_RTTI_ENABLE(); + FENNEC_RTTI_CLASS_ENABLE() { + + } }; } diff --git a/include/fennec/langcpp/startup.h b/include/fennec/langcpp/static_constructor.h similarity index 86% rename from include/fennec/langcpp/startup.h rename to include/fennec/langcpp/static_constructor.h index 9f299b4..c444cd8 100644 --- a/include/fennec/langcpp/startup.h +++ b/include/fennec/langcpp/static_constructor.h @@ -20,9 +20,13 @@ #define FENNEC_LANG_STARTUP_H // Helper for running a function before main() -#define FENNEC_STATIC_CONSTRUCTOR(f) \ +#define FENNEC_PRIVATE_STATIC_CONSTRUCTOR(f) \ inline static void f(void); \ struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \ inline static void f(void) +#define FENNEC_CLASS_STATIC_CONSTRUCTOR(f) \ + struct f##_t_ { inline f##_t_(void) { f(); } }; inline static f##_t_ f##_; \ + inline static void f(void) + #endif // FENNEC_LANG_STARTUP_H diff --git a/include/fennec/langcpp/type_traits.h b/include/fennec/langcpp/type_traits.h index dc9970c..a121162 100644 --- a/include/fennec/langcpp/type_traits.h +++ b/include/fennec/langcpp/type_traits.h @@ -683,7 +683,7 @@ template struct is_complete : detail::_is_complete::type {}; /// \tparam T type to check template constexpr bool_t is_complete_v = is_complete{}; -// fennec::is_complete ============================================================================================== +// fennec::is_iterable ============================================================================================== /// /// \brief check if type `T` is iterable @@ -697,7 +697,7 @@ template struct is_iterable : decltype(detail::_is_iterable(0)) { /// \tparam T type to check template constexpr bool_t is_iterable_v = is_iterable{}; -// fennec::is_complete ============================================================================================== +// fennec::is_indexable ============================================================================================== /// /// \brief check if type `T` is indexable @@ -711,7 +711,7 @@ template struct is_indexable : decltype(detail::_is_indexable(0)) /// \tparam T type to check template constexpr bool_t is_indexable_v = is_indexable{}; -// fennec::is_complete ============================================================================================== +// fennec::is_mappable ============================================================================================== /// /// \brief check if type `T` is mappable diff --git a/include/fennec/platform/interface/display_server.h b/include/fennec/platform/interface/display_server.h new file mode 100644 index 0000000..7022bdf --- /dev/null +++ b/include/fennec/platform/interface/display_server.h @@ -0,0 +1,114 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +/// +/// \file display_server.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_DISPLAY_SERVER_H +#define FENNEC_PLATFORM_INTERFACE_DISPLAY_SERVER_H + +#include +#include +#include +#include + +namespace fennec +{ + +class display_server { +// Typedefs/Constants/Enums ============================================================================================ +public: + +enum feature_ : uint32_t { + feature_subwindows = 0, + feature_icon, + + feature_window_drag, + + feature_mouse, + feature_cursors, + feature_custom_cursors, + + feature_clipboard, + feature_clipboard_primary, + feature_virtual_keyboard, + + feature_status_indicators, + feature_dialogues, + feature_input_dialogues, + feature_file_dialogues, + feature_filtered_file_dialogues, + + feature_orientation, + feature_hidpi, + feature_hdr, + feature_swap_buffers, + feature_window_transparency, + + feature_screen_reader, + feature_text_to_speech, + feature_touchscreen, + feature_system_theme, + + feature_count, + }; + + using featureset_t = bitfield; + + struct config { + }; + + +// Public Members ====================================================================================================== + platform* const platform; + + explicit display_server(fennec::platform* p) + : platform(p) { + } + + virtual ~display_server() = default; + + + bool has_feature(uint32_t feature) const { + return _features.test(feature); + } + + + virtual window* create_window(const window::config& conf) = 0; + + +private: + featureset_t _features; + + FENNEC_RTTI_CLASS_ENABLE() { + + } +}; + +} + +#endif // FENNEC_PLATFORM_INTERFACE_DISPLAY_SERVER_H \ No newline at end of file diff --git a/include/fennec/platform/interface/fwd.h b/include/fennec/platform/interface/fwd.h index a183523..07d4151 100644 --- a/include/fennec/platform/interface/fwd.h +++ b/include/fennec/platform/interface/fwd.h @@ -22,7 +22,10 @@ namespace fennec { -class window; // Handles window surfaces of the display protocol +class platform; + +class display_server; // The display server used by the OS, e.g. WDM, Wayland, X11, etc. +class window; // Handles window surfaces of the display protocol } diff --git a/include/fennec/platform/interface/platform.h b/include/fennec/platform/interface/platform.h index 313bad1..681d0ca 100644 --- a/include/fennec/platform/interface/platform.h +++ b/include/fennec/platform/interface/platform.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include /* * This class should resemble the target platform as a whole. By itself, it will represent the OS, i.e. Linux, Windows, @@ -65,50 +67,7 @@ public: using shared_object = struct shared_object; using symbol = void*; - template - struct driver { - int priority; - ctor constructor; - - driver() - : priority(0) - , constructor(nullptr) { - } - - driver(int priority, ctor constructor) - : priority(priority) - , constructor(constructor) { - } - - driver(const driver& d) - : priority(d.priority) - , constructor(d.constructor) { - } - - driver(driver&& d) noexcept - : priority(d.priority) - , constructor(d.constructor) { - } - - driver& operator=(const driver& d) { - priority = d.priority; - constructor = d.constructor; - return *this; - } - - driver& operator=(driver&& d) noexcept { - priority = fennec::move(d.priority); - constructor = fennec::move(d.constructor); - return *this; - } - - bool operator<(const driver& d) const { - return priority > d.priority; - } - }; - - const string name; - + platform() = default; virtual ~platform() = default; platform(const platform&) = delete; @@ -120,39 +79,9 @@ public: virtual void initialize(); // Initialize Drivers and Contexts virtual void shutdown(); // Close Drivers and Contexts -// Platform level functions for retrieving driver and protocol contexts ================================================ + FENNEC_RTTI_CLASS_ENABLE() { - // Window Management - using window_ctor = window* (*)(platform*, const window::config&); - using window_driver = driver; - window* create_window(const window::config& config); - static void register_window_driver(window_driver&& driver); - -protected: - template - explicit platform(const cstring& name, PlatformT*) - : name(name) { - assertf(globals.singleton == nullptr, "Conflicting platform implementations!"); - globals.singleton = this; } - -// Static Stuff ======================================================================================================== - -public: - static platform* instance() { - return globals.singleton; - } - -private: - inline static struct global { - platform* singleton; - sequence windows; - - global() - : singleton(nullptr) - , windows() { - } - } globals = global(); }; } diff --git a/include/fennec/platform/interface/window.h b/include/fennec/platform/interface/window.h index a32deab..9ccbbf4 100644 --- a/include/fennec/platform/interface/window.h +++ b/include/fennec/platform/interface/window.h @@ -33,120 +33,46 @@ #include #include +#include #include namespace fennec { class window { +// Structures & Typedefs =============================================================================================== public: - virtual ~window() = default; + enum flag_ { + flag_always_on_top = 0, // Window always appears on top level + flag_borderless, // Window has no border decorations + flag_child, // Window is a child window, and closes when the parent does + flag_decorations, // Window has a titlebar with basic functions + flag_modal, // Window always appears above parent and blocks input going to parent + flag_pass_mouse, // Mouse interaction passes to next underlying window in the application + flag_popup, // Window does not show in taskbar and closes when loses focus + flag_resizable, // Window can be resized through functions defined by Desktop Environment + flag_transparent, // Window has an alpha value + flag_visible, // Window is visible + flag_no_focus, // Window can be focused - enum flags : uint8_t { - fullscreen = 0x1 << 0, - borderless = 0x1 << 1, - resizeable = 0x1 << 2, - modal = 0x1 << 3, // Treat as modal, blocks interaction with parent windows - popup = 0x1 << 4, // Treat as a popup menu - tooltip = 0x1 << 5, // Treat as a tooltip, does not receive mouse or keyboard focus - utility = 0x1 << 6, // Treat as utility, does not show in taskbar + flag_count }; - enum vsync { - vsync_off = 0, - vsync_on = 1, - adaptive_sync = -1, - }; + using flags_t = bitfield; - struct pixel_format { - uint8_t r, g, b, a; - bool floating_point; - }; - - struct display_mode { - pixel_format format; - float rate; - float density; + struct accessibility { + string name, description; }; struct config { - uint8_t flags; - display_mode mode; - string title; - int8_t vsync; + string title; + flags_t flags; + + ivec2 size; + + accessibility accessibility; }; -// Properties ========================================================================================================== - - virtual bool running() = 0; - - bool is_fullscreen() const { - return _config.flags & fullscreen; - } - - bool is_borderless() const { - return _config.flags & borderless; - } - - bool is_modal() const { - return _config.flags & modal; - } - - bool is_resizeable() const { - return _config.flags & resizeable; - } - - const display_mode& get_mode() const { - return _config.mode; - } - - const pixel_format& get_format() const { - return _config.mode.format; - } - - bool is_hdr() const { - static constexpr size_t sdr = 255ull * 255ull * 255ull; - const pixel_format& fmt = _config.mode.format; - return fmt.r * fmt.g * fmt.b > sdr; - } - - const config& get_config() const { - return _config; - } - -// Modifiers =========================================================================================================== - - virtual void resize(size_t, size_t) = 0; - virtual void position(size_t, size_t) = 0; - - virtual void set_fullscreen(bool) = 0; - virtual void set_borderless(bool) = 0; - - virtual void grab_mouse(bool) = 0; - virtual void grab_keyboard(bool) = 0; - - virtual void set_title(const cstring&) = 0; - virtual void set_title(const string&) = 0; - virtual void set_progress(bool, float) = 0; - - virtual void vsync(int8_t) = 0; - -// Graphics ============================================================================================================ - - virtual void begin_frame() = 0; - virtual void end_frame() = 0; - -protected: - window* _parent; - gfxcontext* _context; - config _config; - - window(window* parent, const config& cfg) - : _parent(parent) - , _config(cfg) { - } - -private: }; } diff --git a/include/fennec/platform/linux/platform.h b/include/fennec/platform/linux/platform.h index e55ef57..7aad820 100644 --- a/include/fennec/platform/linux/platform.h +++ b/include/fennec/platform/linux/platform.h @@ -26,7 +26,7 @@ namespace fennec class linux_platform : public unix_platform { public: linux_platform() - : unix_platform("linux", this) { + : unix_platform() { } void initialize() override; diff --git a/include/fennec/platform/sdl/sdlwindow.h b/include/fennec/platform/linux/wayland/display_server.h similarity index 64% rename from include/fennec/platform/sdl/sdlwindow.h rename to include/fennec/platform/linux/wayland/display_server.h index a7685e9..ade6a07 100644 --- a/include/fennec/platform/sdl/sdlwindow.h +++ b/include/fennec/platform/linux/wayland/display_server.h @@ -17,7 +17,7 @@ // ===================================================================================================================== /// -/// \file sdlwindow.h +/// \file display_server.h /// \brief /// /// @@ -28,40 +28,25 @@ /// /// -#ifndef FENNEC_PLATFORM_SDL_SDLWINDOW_H -#define FENNEC_PLATFORM_SDL_SDLWINDOW_H - -#include +#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H +#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H +#include namespace fennec { -class sdlwindow : public window { +class wayland_server : display_server { public: - sdlwindow(window* parent, const config& cfg); - - bool running() override; - - void set_fullscreen(bool) override; - void set_borderless(bool) override; - - void grab_mouse(bool) override; - void grab_keyboard(bool) override; - - void set_title(const cstring&) override; - void set_title(const string&) override; - void set_progress(bool, float) override; - - void vsync(int8_t) override; - - - void begin_frame() override; - void end_frame() override; + explicit wayland_server(fennec::platform* p) + : display_server(p) { + } private: + FENNEC_RTTI_CLASS_ENABLE(display_server) { + } }; } -#endif // FENNEC_PLATFORM_SDL_SDLWINDOW_H \ No newline at end of file +#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H diff --git a/include/fennec/platform/unix/platform.h b/include/fennec/platform/unix/platform.h index c3acea4..6e56892 100644 --- a/include/fennec/platform/unix/platform.h +++ b/include/fennec/platform/unix/platform.h @@ -26,9 +26,8 @@ namespace fennec class unix_platform : public platform { public: - template - explicit unix_platform(const cstring& name, PlatformT* type) - : platform(name, type) { + explicit unix_platform() + : platform() { } shared_object* load_object(const cstring& file) override; diff --git a/include/fennec/rtti/detail/_this_t.h b/include/fennec/rtti/detail/_this_t.h new file mode 100644 index 0000000..fb85273 --- /dev/null +++ b/include/fennec/rtti/detail/_this_t.h @@ -0,0 +1,77 @@ +// ===================================================================================================================== +// 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 . +// ===================================================================================================================== + +/// +/// \file _this_t.h +/// \brief +/// +/// +/// \details +/// \author Medusa Slockbower +/// +/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html)) +/// +/// + +#ifndef FENNEC_RTTI_DETAIL_THIS_T_H +#define FENNEC_RTTI_DETAIL_THIS_T_H +#include + +#define FENNEC_DEFINE_THIS_T \ +private: \ + struct _this_t_tag {}; \ + constexpr auto _this_t_helper() -> decltype(fennec::detail::_this::writer<_this_t_tag, decltype(this)>{}, void()) {} \ +public: \ + using this_t = fennec::detail::_this::read<_this_t_tag> + +namespace fennec::detail +{ + +// https://stackoverflow.com/a/70701479 + +#if FENNEC_COMPILER_GCC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-template-friend" +#endif + +namespace _this { + template + struct reader + { + friend auto _test(reader); + }; + + template + struct writer + { + friend auto _test(reader){return U{};} + }; + + inline void _test() {} + + template + using read = remove_pointer_t{}))>; +}; + +#if FENNEC_COMPILER_GCC +#pragma GCC diagnostic pop +#endif + +} + +#endif // FENNEC_RTTI_DETAIL_THIS_T_H \ No newline at end of file diff --git a/include/fennec/rtti/enable.h b/include/fennec/rtti/enable.h index 4e26aae..3980399 100644 --- a/include/fennec/rtti/enable.h +++ b/include/fennec/rtti/enable.h @@ -31,12 +31,19 @@ #ifndef FENNEC_RTTI_ENABLE_H #define FENNEC_RTTI_ENABLE_H +#include + #include #include -#define FENNEC_RTTI_ENABLE(...) \ +#include + +#define FENNEC_RTTI_CLASS_ENABLE(...) \ public: \ using super_class_list = fennec::typelist<__VA_ARGS__>; \ - virtual fennec::type get_type() { return fennec::type::get_from_instance(this); } + virtual fennec::type get_type() { return fennec::type::get_from_instance(this); } \ + FENNEC_DEFINE_THIS_T; \ +private: \ + FENNEC_CLASS_STATIC_CONSTRUCTOR(_init_reflection) #endif // FENNEC_RTTI_ENABLE_H \ No newline at end of file diff --git a/include/fennec/rtti/type.h b/include/fennec/rtti/type.h index 132493c..ad4c812 100644 --- a/include/fennec/rtti/type.h +++ b/include/fennec/rtti/type.h @@ -67,25 +67,25 @@ struct type { /// /// \returns `true` if this is a complete type, false otherwise bool is_complete() const { - return _data ? _data->properties.test(type_prop_complete) : false; + return _data ? _data->properties.test(type_data::property_complete) : false; } /// /// \returns `true` if this type fulfills the [C++11 range-initializer](https://en.cppreference.com/w/cpp/language/range-for.html), false otherwise bool is_iterable() const { - return _data ? _data->properties.test(type_prop_iterable) : false; + return _data ? _data->properties.test(type_data::property_iterable) : false; } /// /// \returns `true` if this type implements `operator[]` with a single parameter of integral type, false otherwise bool is_indexable() const { - return _data ? _data->properties.test(type_prop_indexable) : false; + return _data ? _data->properties.test(type_data::property_indexable) : false; } /// /// \returns `true` if this type implements `operator[]` with a single parameter of type `type::key_t` bool is_mappable() const { - return _data ? _data->properties.test(type_prop_mappable) : false; + return _data ? _data->properties.test(type_data::property_mappable) : false; } /// diff --git a/include/fennec/rtti/type_data.h b/include/fennec/rtti/type_data.h index ae1a748..7a6b8d2 100644 --- a/include/fennec/rtti/type_data.h +++ b/include/fennec/rtti/type_data.h @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -43,14 +42,13 @@ namespace fennec { -enum type_prop_ { - type_prop_complete = 0, - type_prop_iterable, - type_prop_indexable, - type_prop_mappable, -}; - struct type_data { + enum property_ { + property_complete = 0, + property_iterable, + property_indexable, + property_mappable, + }; uint64_t uuid; string name; diff --git a/include/fennec/scene/component.h b/include/fennec/scene/component.h index f43c448..a2f63db 100644 --- a/include/fennec/scene/component.h +++ b/include/fennec/scene/component.h @@ -19,20 +19,9 @@ #ifndef FENNEC_SCENE_COMPONENT_H #define FENNEC_SCENE_COMPONENT_H -#include -#include -#include -#include -#include -#include -#include - #include -#define FENNEC_REGISTER_COMPONENT(T, p) \ - FENNEC_STATIC_CONSTRUCTOR(T) { \ - component::register_type(p) \ - } +#include namespace fennec { @@ -47,6 +36,9 @@ public: component(scene_node* node) : node(node) { } + + FENNEC_RTTI_CLASS_ENABLE() { + } }; } diff --git a/include/fennec/scene/node2d.h b/include/fennec/scene/node2d.h index 635b5fe..9063c09 100644 --- a/include/fennec/scene/node2d.h +++ b/include/fennec/scene/node2d.h @@ -47,7 +47,9 @@ struct node2d; struct transform_update_2d : event { node2d* node; - FENNEC_RTTI_ENABLE(event); + FENNEC_RTTI_CLASS_ENABLE(event) { + + } }; struct node2d : scene_node { diff --git a/include/fennec/scene/scene_node.h b/include/fennec/scene/scene_node.h index 89e0e1a..4cf0c95 100644 --- a/include/fennec/scene/scene_node.h +++ b/include/fennec/scene/scene_node.h @@ -31,10 +31,11 @@ #ifndef FENNEC_SCENE_NODE_H #define FENNEC_SCENE_NODE_H +#include + #include -#include -#include +#include namespace fennec { @@ -56,7 +57,8 @@ public: private: dynarray _components; - FENNEC_RTTI_ENABLE(); + FENNEC_RTTI_CLASS_ENABLE() { + } }; } diff --git a/source/platform/interface/platform.cpp b/source/platform/interface/platform.cpp index c472875..d070600 100644 --- a/source/platform/interface/platform.cpp +++ b/source/platform/interface/platform.cpp @@ -21,32 +21,10 @@ namespace fennec { -template -static constexpr void insert_driver(list>& drvrs, CtorT ctor, int priority) { - using list_t = list>; - using iter_t = typename list_t::iterator; - - iter_t it = drvrs.begin(); - while (it != drvrs.end()) { - if (priority >= it->priority) { - break; - } - } - drvrs.insert(it, { priority, ctor }); -} - void platform::initialize() { } void platform::shutdown() { } -window* platform::create_window(const window::config&) { - return nullptr; -} - -void platform::register_window_driver(window_driver&& driver) { - globals.windows.insert(fennec::forward(driver)); -} - } diff --git a/source/platform/linux/platform.cpp b/source/platform/linux/platform.cpp index 74a1f8f..fafe902 100644 --- a/source/platform/linux/platform.cpp +++ b/source/platform/linux/platform.cpp @@ -19,12 +19,12 @@ #include #include -#include +#include namespace fennec { -FENNEC_STATIC_CONSTRUCTOR(_init_linux) { +FENNEC_PRIVATE_STATIC_CONSTRUCTOR(_init_linux) { static linux_platform platform; } diff --git a/test/tests/test_rtti.h b/test/tests/test_rtti.h index 30ee499..e97f521 100644 --- a/test/tests/test_rtti.h +++ b/test/tests/test_rtti.h @@ -44,11 +44,15 @@ namespace fennec::test { struct rtti_test_base { - FENNEC_RTTI_ENABLE(); + FENNEC_RTTI_CLASS_ENABLE() { + + } }; struct rtti_test_sub : rtti_test_base { - FENNEC_RTTI_ENABLE(rtti_test_base); + FENNEC_RTTI_CLASS_ENABLE(rtti_test_base) { + + } }; inline void fennec_test_rtti() {