- Some underlying features for RTTI

- Macro for automatically generating this_t
 - Semantics with static_constructor.h, now FENNEC_PRIVATE_STATIC_CONSTRUCTOR for .cpp files and FENNEC_CLASS_STATIC_CONSTRUCTOR for a class in any source file type.
This commit is contained in:
2025-12-03 01:41:30 -05:00
parent 0b76b06a1b
commit d928d86014
28 changed files with 479 additions and 301 deletions

3
.gitmodules vendored
View File

@@ -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

View File

@@ -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)

View File

@@ -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()

View File

@@ -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 <https://www.gnu.org/licenses/>.
# ======================================================================================================================
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
)

120
cmake/wayland.cmake Normal file
View File

@@ -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://www.gnu.org/licenses/>.
# ======================================================================================================================
# 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()

58
cmake/xkb.cmake Normal file
View File

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

1
external/SDL vendored

Submodule external/SDL deleted from dee2414ee7

View File

@@ -55,6 +55,13 @@ public:
}
}
template<size_t I>
constexpr bitfield(const size_t (&arr)[I]) {
for (size_t i : arr) {
this->set(i);
}
}
template<typename...ArgsT>
constexpr bitfield(ArgsT&&...args) {
size_t i = 0;

View File

@@ -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() {
}
};
}

View File

@@ -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

View File

@@ -683,7 +683,7 @@ template<typename T> struct is_complete : detail::_is_complete<T>::type {};
/// \tparam T type to check
template<typename T> constexpr bool_t is_complete_v = is_complete<T>{};
// fennec::is_complete ==============================================================================================
// fennec::is_iterable ==============================================================================================
///
/// \brief check if type `T` is iterable
@@ -697,7 +697,7 @@ template<typename T> struct is_iterable : decltype(detail::_is_iterable<T>(0)) {
/// \tparam T type to check
template<typename T> constexpr bool_t is_iterable_v = is_iterable<T>{};
// fennec::is_complete ==============================================================================================
// fennec::is_indexable ==============================================================================================
///
/// \brief check if type `T` is indexable
@@ -711,7 +711,7 @@ template<typename T> struct is_indexable : decltype(detail::_is_indexable<T>(0))
/// \tparam T type to check
template<typename T> constexpr bool_t is_indexable_v = is_indexable<T>{};
// fennec::is_complete ==============================================================================================
// fennec::is_mappable ==============================================================================================
///
/// \brief check if type `T` is mappable

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <fennec/containers/bitfield.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
#include <fennec/rtti/enable.h>
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<feature_count>;
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

View File

@@ -22,6 +22,9 @@
namespace fennec
{
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
}

View File

@@ -25,6 +25,8 @@
#include <fennec/lang/strings/string.h>
#include <fennec/platform/interface/fwd.h>
#include <fennec/platform/interface/window.h>
#include <fennec/rtti/enable.h>
#include <fennec/rtti/detail/_this_t.h>
/*
* 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<typename ctor>
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_ctor>;
window* create_window(const window::config& config);
static void register_window_driver(window_driver&& driver);
protected:
template<typename PlatformT>
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<window_driver> windows;
global()
: singleton(nullptr)
, windows() {
}
} globals = global();
};
}

View File

@@ -33,120 +33,46 @@
#include <fennec/langcpp/types.h>
#include <fennec/lang/strings/string.h>
#include <fennec/containers/bitfield.h>
#include <fennec/renderers/interface/gfxcontext.h>
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<flag_count>;
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;
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:
};
}

View File

@@ -26,7 +26,7 @@ namespace fennec
class linux_platform : public unix_platform {
public:
linux_platform()
: unix_platform("linux", this) {
: unix_platform() {
}
void initialize() override;

View File

@@ -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 <fennec/platform/interface/window.h>
#ifndef FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H
#define FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H
#include <fennec/platform/interface/display_server.h>
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
#endif // FENNEC_PLATFORM_LINUX_WAYLAND_DISPLAY_SERVER_H

View File

@@ -26,9 +26,8 @@ namespace fennec
class unix_platform : public platform {
public:
template<typename PlatformT>
explicit unix_platform(const cstring& name, PlatformT* type)
: platform(name, type) {
explicit unix_platform()
: platform() {
}
shared_object* load_object(const cstring& file) override;

View File

@@ -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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
///
/// \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 <fennec/langcpp/type_transforms.h>
#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 <typename T>
struct reader
{
friend auto _test(reader<T>);
};
template <typename T, typename U>
struct writer
{
friend auto _test(reader<T>){return U{};}
};
inline void _test() {}
template <typename T>
using read = remove_pointer_t<decltype(_test(reader<T>{}))>;
};
#if FENNEC_COMPILER_GCC
#pragma GCC diagnostic pop
#endif
}
#endif // FENNEC_RTTI_DETAIL_THIS_T_H

View File

@@ -31,12 +31,19 @@
#ifndef FENNEC_RTTI_ENABLE_H
#define FENNEC_RTTI_ENABLE_H
#include <fennec/langcpp/static_constructor.h>
#include <fennec/rtti/type.h>
#include <fennec/rtti/typelist.h>
#define FENNEC_RTTI_ENABLE(...) \
#include <fennec/rtti/detail/_this_t.h>
#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

View File

@@ -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;
}
///

View File

@@ -33,7 +33,6 @@
#include <fennec/containers/bitfield.h>
#include <fennec/containers/dynarray.h>
#include <fennec/containers/optional.h>
#include <fennec/lang/strings/string.h>
#include <fennec/memory/pointers.h>
#include <fennec/rtti/typeid.h>
@@ -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;

View File

@@ -19,20 +19,9 @@
#ifndef FENNEC_SCENE_COMPONENT_H
#define FENNEC_SCENE_COMPONENT_H
#include <fennec/containers/dynarray.h>
#include <fennec/containers/map.h>
#include <fennec/containers/optional.h>
#include <fennec/containers/rdtree.h>
#include <fennec/langcpp/startup.h>
#include <fennec/lang/strings/string.h>
#include <fennec/lang/filesystem/path.h>
#include <fennec/scene/forward.h>
#define FENNEC_REGISTER_COMPONENT(T, p) \
FENNEC_STATIC_CONSTRUCTOR(T) { \
component::register_type<T>(p) \
}
#include <fennec/rtti/enable.h>
namespace fennec
{
@@ -47,6 +36,9 @@ public:
component(scene_node* node)
: node(node) {
}
FENNEC_RTTI_CLASS_ENABLE() {
}
};
}

View File

@@ -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 {

View File

@@ -31,10 +31,11 @@
#ifndef FENNEC_SCENE_NODE_H
#define FENNEC_SCENE_NODE_H
#include <fennec/scene/component.h>
#include <fennec/lang/strings/string.h>
#include <fennec/scene/scene.h>
#include <fennec/scene/component.h>
#include <fennec/rtti/enable.h>
namespace fennec
{
@@ -56,7 +57,8 @@ public:
private:
dynarray<component*> _components;
FENNEC_RTTI_ENABLE();
FENNEC_RTTI_CLASS_ENABLE() {
}
};
}

View File

@@ -21,32 +21,10 @@
namespace fennec
{
template<typename CtorT>
static constexpr void insert_driver(list<platform::driver<CtorT>>& drvrs, CtorT ctor, int priority) {
using list_t = list<platform::driver<CtorT>>;
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<window_driver>(driver));
}
}

View File

@@ -19,12 +19,12 @@
#include <fennec/lang/filesystem/file.h>
#include <fennec/platform/linux/platform.h>
#include <fennec/langcpp/startup.h>
#include <fennec/langcpp/static_constructor.h>
namespace fennec
{
FENNEC_STATIC_CONSTRUCTOR(_init_linux) {
FENNEC_PRIVATE_STATIC_CONSTRUCTOR(_init_linux) {
static linux_platform platform;
}

View File

@@ -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() {