Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // copyright bipping
- #include "SoftwareEngine.h"
- /* includes ============================================================== */
- #include <boost/chrono.hpp>
- #include <algorithm>
- #include <limits>
- /* internal public functions =========================================== */
- SoftwareEngine& SoftwareEngine::GetInstance() {
- static SoftwareEngine instance;
- return instance;
- }
- SoftwareEngine::SoftwareEngine()
- : currentTime(0), nextTaskId(1) {
- // Initialisation si nécessaire
- }
- void SoftwareEngine::Start() {
- while (true) {
- std::vector<Task*> tasksToExecute;
- Task* nextTask = nullptr;
- // Vérifier les tâches prêtes et déterminer la prochaine tâche
- CheckTasks(tasksToExecute, nextTask);
- if (!tasksToExecute.empty()) {
- ExecuteTasks(tasksToExecute);
- } else if (nextTask) {
- ExecuteNextTask(nextTask);
- }
- }
- }
- void SoftwareEngine::AddTask(boost::function<void()> func, uint32_t intervalMicros) {
- int newId = GenerateUniqueTaskId();
- Task newTask = { newId, func, intervalMicros, currentTime + intervalMicros };
- taskList.push_back(newTask);
- }
- void SoftwareEngine::RemoveTask(boost::function<void()> func) {
- int taskId = -1;
- for (const auto& task : taskList) {
- if (task.func.target<void()>() == func.target<void()>()) {
- taskId = task.id;
- break;
- }
- }
- if (taskId != -1) {
- RemoveTaskById(taskId);
- }
- }
- void SoftwareEngine::ModifyTaskInterval(boost::function<void()> func, uint32_t newIntervalMicros) {
- for (auto& task : taskList) {
- if (task.func.target<void()>() == func.target<void()>()) {
- task.intervalMicros = newIntervalMicros;
- task.nextExecution = currentTime + newIntervalMicros;
- break;
- }
- }
- }
- void SoftwareEngine::RemoveTaskById(int taskId) {
- taskList.erase(std::remove_if(taskList.begin(), taskList.end(),
- [taskId](const Task& t) { return t.id == taskId; }),
- taskList.end());
- }
- int SoftwareEngine::GenerateUniqueTaskId() {
- int newId = nextTaskId++;
- if (newId == std::numeric_limits<int>::max()) {
- nextTaskId = 1; // Réinitialiser l'ID si on atteint la limite maximale
- newId = nextTaskId++;
- }
- // Vérifier que l'ID n'est pas déjà utilisé
- auto it = std::find_if(taskList.begin(), taskList.end(),
- [newId](const Task& task) { return task.id == newId; });
- if (it != taskList.end()) {
- return GenerateUniqueTaskId(); // Recommencer si l'ID est déjà utilisé
- }
- return newId;
- }
- void SoftwareEngine::UpdateCurrentTime() {
- currentTime = GetCurrentTimeMicros();
- }
- uint64_t SoftwareEngine::GetCurrentTimeMicros() {
- auto now = boost::chrono::steady_clock::now();
- auto micros = boost::chrono::duration_cast<boost::chrono::microseconds>(now.time_since_epoch()).count();
- return static_cast<uint64_t>(micros);
- }
- void SoftwareEngine::CheckTasks(std::vector<Task*>& tasksToExecute, Task*& nextTask) {
- UpdateCurrentTime();
- uint64_t nextTime = UINT64_MAX;
- tasksToExecute.clear();
- nextTask = nullptr;
- for (auto& task : taskList) {
- if (task.nextExecution <= currentTime) {
- tasksToExecute.push_back(&task);
- } else if (task.nextExecution < nextTime) {
- nextTime = task.nextExecution;
- nextTask = &task;
- }
- }
- }
- void SoftwareEngine::ExecuteTasks(const std::vector<Task*>& tasksToExecute) {
- std::vector<int> tasksToRemoveIds;
- for (const auto& taskPtr : tasksToExecute) {
- taskPtr->func();
- if (taskPtr->intervalMicros == 0) {
- tasksToRemoveIds.push_back(taskPtr->id);
- } else {
- taskPtr->nextExecution = currentTime + taskPtr->intervalMicros;
- }
- }
- for (int taskId : tasksToRemoveIds) {
- RemoveTaskById(taskId);
- }
- }
- void SoftwareEngine::ExecuteNextTask(Task* nextTask) {
- uint64_t timeUntilNextExecution = nextTask->nextExecution - currentTime;
- // Fonction de sommeil adaptée à une plateforme monothread
- boost::this_thread::sleep_for(boost::chrono::microseconds(timeUntilNextExecution));
- UpdateCurrentTime();
- nextTask->func();
- if (nextTask->intervalMicros == 0) {
- RemoveTaskById(nextTask->id);
- } else {
- nextTask->nextExecution = currentTime + nextTask->intervalMicros;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement