Advertisement
bipping

SoftwareEngine.cpp

Oct 7th, 2024
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.51 KB | Source Code | 0 0
  1. // copyright bipping
  2. #include "SoftwareEngine.h"
  3. /* includes ============================================================== */
  4. #include <boost/chrono.hpp>
  5. #include <algorithm>
  6. #include <limits>
  7.  
  8. /* internal public functions =========================================== */
  9. SoftwareEngine& SoftwareEngine::GetInstance() {
  10.     static SoftwareEngine instance;
  11.     return instance;
  12. }
  13.  
  14. SoftwareEngine::SoftwareEngine()
  15.     : currentTime(0), nextTaskId(1) {
  16.     // Initialisation si nécessaire
  17. }
  18.  
  19. void SoftwareEngine::Start() {
  20.     while (true) {
  21.         std::vector<Task*> tasksToExecute;
  22.         Task* nextTask = nullptr;
  23.  
  24.         // Vérifier les tâches prêtes et déterminer la prochaine tâche
  25.         CheckTasks(tasksToExecute, nextTask);
  26.  
  27.         if (!tasksToExecute.empty()) {
  28.             ExecuteTasks(tasksToExecute);
  29.         } else if (nextTask) {
  30.             ExecuteNextTask(nextTask);
  31.         }
  32.     }
  33. }
  34.  
  35. void SoftwareEngine::AddTask(boost::function<void()> func, uint32_t intervalMicros) {
  36.     int newId = GenerateUniqueTaskId();
  37.     Task newTask = { newId, func, intervalMicros, currentTime + intervalMicros };
  38.     taskList.push_back(newTask);
  39. }
  40.  
  41. void SoftwareEngine::RemoveTask(boost::function<void()> func) {
  42.     int taskId = -1;
  43.     for (const auto& task : taskList) {
  44.         if (task.func.target<void()>() == func.target<void()>()) {
  45.             taskId = task.id;
  46.             break;
  47.         }
  48.     }
  49.     if (taskId != -1) {
  50.         RemoveTaskById(taskId);
  51.     }
  52. }
  53.  
  54. void SoftwareEngine::ModifyTaskInterval(boost::function<void()> func, uint32_t newIntervalMicros) {
  55.     for (auto& task : taskList) {
  56.         if (task.func.target<void()>() == func.target<void()>()) {
  57.             task.intervalMicros = newIntervalMicros;
  58.             task.nextExecution = currentTime + newIntervalMicros;
  59.             break;
  60.         }
  61.     }
  62. }
  63.  
  64. void SoftwareEngine::RemoveTaskById(int taskId) {
  65.     taskList.erase(std::remove_if(taskList.begin(), taskList.end(),
  66.                                   [taskId](const Task& t) { return t.id == taskId; }),
  67.                    taskList.end());
  68. }
  69.  
  70. int SoftwareEngine::GenerateUniqueTaskId() {
  71.     int newId = nextTaskId++;
  72.     if (newId == std::numeric_limits<int>::max()) {
  73.         nextTaskId = 1;  // Réinitialiser l'ID si on atteint la limite maximale
  74.         newId = nextTaskId++;
  75.     }
  76.  
  77.     // Vérifier que l'ID n'est pas déjà utilisé
  78.     auto it = std::find_if(taskList.begin(), taskList.end(),
  79.                            [newId](const Task& task) { return task.id == newId; });
  80.     if (it != taskList.end()) {
  81.         return GenerateUniqueTaskId();  // Recommencer si l'ID est déjà utilisé
  82.     }
  83.  
  84.     return newId;
  85. }
  86.  
  87. void SoftwareEngine::UpdateCurrentTime() {
  88.     currentTime = GetCurrentTimeMicros();
  89. }
  90.  
  91. uint64_t SoftwareEngine::GetCurrentTimeMicros() {
  92.     auto now = boost::chrono::steady_clock::now();
  93.     auto micros = boost::chrono::duration_cast<boost::chrono::microseconds>(now.time_since_epoch()).count();
  94.     return static_cast<uint64_t>(micros);
  95. }
  96.  
  97. void SoftwareEngine::CheckTasks(std::vector<Task*>& tasksToExecute, Task*& nextTask) {
  98.     UpdateCurrentTime();
  99.  
  100.     uint64_t nextTime = UINT64_MAX;
  101.  
  102.     tasksToExecute.clear();
  103.     nextTask = nullptr;
  104.  
  105.     for (auto& task : taskList) {
  106.         if (task.nextExecution <= currentTime) {
  107.             tasksToExecute.push_back(&task);
  108.         } else if (task.nextExecution < nextTime) {
  109.             nextTime = task.nextExecution;
  110.             nextTask = &task;
  111.         }
  112.     }
  113. }
  114.  
  115. void SoftwareEngine::ExecuteTasks(const std::vector<Task*>& tasksToExecute) {
  116.     std::vector<int> tasksToRemoveIds;
  117.  
  118.     for (const auto& taskPtr : tasksToExecute) {
  119.         taskPtr->func();
  120.  
  121.         if (taskPtr->intervalMicros == 0) {
  122.             tasksToRemoveIds.push_back(taskPtr->id);
  123.         } else {
  124.             taskPtr->nextExecution = currentTime + taskPtr->intervalMicros;
  125.         }
  126.     }
  127.  
  128.     for (int taskId : tasksToRemoveIds) {
  129.         RemoveTaskById(taskId);
  130.     }
  131. }
  132.  
  133. void SoftwareEngine::ExecuteNextTask(Task* nextTask) {
  134.     uint64_t timeUntilNextExecution = nextTask->nextExecution - currentTime;
  135.  
  136.     // Fonction de sommeil adaptée à une plateforme monothread
  137.     boost::this_thread::sleep_for(boost::chrono::microseconds(timeUntilNextExecution));
  138.  
  139.     UpdateCurrentTime();
  140.     nextTask->func();
  141.  
  142.     if (nextTask->intervalMicros == 0) {
  143.         RemoveTaskById(nextTask->id);
  144.     } else {
  145.         nextTask->nextExecution = currentTime + nextTask->intervalMicros;
  146.     }
  147. }
  148.  
Tags: Header
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement