From e64f5f634796a6dab64433f9157879098e05d8d8 Mon Sep 17 00:00:00 2001 From: Toyosatomimi no Miko <110693261+mikomikotaishi@users.noreply.github.com> Date: Thu, 29 May 2025 12:46:43 -0400 Subject: [PATCH] Add support for C++20 modules --- CMakeLists.txt | 14 +++ README.md | 18 ++++ include/raymath.hpp | 2 + modules/CMakeLists.txt | 30 ++++++ modules/raylib.cppm | 211 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 275 insertions(+) create mode 100644 modules/CMakeLists.txt create mode 100644 modules/raylib.cppm diff --git a/CMakeLists.txt b/CMakeLists.txt index f637e9d5..8dfa16bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,20 @@ option(BUILD_RAYLIB_CPP_EXAMPLES "Examples" ${RAYLIB_CPP_IS_MAIN}) # Include Directory add_subdirectory(include) +# Modules +option(BUILD_RAYLIB_CPP_MODULES "Build C++ modules support" OFF) + +if(BUILD_RAYLIB_CPP_MODULES) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) + message(STATUS "Building raylib-cpp C++ modules (CMake ${CMAKE_VERSION} supports modules)") + add_subdirectory(modules) + else() + message(WARNING "Skipping raylib-cpp C++ modules (requires CMake 3.28+, found ${CMAKE_VERSION})") + endif() +else() + message(STATUS "raylib-cpp C++ modules support is disabled. Enable with -BUILD_RAYLIB_CPP_MODULES=ON") +endif() + # Examples if(BUILD_RAYLIB_CPP_EXAMPLES) add_subdirectory(examples) diff --git a/README.md b/README.md index 70566007..ef8e9d3c 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,24 @@ raylib::Vector2 direction(50, 50); raylib::Vector2 newDirection = direction.Rotate(30); ``` +### Modules + +If using C++20 or later, by passing `BUILD_RAYLIB_CPP_MODULES` to the build system the library may be imported as a module by using `import raylib;`. + +```cpp +import raylib; + +int main() { + int screenWidth = 800; + int screenHeight = 450; + + raylib::Window window(screenWidth, screenHeight, "raylib-cpp - basic window"); + raylib::Texture logo("raylib_logo.png"); + + // ... +} +``` + ## Getting Started *raylib-cpp* is a header-only library. This means in order to use it, you must link your project to [raylib](https://www.raylib.com/), and then include [`raylib-cpp.hpp`](raylib-cpp/include/raylib-cpp.hpp). diff --git a/include/raymath.hpp b/include/raymath.hpp index f166488e..41e37cf3 100644 --- a/include/raymath.hpp +++ b/include/raymath.hpp @@ -8,9 +8,11 @@ extern "C" { #endif #ifndef RAYLIB_CPP_NO_MATH +#ifndef BUILD_RAYLIB_CPP_MODULES #ifndef RAYMATH_STATIC_INLINE #define RAYMATH_STATIC_INLINE #endif +#endif #ifdef __GNUC__ #pragma GCC diagnostic push // These throw a warnings on visual studio, need to check if __GNUC__ is defined to use it. #pragma GCC diagnostic ignored "-Wmissing-field-initializers" diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 00000000..b61a34fd --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,30 @@ +file(GLOB_RECURSE RAYLIB_CPP_MODULES raylib.cppm) + +add_library(raylib_cpp_modules) + +cmake_minimum_required(VERSION 3.28) + +if(NOT COMMAND configure_cpp_module_target) + function(configure_cpp_module_target target) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.28) + target_sources(${target} PUBLIC FILE_SET CXX_MODULES FILES ${RAYLIB_CPP_MODULES}) + else() + message(WARNING "C++ modules require CMake 3.28+. Using standard compilation.") + target_sources(${target} PRIVATE ${RAYLIB_CPP_MODULES}) + endif() + endfunction() +endif() + +configure_cpp_module_target(raylib_cpp_modules) + +target_link_libraries(raylib_cpp_modules + PUBLIC + raylib_cpp +) + +target_include_directories(raylib_cpp_modules + PRIVATE + ${PROJECT_SOURCE_DIR}/include +) + +target_compile_features(raylib_cpp_modules PUBLIC cxx_std_20) \ No newline at end of file diff --git a/modules/raylib.cppm b/modules/raylib.cppm new file mode 100644 index 00000000..2fcea73d --- /dev/null +++ b/modules/raylib.cppm @@ -0,0 +1,211 @@ +/** + * @file raylib.cppm + * @brief Module file exporting all symbols in raylib-cpp. + */ + +module; + +#define BUILD_RAYLIB_CPP_MODULES +#define RLCPPAPI +#define RAYMATH_IMPLEMENTATION +#include "../include/raylib-cpp.hpp" + +export module raylib; + +/** + * @namespace raylib + * @brief All raylib-cpp classes and functions appear in the raylib namespace. + */ +export namespace raylib { + // Classes + using raylib::AudioDevice; + using raylib::AudioStream; + using raylib::AutomationEventList; + using raylib::BoundingBox; + using raylib::Camera; // Alias for Camera3D + using raylib::Camera2D; + using raylib::Camera3D; + using raylib::Color; + using raylib::FileData; + using raylib::FileText; + using raylib::Font; + using raylib::Gamepad; + using raylib::Image; + using raylib::Material; + using raylib::Matrix; + using raylib::Mesh; + using raylib::Model; + using raylib::ModelAnimation; + using raylib::Music; + using raylib::Ray; + using raylib::RayCollision; + using raylib::RaylibException; + using raylib::Rectangle; + using raylib::RenderTexture; + using raylib::RenderTexture2D; // Alias for RenderTexture + using raylib::Shader; + using raylib::Sound; + using raylib::Text; + using raylib::Texture; + using raylib::Texture2D; // Alias for Texture + using raylib::TextureCubemap; // Alias for Texture + using raylib::TextureUnmanaged; + using raylib::Texture2DUnmanaged; // Alias for TextureUnmanaged + using raylib::TextureCubemapUnmanaged; // Alias for TextureUnmanaged + using raylib::Vector2; + using raylib::Vector3; + using raylib::Vector4; + using raylib::Quaternion; // Alias for Vector4 + using raylib::VrStereoConfig; + using raylib::Wave; + using raylib::Window; + + // From Functions.hpp + using raylib::InitWindow; + using raylib::SetWindowTitle; + using raylib::GetMonitorName; + using raylib::SetClipboardText; + using raylib::GetClipboardText; + using raylib::TakeScreenshot; + using raylib::GetGamepadName; + using raylib::LoadFileText; + using raylib::SaveFileText; + using raylib::FileExists; + using raylib::DirectoryExists; + using raylib::IsFileExtension; + using raylib::GetFileExtension; + using raylib::GetFileName; + using raylib::GetFileNameWithoutExt; + using raylib::GetDirectoryPath; + using raylib::GetPrevDirectoryPath; + using raylib::GetWorkingDirectory; + using raylib::LoadDirectoryFiles; + using raylib::ChangeDirectory; + using raylib::LoadDroppedFiles; + using raylib::GetFileModTime; + using raylib::OpenURL; + using raylib::LoadImage; + using raylib::LoadImageRaw; + using raylib::LoadImageAnim; + using raylib::LoadImageFromMemory; + using raylib::ExportImage; + using raylib::ExportImageAsCode; + using raylib::DrawText; + using raylib::DrawTextEx; + using raylib::DrawTextPro; + using raylib::LoadFont; + using raylib::LoadFontEx; + using raylib::MeasureText; + using raylib::TextIsEqual; + using raylib::TextLength; + using raylib::TextSubtext; + using raylib::TextReplace; + using raylib::TextInsert; + using raylib::TextSplit; + using raylib::TextFindIndex; + using raylib::TextToUpper; + using raylib::TextToLower; + using raylib::TextToPascal; + using raylib::TextToInteger; + + /** + * @namespace raylib::Keyboard + * @brief Input-related functions: keyboard + */ + namespace Keyboard { + using raylib::Keyboard::IsKeyPressed; + using raylib::Keyboard::IsKeyPressedRepeat; + using raylib::Keyboard::IsKeyDown; + using raylib::Keyboard::IsKeyReleased; + using raylib::Keyboard::IsKeyUp; + using raylib::Keyboard::GetKeyPressed; + using raylib::Keyboard::GetCharPressed; + } + + /** + * @namespace raylib::Mouse + * @brief Input-related functions: mouse + */ + namespace Mouse { + using raylib::Mouse::IsButtonPressed; + using raylib::Mouse::IsButtonDown; + using raylib::Mouse::IsButtonReleased; + using raylib::Mouse::IsButtonUp; + using raylib::Mouse::GetX; + using raylib::Mouse::GetY; + using raylib::Mouse::SetX; + using raylib::Mouse::SetY; + using raylib::Mouse::GetPosition; + using raylib::Mouse::SetPosition; + using raylib::Mouse::GetDelta; + using raylib::Mouse::SetOffset; + using raylib::Mouse::SetScale; + using raylib::Mouse::GetWheelMove; + using raylib::Mouse::GetWheelMoveV; + using raylib::Mouse::SetCursor; + using raylib::Mouse::GetTouchX; + using raylib::Mouse::GetTouchY; + using raylib::Mouse::GetTouchPosition; + using raylib::Mouse::GetRay; + } + + /** + * @namespace raylib::Touch + * @brief Input-related functions: touch + */ + namespace Touch { + using raylib::Touch::GetX; + using raylib::Touch::GetY; + using raylib::Touch::GetPosition; + using raylib::Touch::GetPointId; + using raylib::Touch::GetPointCount; + } + + +} // namespace raylib + +#ifdef RAYLIB_CPP_R_PREFIXES +export { + using RAudioDevice = raylib::AudioDevice; + using RAudioStream = raylib::AudioStream; + using RAutomationEventList = raylib::AutomationEventList; + using RBoundingBox = raylib::BoundingBox; + using RCamera = raylib::Camera; // Alias for Camera3D + using RCamera2D = raylib::Camera2D; + using RCamera3D = raylib::Camera3D; + using RColor = raylib::Color; + using RFileData = raylib::FileData; + using RFileText = raylib::FileText; + using RFont = raylib::Font; + using RGamepad = raylib::Gamepad; + using RImage = raylib::Image; + using RMaterial = raylib::Material; + using RMatrix = raylib::Matrix; + using RMesh = raylib::Mesh; + using RModel = raylib::Model; + using RModelAnimation = raylib::ModelAnimation; + using RMusic = raylib::Music; + using RRay = raylib::Ray; + using RRayCollision = raylib::RayCollision; + using RRaylibException = raylib::RaylibException; + using RRectangle = raylib::Rectangle; + using RRenderTexture = raylib::RenderTexture; + using RRenderTexture2D = raylib::RenderTexture2D; // Alias for RenderTexture + using RShader = raylib::Shader; + using RSound = raylib::Sound; + using RText = raylib::Text; + using RTexture = raylib::Texture; + using RTexture2D = raylib::Texture2D; // Alias for Texture + using RTextureCubemap = raylib::TextureCubemap; // Alias for Texture + using RTextureUnmanaged = raylib::TextureUnmanaged; + using RTexture2DUnmanaged = raylib::Texture2DUnmanaged; // Alias for TextureUnmanaged + using RTextureCubemapUnmanaged = raylib::TextureCubemapUnmanaged; // Alias for TextureUnmanaged + using RVector2 = raylib::Vector2; + using RVector3 = raylib::Vector3; + using RVector4 = raylib::Vector4; + using RQuaternion = raylib::Quaternion; // Alias for Vector4 + using RVrStereoConfig = raylib::VrStereoConfig; + using RWave = raylib::Wave; + using RWindow = raylib::Window; +} +#endif