Newer
Older
Import / applications / HighwayDash / ports / Framework / Tasks.h
//  BlockyFroggy
//  Copyright © 2017 John Ryland.
//  All rights reserved.
#pragma once
#ifndef TASKS_H
#define TASKS_H


#include <functional>
#include <string>
#include <memory>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <thread>


class Task
{
public:
  explicit Task(std::string a_name) : m_name(a_name) {}
  virtual ~Task() = 0;
  virtual void process() = 0;
  virtual void continuation() = 0;
private:
  std::string m_name;
};


template <typename T>
class GenericTask : public Task
{
public:
  GenericTask(std::string a_name, std::function<T()> a_process, std::function<void(T)> a_cont)
    : Task(a_name)
    , m_process(a_process)
    , m_cont(a_cont)
  {
  }
  ~GenericTask() override
  {
  }
  void process() override
  {
    m_return = m_process();
  }
  void continuation() override
  {
    m_cont(m_return);
  }
private:
  T m_return;
  std::function<T()> m_process;
  std::function<void(T)> m_cont;
};


class TaskManager
{
public:
  TaskManager(size_t a_numberOfThreads);
  ~TaskManager();
  void update();
  void queueTask(std::unique_ptr<Task> t);
private:
  std::queue<std::unique_ptr<Task>>   m_queuedTasks;
  std::queue<std::unique_ptr<Task>>   m_pendingContinuation;
  std::mutex                          m_mutex;
  std::condition_variable             m_cond;
  std::atomic<bool>                   m_running;
  std::vector<std::thread>            m_threads;
};


#endif // TASKS_H