Fase 1: Migración inicial a C++20 modules

Implementada la estructura base de módulos para vibe2_modules:

- Configurado CMakeLists.txt para soportar C++23 y módulos
- Creado módulo core.cppm con tipos básicos (Color, ColorTheme, constantes)
- Creado módulo sdl_wrapper.cppm para encapsular SDL3
- Migrado defines.h completamente al módulo core
- Actualizado ball.h y ball.cpp para usar el módulo core
- Actualizado main.cpp para importar y usar el módulo core
- Eliminado defines.h obsoleto

El proyecto ahora compila y funciona con módulos C++20.
Próximos pasos: crear módulos especializados (physics, rendering, etc.)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-17 21:17:40 +02:00
parent 34a0e0505b
commit ea6bb25d5d
7 changed files with 199 additions and 44 deletions

View File

@@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 3.20)
project(vibe2_modules)
# Establecer el estándar de C++
set(CMAKE_CXX_STANDARD 20)
# Establecer el estándar de C++ y habilitar modules
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
# Opciones comunes de compilación
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Os -ffunction-sections -fdata-sections")
@@ -16,9 +17,12 @@ if (NOT SDL3_FOUND)
message(FATAL_ERROR "SDL3 no encontrado. Por favor, verifica su instalación.")
endif()
# Archivos fuente
# Archivos fuente tradicionales
file(GLOB SOURCE_FILES source/*.cpp source/external/*.cpp)
# Archivos de módulos C++20
file(GLOB MODULE_FILES source/modules/*.cppm source/modules/external/*.cppm)
# Comprobar si se encontraron archivos fuente
if(NOT SOURCE_FILES)
message(FATAL_ERROR "No se encontraron archivos fuente en el directorio 'source/'. Verifica la ruta.")
@@ -42,6 +46,13 @@ include_directories(${SDL3_INCLUDE_DIRS})
# Añadir el ejecutable reutilizando el nombre del proyecto
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
# Añadir módulos C++20 si existen
if(MODULE_FILES)
target_sources(${PROJECT_NAME} PRIVATE
FILE_SET CXX_MODULES FILES ${MODULE_FILES}
)
endif()
# Especificar la ubicación del ejecutable (en la raíz del proyecto)
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})

View File

@@ -4,22 +4,22 @@
#include <cmath> // for fabs
#include "defines.h" // for BALL_SIZE, Color, SCREEN_HEIGHT, GRAVITY_FORCE
// defines.h ya no es necesario, todo está en el módulo core via ball.h
class Texture;
// Constructor
Ball::Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> texture)
Ball::Ball(float x, float vx, float vy, vibe2::Color color, std::shared_ptr<Texture> texture)
: sprite_(std::make_unique<Sprite>(texture)),
pos_({x, 0.0f, BALL_SIZE, BALL_SIZE}) {
pos_({x, 0.0f, vibe2::BALL_SIZE, vibe2::BALL_SIZE}) {
// Convertir velocidades de píxeles/frame a píxeles/segundo (multiplicar por 60)
vx_ = vx * 60.0f;
vy_ = vy * 60.0f;
sprite_->setPos({pos_.x, pos_.y});
sprite_->setSize(BALL_SIZE, BALL_SIZE);
sprite_->setClip({0, 0, BALL_SIZE, BALL_SIZE});
sprite_->setSize(vibe2::BALL_SIZE, vibe2::BALL_SIZE);
sprite_->setClip({0, 0, vibe2::BALL_SIZE, vibe2::BALL_SIZE});
color_ = color;
// Convertir gravedad de píxeles/frame² a píxeles/segundo² (multiplicar por 60²)
gravity_force_ = GRAVITY_FORCE * 60.0f * 60.0f;
gravity_force_ = vibe2::GRAVITY_FORCE * 60.0f * 60.0f;
on_floor_ = false;
stopped_ = false;
loss_ = ((rand() % 30) * 0.01f) + 0.6f;
@@ -42,7 +42,7 @@ void Ball::update(float deltaTime) {
pos_.y += vy_ * deltaTime;
} else {
// Si está en el suelo, mantenerla ahí
pos_.y = SCREEN_HEIGHT - pos_.h;
pos_.y = vibe2::SCREEN_HEIGHT - pos_.h;
}
// Comprueba las colisiones con el lateral izquierdo
@@ -52,8 +52,8 @@ void Ball::update(float deltaTime) {
}
// Comprueba las colisiones con el lateral derecho
if (pos_.x + pos_.w > SCREEN_WIDTH) {
pos_.x = SCREEN_WIDTH - pos_.w;
if (pos_.x + pos_.w > vibe2::SCREEN_WIDTH) {
pos_.x = vibe2::SCREEN_WIDTH - pos_.w;
vx_ = -vx_;
}
@@ -64,8 +64,8 @@ void Ball::update(float deltaTime) {
}
// Comprueba las colisiones con la parte inferior
if (pos_.y + pos_.h > SCREEN_HEIGHT) {
pos_.y = SCREEN_HEIGHT - pos_.h;
if (pos_.y + pos_.h > vibe2::SCREEN_HEIGHT) {
pos_.y = vibe2::SCREEN_HEIGHT - pos_.h;
vy_ = -vy_ * loss_;
if (std::fabs(vy_) < 6.0f) // Convertir 0.1f frame-based a 6.0f time-based
{
@@ -111,5 +111,5 @@ void Ball::modVel(float vx, float vy) {
// Cambia la gravedad (usa la versión convertida)
void Ball::switchGravity() {
gravity_force_ = gravity_force_ == 0.0f ? (GRAVITY_FORCE * 60.0f * 60.0f) : 0.0f;
gravity_force_ = gravity_force_ == 0.0f ? (vibe2::GRAVITY_FORCE * 60.0f * 60.0f) : 0.0f;
}

View File

@@ -4,7 +4,7 @@
#include <memory> // for shared_ptr, unique_ptr
#include "defines.h" // for Color
import vibe2.core; // for Color y constantes
#include "external/sprite.h" // for Sprite
class Texture;
@@ -14,14 +14,14 @@ class Ball {
SDL_FRect pos_; // Posición y tamaño de la pelota
float vx_, vy_; // Velocidad
float gravity_force_; // Gravedad
Color color_; // Color de la pelota
vibe2::Color color_; // Color de la pelota
bool on_floor_; // Indica si la pelota está ya en el suelo
bool stopped_; // Indica si la pelota ha terminado de moverse;
float loss_; // Coeficiente de rebote. Pérdida de energía en cada rebote
public:
// Constructor
Ball(float x, float vx, float vy, Color color, std::shared_ptr<Texture> texture);
Ball(float x, float vx, float vy, vibe2::Color color, std::shared_ptr<Texture> texture);
// Destructor
~Ball() = default;
@@ -45,5 +45,5 @@ class Ball {
// Getters para batch rendering
SDL_FRect getPosition() const { return pos_; }
Color getColor() const { return color_; }
vibe2::Color getColor() const { return color_; }
};

View File

@@ -1,16 +0,0 @@
#pragma once
constexpr char WINDOW_CAPTION[] = "vibe2_modules";
constexpr int SCREEN_WIDTH = 320;
constexpr int SCREEN_HEIGHT = 240;
constexpr int WINDOW_SIZE = 3;
constexpr int BALL_SIZE = 10;
constexpr float GRAVITY_FORCE = 0.2f;
// DEMO_SPEED eliminado - ya no se usa con delta time
constexpr Uint64 TEXT_DURATION = 2000;
struct Color {
int r, g, b;
};

View File

@@ -16,7 +16,7 @@
#include <vector> // for vector
#include "ball.h" // for Ball
#include "defines.h" // for SCREEN_WIDTH, SCREEN_HEIGHT, WINDOW_SIZE
import vibe2.core; // Módulo con constantes y tipos básicos
#include "external/dbgtxt.h" // for dbg_init, dbg_print
#include "external/texture.h" // for Texture
@@ -27,6 +27,9 @@ std::shared_ptr<Texture> texture = nullptr;
std::vector<std::unique_ptr<Ball>> balls;
std::array<int, 8> test = {1, 10, 100, 500, 1000, 10000, 50000, 100000};
// Usar namespace del módulo
using namespace vibe2;
bool should_exit = false; // Controla si la aplicación debe cerrarse
// ticks eliminado - reemplazado por delta time system
int scenario = 0; // Escenario actual basado en el número de bolas
@@ -52,14 +55,7 @@ float delta_time = 0.0f; // Tiempo transcurrido desde el último frame en se
// Variables para Debug Display
bool show_debug = false; // Debug display desactivado por defecto
// Sistema de temas de colores
enum class ColorTheme {
SUNSET = 0,
OCEAN = 1,
NEON = 2,
FOREST = 3
};
// El sistema de temas ahora está en el módulo core
ColorTheme current_theme = ColorTheme::SUNSET;
std::string theme_names[] = {"SUNSET", "OCEAN", "NEON", "FOREST"};

57
source/modules/core.cppm Normal file
View File

@@ -0,0 +1,57 @@
export module vibe2.core;
#include <cstdint>
export namespace vibe2 {
// Constantes de pantalla
constexpr char WINDOW_CAPTION[] = "vibe2_modules";
constexpr int SCREEN_WIDTH = 320;
constexpr int SCREEN_HEIGHT = 240;
constexpr int WINDOW_SIZE = 3;
constexpr int BALL_SIZE = 10;
constexpr float GRAVITY_FORCE = 0.2f;
constexpr std::uint64_t TEXT_DURATION = 2000;
// Tipos básicos
struct Color {
int r, g, b;
constexpr Color(int red = 0, int green = 0, int blue = 0)
: r(red), g(green), b(blue) {}
};
struct Position {
float x, y;
constexpr Position(float px = 0.0f, float py = 0.0f)
: x(px), y(py) {}
};
struct Velocity {
float vx, vy;
constexpr Velocity(float x_vel = 0.0f, float y_vel = 0.0f)
: vx(x_vel), vy(y_vel) {}
};
// Enums para el sistema de temas
enum class ColorTheme {
SUNSET = 0,
OCEAN = 1,
NEON = 2,
FOREST = 3
};
// Constantes útiles para la física
namespace physics {
constexpr float FRICTION_FACTOR = 0.97f;
constexpr float VELOCITY_THRESHOLD = 6.0f;
constexpr float CONVERSION_FACTOR = 60.0f; // Frame-based to time-based
}
// Constantes para debug
namespace debug {
constexpr int DEFAULT_TEXT_SIZE = 8; // Píxeles por carácter
constexpr int MARGIN = 8; // Margen por defecto
}
}

107
source/modules/external/sdl_wrapper.cppm vendored Normal file
View File

@@ -0,0 +1,107 @@
export module vibe2.external.sdl_wrapper;
// Incluir headers de SDL3
#include <cstdint>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_video.h>
#include <SDL3/SDL_rect.h>
export namespace vibe2::sdl {
// Re-exportar tipos de SDL que usamos frecuentemente
using Window = SDL_Window;
using Renderer = SDL_Renderer;
using Event = SDL_Event;
using FRect = SDL_FRect;
using Vertex = SDL_Vertex;
using Texture = SDL_Texture;
// Re-exportar constantes de SDL
constexpr auto INIT_VIDEO = SDL_INIT_VIDEO;
constexpr auto WINDOW_OPENGL = SDL_WINDOW_OPENGL;
constexpr auto EVENT_QUIT = SDL_EVENT_QUIT;
constexpr auto EVENT_KEY_DOWN = SDL_EVENT_KEY_DOWN;
constexpr auto LOGICAL_PRESENTATION_INTEGER_SCALE = SDL_LOGICAL_PRESENTATION_INTEGER_SCALE;
// Re-exportar teclas que usamos
constexpr auto KEY_ESCAPE = SDLK_ESCAPE;
constexpr auto KEY_SPACE = SDLK_SPACE;
constexpr auto KEY_G = SDLK_G;
constexpr auto KEY_V = SDLK_V;
constexpr auto KEY_H = SDLK_H;
constexpr auto KEY_T = SDLK_T;
constexpr auto KEY_F1 = SDLK_F1;
constexpr auto KEY_F2 = SDLK_F2;
constexpr auto KEY_F3 = SDLK_F3;
constexpr auto KEY_F4 = SDLK_F4;
constexpr auto KEY_1 = SDLK_1;
constexpr auto KEY_2 = SDLK_2;
constexpr auto KEY_3 = SDLK_3;
constexpr auto KEY_4 = SDLK_4;
constexpr auto KEY_5 = SDLK_5;
constexpr auto KEY_6 = SDLK_6;
constexpr auto KEY_7 = SDLK_7;
constexpr auto KEY_8 = SDLK_8;
// Wrapper functions para funciones de SDL más usadas
inline bool init(Uint32 flags) {
return SDL_Init(flags);
}
inline void quit() {
SDL_Quit();
}
inline Window* createWindow(const char* title, int w, int h, Uint64 flags) {
return SDL_CreateWindow(title, w, h, flags);
}
inline void destroyWindow(Window* window) {
SDL_DestroyWindow(window);
}
inline Renderer* createRenderer(Window* window, const char* name) {
return SDL_CreateRenderer(window, name);
}
inline void destroyRenderer(Renderer* renderer) {
SDL_DestroyRenderer(renderer);
}
inline bool setRenderDrawColor(Renderer* renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
return SDL_SetRenderDrawColor(renderer, r, g, b, a);
}
inline bool setRenderLogicalPresentation(Renderer* renderer, int w, int h, SDL_RendererLogicalPresentation mode) {
return SDL_SetRenderLogicalPresentation(renderer, w, h, mode);
}
inline bool setRenderVSync(Renderer* renderer, int vsync) {
return SDL_SetRenderVSync(renderer, vsync);
}
inline bool renderGeometry(Renderer* renderer, Texture* texture, const Vertex* vertices, int num_vertices, const int* indices, int num_indices) {
return SDL_RenderGeometry(renderer, texture, vertices, num_vertices, indices, num_indices);
}
inline bool renderPresent(Renderer* renderer) {
return SDL_RenderPresent(renderer);
}
inline bool pollEvent(Event* event) {
return SDL_PollEvent(event);
}
inline Uint64 getTicks() {
return SDL_GetTicks();
}
inline const char* getError() {
return SDL_GetError();
}
}