Preparando la interfaz

This commit is contained in:
Clinv committed 2026-09-29 23:35:03 -03:00
commit 66bedbb5f1
17 files changed
+876

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
#pragma once
// Constantes globales de Tahgibu. Sin dependencias (ni raylib).
// CMake define TAHGIBU_VERSION a partir de project(VERSION ...).
#ifndef TAHGIBU_VERSION
#define TAHGIBU_VERSION "2.0.0"
#endif
namespace tahgibu {
inline constexpr const char* kAppName = "Tahgibu";
inline constexpr const char* kAppVersion = TAHGIBU_VERSION;
// Límite duro: ni el proyecto ni ningún frame individual pueden superarlo.
inline constexpr float kMaxFps = 60.0f;
// Mínimo permitido. 0.1 FPS = un frame visible hasta 10 s, para poder hacer
// pausas largas sin duplicar frames.
inline constexpr float kMinFps = 0.1f;
// FPS base de un proyecto nuevo.
inline constexpr float kDefaultFps = 24.0f;
} // namespace tahgibu
+28
View File
@@ -0,0 +1,28 @@
#include "core/Frame.hpp"
#include <algorithm>
#include <cmath>
namespace tahgibu {
float Frame::clampFps(float fps) noexcept {
if (!std::isfinite(fps)) {
return kDefaultFps;
}
return std::clamp(fps, kMinFps, kMaxFps);
}
void Frame::setFpsOverride(float fps) noexcept {
fpsOverride_ = clampFps(fps);
}
float Frame::effectiveFps(float baseFps) const noexcept {
return fpsOverride_ ? *fpsOverride_ : clampFps(baseFps);
}
double Frame::durationSeconds(float baseFps) const noexcept {
// effectiveFps() >= kMinFps, así que nunca se divide por cero.
return 1.0 / static_cast<double>(effectiveFps(baseFps));
}
} // namespace tahgibu
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <optional>
#include "core/Constants.hpp"
namespace tahgibu {
// Un frame de la animación. Solo guarda cuánto dura: usa los FPS base del
// proyecto, salvo que tenga FPS propios (override).
class Frame {
public:
// Fuerza el valor al rango [kMinFps, kMaxFps]. Valores no finitos (NaN, inf)
// devuelven kDefaultFps.
static float clampFps(float fps) noexcept;
bool hasFpsOverride() const noexcept { return fpsOverride_.has_value(); }
void setFpsOverride(float fps) noexcept; // aplica clampFps
void clearFpsOverride() noexcept { fpsOverride_.reset(); }
float effectiveFps(float baseFps) const noexcept;
double durationSeconds(float baseFps) const noexcept;
private:
std::optional<float> fpsOverride_;
};
} // namespace tahgibu
+30
View File
@@ -0,0 +1,30 @@
#include "core/Project.hpp"
namespace tahgibu {
Project::Project() : name_("Sin título") {
frames_.emplace_back();
}
void Project::setBaseFps(float fps) noexcept {
baseFps_ = Frame::clampFps(fps);
}
std::size_t Project::addFrame() {
frames_.emplace_back();
return frames_.size() - 1;
}
double Project::frameDurationSeconds(std::size_t index) const {
return frames_.at(index).durationSeconds(baseFps_);
}
double Project::totalDurationSeconds() const {
double total = 0.0;
for (const Frame& frame : frames_) {
total += frame.durationSeconds(baseFps_);
}
return total;
}
} // namespace tahgibu
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <cstddef>
#include <string>
#include <vector>
#include "core/Frame.hpp"
namespace tahgibu {
// Modelo de datos del proyecto. No conoce raylib ni la interfaz.
class Project {
public:
Project(); // 1280x720, FPS base kDefaultFps, un frame inicial
const std::string& name() const noexcept { return name_; }
int width() const noexcept { return width_; }
int height() const noexcept { return height_; }
float baseFps() const noexcept { return baseFps_; }
void setBaseFps(float fps) noexcept; // aplica Frame::clampFps
std::size_t frameCount() const noexcept { return frames_.size(); }
const Frame& frame(std::size_t index) const { return frames_.at(index); }
Frame& frame(std::size_t index) { return frames_.at(index); }
std::size_t addFrame(); // devuelve el índice del frame nuevo
double frameDurationSeconds(std::size_t index) const;
double totalDurationSeconds() const;
private:
std::string name_;
int width_ = 1280;
int height_ = 720;
float baseFps_ = kDefaultFps;
std::vector<Frame> frames_;
};
} // namespace tahgibu