- Normalize CRLF to LF across all source files - Replace CLAUDE.md.old with updated CLAUDE.md - Standardize configuration file formatting - Update module source files with consistent line endings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
180 lines
6.4 KiB
C++
180 lines
6.4 KiB
C++
#include "SchedulerModule.h"
|
|
#include <grove/JsonDataNode.h>
|
|
|
|
namespace aissia {
|
|
|
|
SchedulerModule::SchedulerModule() {
|
|
m_logger = spdlog::get("SchedulerModule");
|
|
if (!m_logger) {
|
|
m_logger = spdlog::stdout_color_mt("SchedulerModule");
|
|
}
|
|
m_config = std::make_unique<grove::JsonDataNode>("config");
|
|
}
|
|
|
|
void SchedulerModule::setConfiguration(const grove::IDataNode& configNode,
|
|
grove::IIO* io,
|
|
grove::ITaskScheduler* scheduler) {
|
|
m_io = io;
|
|
m_config = std::make_unique<grove::JsonDataNode>("config");
|
|
|
|
// Charger la configuration
|
|
m_hyperfocusThresholdMinutes = configNode.getInt("hyperfocusThresholdMinutes", 120);
|
|
m_breakReminderIntervalMinutes = configNode.getInt("breakReminderIntervalMinutes", 45);
|
|
m_breakDurationMinutes = configNode.getInt("breakDurationMinutes", 10);
|
|
|
|
m_logger->info("SchedulerModule configuré: hyperfocus={}min, break_interval={}min",
|
|
m_hyperfocusThresholdMinutes, m_breakReminderIntervalMinutes);
|
|
}
|
|
|
|
const grove::IDataNode& SchedulerModule::getConfiguration() {
|
|
return *m_config;
|
|
}
|
|
|
|
void SchedulerModule::process(const grove::IDataNode& input) {
|
|
float currentTime = input.getDouble("gameTime", 0.0);
|
|
float dt = input.getDouble("deltaTime", 0.016);
|
|
|
|
// Convertir le temps en minutes pour les calculs
|
|
float sessionMinutes = (currentTime - m_sessionStartTime) / 60.0f;
|
|
|
|
// Vérifier l'hyperfocus
|
|
checkHyperfocus(currentTime);
|
|
|
|
// Vérifier les rappels de pause
|
|
checkBreakReminder(currentTime);
|
|
|
|
// Log périodique (toutes les 5 minutes simulées)
|
|
static float lastLog = 0;
|
|
if (currentTime - lastLog > 300.0f) { // 300 secondes = 5 minutes
|
|
lastLog = currentTime;
|
|
m_logger->debug("Session: {:.1f}min, Focus aujourd'hui: {}min, Tâche: {}",
|
|
sessionMinutes, m_totalFocusMinutesToday,
|
|
m_currentTaskId.empty() ? "(aucune)" : m_currentTaskId);
|
|
}
|
|
}
|
|
|
|
void SchedulerModule::checkHyperfocus(float currentTime) {
|
|
if (m_currentTaskId.empty()) return;
|
|
|
|
float sessionMinutes = (currentTime - m_sessionStartTime) / 60.0f;
|
|
|
|
if (sessionMinutes >= m_hyperfocusThresholdMinutes && !m_hyperfocusAlertSent) {
|
|
m_hyperfocusAlertSent = true;
|
|
m_logger->warn("HYPERFOCUS DÉTECTÉ! Session de {:.0f} minutes sur '{}'",
|
|
sessionMinutes, m_currentTaskId);
|
|
|
|
// Publier l'alerte (si IO disponible)
|
|
// Note: Dans une version complète, on publierait via m_io
|
|
}
|
|
}
|
|
|
|
void SchedulerModule::checkBreakReminder(float currentTime) {
|
|
float timeSinceBreak = (currentTime - m_lastBreakTime) / 60.0f;
|
|
|
|
if (timeSinceBreak >= m_breakReminderIntervalMinutes) {
|
|
m_lastBreakTime = currentTime;
|
|
m_logger->info("RAPPEL: Pause de {} minutes recommandée!", m_breakDurationMinutes);
|
|
|
|
// Publier le rappel (si IO disponible)
|
|
}
|
|
}
|
|
|
|
void SchedulerModule::startTask(const std::string& taskId) {
|
|
// Compléter la tâche précédente si nécessaire
|
|
if (!m_currentTaskId.empty()) {
|
|
completeCurrentTask();
|
|
}
|
|
|
|
m_currentTaskId = taskId;
|
|
m_sessionStartTime = m_lastActivityTime;
|
|
m_hyperfocusAlertSent = false;
|
|
|
|
Task* task = findTask(taskId);
|
|
if (task) {
|
|
m_logger->info("Tâche démarrée: {} (estimé: {}min)", task->name, task->estimatedMinutes);
|
|
}
|
|
}
|
|
|
|
void SchedulerModule::completeCurrentTask() {
|
|
if (m_currentTaskId.empty()) return;
|
|
|
|
Task* task = findTask(m_currentTaskId);
|
|
if (task) {
|
|
float sessionMinutes = (m_lastActivityTime - m_sessionStartTime) / 60.0f;
|
|
task->actualMinutes = static_cast<int>(sessionMinutes);
|
|
task->completed = true;
|
|
m_totalFocusMinutesToday += task->actualMinutes;
|
|
|
|
m_logger->info("Tâche terminée: {} (réel: {}min vs estimé: {}min)",
|
|
task->name, task->actualMinutes, task->estimatedMinutes);
|
|
}
|
|
|
|
m_currentTaskId.clear();
|
|
}
|
|
|
|
SchedulerModule::Task* SchedulerModule::findTask(const std::string& taskId) {
|
|
for (auto& task : m_tasks) {
|
|
if (task.id == taskId) return &task;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<grove::IDataNode> SchedulerModule::getHealthStatus() {
|
|
auto status = std::make_unique<grove::JsonDataNode>("status");
|
|
status->setString("status", "running");
|
|
status->setInt("taskCount", m_tasks.size());
|
|
status->setString("currentTask", m_currentTaskId);
|
|
status->setInt("totalFocusMinutesToday", m_totalFocusMinutesToday);
|
|
status->setBool("hyperfocusAlertSent", m_hyperfocusAlertSent);
|
|
return status;
|
|
}
|
|
|
|
void SchedulerModule::shutdown() {
|
|
if (!m_currentTaskId.empty()) {
|
|
completeCurrentTask();
|
|
}
|
|
m_logger->info("SchedulerModule arrêté. Focus total: {}min", m_totalFocusMinutesToday);
|
|
}
|
|
|
|
std::unique_ptr<grove::IDataNode> SchedulerModule::getState() {
|
|
auto state = std::make_unique<grove::JsonDataNode>("state");
|
|
|
|
state->setString("currentTaskId", m_currentTaskId);
|
|
state->setDouble("sessionStartTime", m_sessionStartTime);
|
|
state->setDouble("lastBreakTime", m_lastBreakTime);
|
|
state->setDouble("lastActivityTime", m_lastActivityTime);
|
|
state->setBool("hyperfocusAlertSent", m_hyperfocusAlertSent);
|
|
state->setInt("totalFocusMinutesToday", m_totalFocusMinutesToday);
|
|
state->setInt("taskCount", m_tasks.size());
|
|
|
|
m_logger->debug("État sauvegardé: {} tâches, focus={}min", m_tasks.size(), m_totalFocusMinutesToday);
|
|
return state;
|
|
}
|
|
|
|
void SchedulerModule::setState(const grove::IDataNode& state) {
|
|
m_currentTaskId = state.getString("currentTaskId", "");
|
|
m_sessionStartTime = state.getDouble("sessionStartTime", 0.0);
|
|
m_lastBreakTime = state.getDouble("lastBreakTime", 0.0);
|
|
m_lastActivityTime = state.getDouble("lastActivityTime", 0.0);
|
|
m_hyperfocusAlertSent = state.getBool("hyperfocusAlertSent", false);
|
|
m_totalFocusMinutesToday = state.getInt("totalFocusMinutesToday", 0);
|
|
|
|
m_logger->info("État restauré: tâche='{}', focus={}min",
|
|
m_currentTaskId.empty() ? "(aucune)" : m_currentTaskId,
|
|
m_totalFocusMinutesToday);
|
|
}
|
|
|
|
} // namespace aissia
|
|
|
|
extern "C" {
|
|
|
|
grove::IModule* createModule() {
|
|
return new aissia::SchedulerModule();
|
|
}
|
|
|
|
void destroyModule(grove::IModule* module) {
|
|
delete module;
|
|
}
|
|
|
|
}
|