Organize stuffs

This commit is contained in:
Sebastian Cabrera 2025-08-09 21:22:44 -04:00
parent a9240cac6e
commit c120871293
Signed by: okseby
GPG key ID: 2DDBFDEE356CF3DE
13 changed files with 625 additions and 56 deletions

View file

@ -7,11 +7,23 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find SDL2
find_package(SDL2 REQUIRED)
# Collect all source files
set(SOURCES
src/main.cpp
src/core/Application.cpp
src/window/Window.cpp
src/renderer/Renderer.cpp
src/events/EventManager.cpp
)
# Add executable
add_executable(${PROJECT_NAME} src/main.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})
# Link SDL2
target_link_libraries(${PROJECT_NAME} SDL2::SDL2)
# Include directories for SDL2
target_include_directories(${PROJECT_NAME} PRIVATE ${SDL2_INCLUDE_DIRS})
# Set include directories for our source files
target_include_directories(${PROJECT_NAME} PRIVATE src)

121
src/core/Application.cpp Normal file
View file

@ -0,0 +1,121 @@
#include "Application.h"
#include "Config.h"
#include "../utils/Utils.h"
#include <iostream>
Application::Application(const std::string& title, int width, int height)
: initialized_(false) {
if (!initialize()) {
Utils::logError("Failed to initialize application");
return;
}
// Create window
window_ = std::make_unique<Window>(title, width, height);
if (!window_ || !window_->isValid()) {
Utils::logError("Failed to create window");
return;
}
// Create renderer
renderer_ = std::make_unique<Renderer>(window_->getHandle());
if (!renderer_ || !renderer_->isValid()) {
Utils::logError("Failed to create renderer");
return;
}
// Create event manager
eventManager_ = std::make_unique<EventManager>();
// Register event callbacks
eventManager_->registerCallback(EventType::Quit,
[this](const EventData& event) { onQuit(event); });
eventManager_->registerCallback(EventType::KeyDown,
[this](const EventData& event) { onKeyDown(event); });
eventManager_->registerCallback(EventType::KeyUp,
[this](const EventData& event) { onKeyUp(event); });
initialized_ = true;
}
Application::~Application() {
cleanup();
}
bool Application::initialize() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "SDL2 initialization failed: " << SDL_GetError() << std::endl;
return false;
}
return true;
}
void Application::cleanup() {
eventManager_.reset();
renderer_.reset();
window_.reset();
SDL_Quit();
}
int Application::run() {
if (!initialized_) {
Utils::logError("Application not properly initialized");
return 1;
}
Utils::log("Starting application...");
// Main application loop
while (isRunning()) {
// Handle events
eventManager_->pollEvents();
// Update game logic
update();
// Render frame
render();
}
Utils::log("Application finished");
return 0;
}
void Application::update() {
// Update game logic here
// This is where you would update game objects, physics, etc.
}
void Application::render() {
if (!renderer_) return;
// Clear screen with black background
renderer_->setDrawColor(0, 0, 0, 255);
renderer_->clear();
// Render game objects here
// This is where you would draw sprites, shapes, etc.
// Present the frame
renderer_->present();
}
void Application::onQuit(const EventData& event) {
stop();
}
void Application::onKeyDown(const EventData& event) {
const SDL_KeyboardEvent& keyEvent = event.sdlEvent.key;
switch (keyEvent.keysym.sym) {
case SDLK_ESCAPE:
stop();
break;
// Add more key handling here
}
}
void Application::onKeyUp(const EventData& event) {
// Handle key up events here
}

48
src/core/Application.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#include "Common.h"
#include "../window/Window.h"
#include "../renderer/Renderer.h"
#include "../events/EventManager.h"
class Application {
public:
Application(const std::string& title, int width, int height);
~Application();
// Disable copying
Application(const Application&) = delete;
Application& operator=(const Application&) = delete;
// Main application loop
int run();
// Getters
Window* getWindow() const { return window_.get(); }
Renderer* getRenderer() const { return renderer_.get(); }
EventManager* getEventManager() const { return eventManager_.get(); }
// Application state
bool isRunning() const { return eventManager_ && eventManager_->isRunning(); }
void stop() { if (eventManager_) eventManager_->stop(); }
private:
// Core components
WindowPtr window_;
RendererPtr renderer_;
EventManagerPtr eventManager_;
// Application state
bool initialized_;
// Private methods
bool initialize();
void cleanup();
void update();
void render();
// Event callbacks
void onQuit(const EventData& event);
void onKeyDown(const EventData& event);
void onKeyUp(const EventData& event);
};

17
src/core/Common.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include <SDL2/SDL.h>
#include <memory>
#include <string>
// Forward declarations
class Window;
class Renderer;
class EventManager;
class Application;
// Type aliases
using WindowPtr = std::unique_ptr<Window>;
using RendererPtr = std::unique_ptr<Renderer>;
using EventManagerPtr = std::unique_ptr<EventManager>;
using ApplicationPtr = std::unique_ptr<Application>;

24
src/core/Config.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <string>
namespace Config {
// Window settings
constexpr int DEFAULT_WINDOW_WIDTH = 800;
constexpr int DEFAULT_WINDOW_HEIGHT = 600;
constexpr const char* DEFAULT_WINDOW_TITLE = "Observations on the Sublime Dynamics of Eroding Matter";
// Rendering settings
constexpr bool VSYNC_ENABLED = true;
constexpr int TARGET_FPS = 60;
constexpr float TARGET_FRAME_TIME = 1.0f / TARGET_FPS;
// Application settings
constexpr bool DEBUG_MODE = true;
constexpr bool LOGGING_ENABLED = true;
// File paths
constexpr const char* ASSETS_PATH = "assets/";
constexpr const char* CONFIG_PATH = "config/";
constexpr const char* LOG_PATH = "logs/";
}

View file

@ -0,0 +1,93 @@
#include "EventManager.h"
#include <iostream>
EventManager::EventManager() : running_(true) {
}
bool EventManager::pollEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
processEvent(event);
}
return running_;
}
void EventManager::registerCallback(EventType type, EventCallback callback) {
callbacks_[type] = callback;
}
void EventManager::unregisterCallback(EventType type) {
callbacks_.erase(type);
}
void EventManager::processEvent(const SDL_Event& event) {
switch (event.type) {
case SDL_QUIT:
handleQuitEvent();
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
handleKeyEvent(event);
break;
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
handleMouseEvent(event);
break;
case SDL_WINDOWEVENT:
handleWindowEvent(event);
break;
}
}
void EventManager::handleQuitEvent() {
running_ = false;
// Call registered callback if any
auto it = callbacks_.find(EventType::Quit);
if (it != callbacks_.end()) {
EventData data{EventType::Quit, {}};
it->second(data);
}
}
void EventManager::handleKeyEvent(const SDL_Event& event) {
EventType type = (event.type == SDL_KEYDOWN) ? EventType::KeyDown : EventType::KeyUp;
auto it = callbacks_.find(type);
if (it != callbacks_.end()) {
EventData data{type, event};
it->second(data);
}
}
void EventManager::handleMouseEvent(const SDL_Event& event) {
EventType type;
switch (event.type) {
case SDL_MOUSEMOTION:
type = EventType::MouseMove;
break;
case SDL_MOUSEBUTTONDOWN:
type = EventType::MouseButtonDown;
break;
case SDL_MOUSEBUTTONUP:
type = EventType::MouseButtonUp;
break;
default:
return;
}
auto it = callbacks_.find(type);
if (it != callbacks_.end()) {
EventData data{type, event};
it->second(data);
}
}
void EventManager::handleWindowEvent(const SDL_Event& event) {
auto it = callbacks_.find(EventType::WindowEvent);
if (it != callbacks_.end()) {
EventData data{EventType::WindowEvent, event};
it->second(data);
}
}

48
src/events/EventManager.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#include "../core/Common.h"
#include <functional>
#include <unordered_map>
enum class EventType {
Quit,
KeyDown,
KeyUp,
MouseMove,
MouseButtonDown,
MouseButtonUp,
WindowEvent
};
struct EventData {
EventType type;
SDL_Event sdlEvent;
};
class EventManager {
public:
EventManager();
~EventManager() = default;
// Event handling
bool pollEvents();
bool isRunning() const { return running_; }
void stop() { running_ = false; }
// Event callbacks
using EventCallback = std::function<void(const EventData&)>;
void registerCallback(EventType type, EventCallback callback);
void unregisterCallback(EventType type);
// Event processing
void processEvent(const SDL_Event& event);
private:
bool running_;
std::unordered_map<EventType, EventCallback> callbacks_;
void handleQuitEvent();
void handleKeyEvent(const SDL_Event& event);
void handleMouseEvent(const SDL_Event& event);
void handleWindowEvent(const SDL_Event& event);
};

View file

@ -1,61 +1,16 @@
#include <SDL2/SDL.h>
#include "core/Application.h"
#include "core/Config.h"
#include <iostream>
int main(int argc, char* argv[]) {
// Initialize SDL2
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "SDL2 initialization failed: " << SDL_GetError() << std::endl;
try {
Application app(Config::DEFAULT_WINDOW_TITLE, Config::DEFAULT_WINDOW_WIDTH, Config::DEFAULT_WINDOW_HEIGHT);
return app.run();
} catch (const std::exception& e) {
std::cerr << "Fatal error: " << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "Unknown fatal error occurred" << std::endl;
return 1;
}
// Create window
SDL_Window* window = SDL_CreateWindow(
"Observations on the Sublime Dynamics of Eroding Matter",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
800, 600,
SDL_WINDOW_SHOWN
);
if (!window) {
std::cerr << "Window creation failed: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
// Create renderer
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
std::cerr << "Renderer creation failed: " << SDL_GetError() << std::endl;
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// Main event loop
bool running = true;
SDL_Event event;
while (running) {
// Handle events
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
// Clear screen with black background
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// Present the renderer
SDL_RenderPresent(renderer);
}
// Cleanup
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

73
src/renderer/Renderer.cpp Normal file
View file

@ -0,0 +1,73 @@
#include "Renderer.h"
#include <iostream>
Renderer::Renderer(SDL_Window* window)
: renderer_(nullptr) {
if (window) {
renderer_ = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer_) {
std::cerr << "Renderer creation failed: " << SDL_GetError() << std::endl;
}
}
}
Renderer::~Renderer() {
if (renderer_) {
SDL_DestroyRenderer(renderer_);
renderer_ = nullptr;
}
}
Renderer::Renderer(Renderer&& other) noexcept
: renderer_(other.renderer_) {
other.renderer_ = nullptr;
}
Renderer& Renderer::operator=(Renderer&& other) noexcept {
if (this != &other) {
if (renderer_) {
SDL_DestroyRenderer(renderer_);
}
renderer_ = other.renderer_;
other.renderer_ = nullptr;
}
return *this;
}
void Renderer::clear() {
if (renderer_) {
SDL_RenderClear(renderer_);
}
}
void Renderer::setDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
if (renderer_) {
SDL_SetRenderDrawColor(renderer_, r, g, b, a);
}
}
void Renderer::present() {
if (renderer_) {
SDL_RenderPresent(renderer_);
}
}
void Renderer::drawLine(int x1, int y1, int x2, int y2) {
if (renderer_) {
SDL_RenderDrawLine(renderer_, x1, y1, x2, y2);
}
}
void Renderer::drawRect(const SDL_Rect& rect) {
if (renderer_) {
SDL_RenderDrawRect(renderer_, &rect);
}
}
void Renderer::fillRect(const SDL_Rect& rect) {
if (renderer_) {
SDL_RenderFillRect(renderer_, &rect);
}
}

35
src/renderer/Renderer.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include "../core/Common.h"
#include <SDL2/SDL.h>
class Renderer {
public:
explicit Renderer(SDL_Window* window);
~Renderer();
// Disable copying
Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete;
// Allow moving
Renderer(Renderer&& other) noexcept;
Renderer& operator=(Renderer&& other) noexcept;
// Getters
SDL_Renderer* getHandle() const { return renderer_; }
bool isValid() const { return renderer_ != nullptr; }
// Rendering operations
void clear();
void setDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a = 255);
void present();
// Drawing primitives
void drawLine(int x1, int y1, int x2, int y2);
void drawRect(const SDL_Rect& rect);
void fillRect(const SDL_Rect& rect);
private:
SDL_Renderer* renderer_;
};

38
src/utils/Utils.h Normal file
View file

@ -0,0 +1,38 @@
#pragma once
#include <string>
#include <iostream>
namespace Utils {
// Logging utilities
inline void log(const std::string& message) {
std::cout << "[INFO] " << message << std::endl;
}
inline void logError(const std::string& message) {
std::cerr << "[ERROR] " << message << std::endl;
}
inline void logWarning(const std::string& message) {
std::cout << "[WARNING] " << message << std::endl;
}
// String utilities
inline std::string formatString(const std::string& format, ...) {
// Simple string formatting - can be expanded later
return format;
}
// Math utilities
template<typename T>
inline T clamp(T value, T min, T max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
template<typename T>
inline T lerp(T a, T b, float t) {
return a + (b - a) * t;
}
}

70
src/window/Window.cpp Normal file
View file

@ -0,0 +1,70 @@
#include "Window.h"
#include <iostream>
Window::Window(const std::string& title, int width, int height)
: window_(nullptr), width_(width), height_(height), title_(title) {
window_ = SDL_CreateWindow(
title.c_str(),
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width,
height,
SDL_WINDOW_SHOWN
);
if (!window_) {
std::cerr << "Window creation failed: " << SDL_GetError() << std::endl;
}
}
Window::~Window() {
if (window_) {
SDL_DestroyWindow(window_);
window_ = nullptr;
}
}
Window::Window(Window&& other) noexcept
: window_(other.window_), width_(other.width_), height_(other.height_), title_(std::move(other.title_)) {
other.window_ = nullptr;
other.width_ = 0;
other.height_ = 0;
}
Window& Window::operator=(Window&& other) noexcept {
if (this != &other) {
if (window_) {
SDL_DestroyWindow(window_);
}
window_ = other.window_;
width_ = other.width_;
height_ = other.height_;
title_ = std::move(other.title_);
other.window_ = nullptr;
other.width_ = 0;
other.height_ = 0;
}
return *this;
}
void Window::show() {
if (window_) {
SDL_ShowWindow(window_);
}
}
void Window::hide() {
if (window_) {
SDL_HideWindow(window_);
}
}
void Window::setTitle(const std::string& title) {
title_ = title;
if (window_) {
SDL_SetWindowTitle(window_, title.c_str());
}
}

35
src/window/Window.h Normal file
View file

@ -0,0 +1,35 @@
#pragma once
#include "../core/Common.h"
#include <string>
class Window {
public:
Window(const std::string& title, int width, int height);
~Window();
// Disable copying
Window(const Window&) = delete;
Window& operator=(const Window&) = delete;
// Allow moving
Window(Window&& other) noexcept;
Window& operator=(Window&& other) noexcept;
// Getters
SDL_Window* getHandle() const { return window_; }
int getWidth() const { return width_; }
int getHeight() const { return height_; }
bool isValid() const { return window_ != nullptr; }
// Window operations
void show();
void hide();
void setTitle(const std::string& title);
private:
SDL_Window* window_;
int width_;
int height_;
std::string title_;
};