first iteration of the Provider and Task classes
This commit is contained in:
parent
8b42ba055b
commit
0c54d5e37b
@ -5,7 +5,7 @@ set(VERSION_MAJOR 0)
|
|||||||
set(VERSION_MINOR 1)
|
set(VERSION_MINOR 1)
|
||||||
|
|
||||||
# choose source file
|
# choose source file
|
||||||
file(GLOB LIB_SRC_LIST src/property.cpp src/serializable.cpp src/serializationmanager.cpp)
|
file(GLOB LIB_SRC_LIST src/property.cpp src/serializable.cpp src/serializationmanager.cpp src/taskmanager.cpp src/provider.cpp)
|
||||||
file(GLOB LIB_HEAD_LIST src/*.h)
|
file(GLOB LIB_HEAD_LIST src/*.h)
|
||||||
set(EXEC_SRC_LIST src/main.cpp)
|
set(EXEC_SRC_LIST src/main.cpp)
|
||||||
|
|
||||||
|
2
src/provider.cpp
Normal file
2
src/provider.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "provider.h"
|
||||||
|
|
41
src/provider.h
Normal file
41
src/provider.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#ifndef PROVIDER_H
|
||||||
|
#define PROVIDER_H
|
||||||
|
|
||||||
|
#include "serializable.h"
|
||||||
|
|
||||||
|
#include "taskmanager.h"
|
||||||
|
|
||||||
|
class AbstractProvider : public Serializable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Task* getTask() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Provider : public AbstractProvider
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
struct ProviderTask : public Task
|
||||||
|
{
|
||||||
|
T* m_object = nullptr;
|
||||||
|
int m_progress = 0;
|
||||||
|
int m_flags;
|
||||||
|
std::string m_providerName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This should be overloaded
|
||||||
|
*/
|
||||||
|
virtual void performTask() { m_object = new T(); m_progress = 1; }
|
||||||
|
|
||||||
|
virtual int getProgressInt() { }
|
||||||
|
virtual Task::TaskTypeFlags getFlags() { return m_flags; }
|
||||||
|
virtual const std::string &getLabel() { return m_providerName; }
|
||||||
|
};
|
||||||
|
|
||||||
|
ProviderTask m_task;
|
||||||
|
public:
|
||||||
|
virtual Task* getTask() { return (Task*)&m_task; }
|
||||||
|
virtual T* provide() { return m_task.m_object; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PROVIDER_H
|
129
src/taskmanager.cpp
Normal file
129
src/taskmanager.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#include "taskmanager.h"
|
||||||
|
|
||||||
|
// TASK THREAD
|
||||||
|
TaskThread::~TaskThread()
|
||||||
|
{
|
||||||
|
waitUntilOver();
|
||||||
|
for(std::thread * t : m_threads)
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskThread::addTask(Task* task)
|
||||||
|
{
|
||||||
|
m_tasks.push_back(task);
|
||||||
|
++m_totalTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskThread::start(int nbThreads)
|
||||||
|
{
|
||||||
|
for(int i=0; i<nbThreads; ++i)
|
||||||
|
{
|
||||||
|
std::thread *thread = new std::thread(&TaskThread::run, this, i);
|
||||||
|
m_currentTasks.push_back(nullptr);
|
||||||
|
m_threads.push_back(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskThread::run(int id)
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
while(!m_tasks.empty())
|
||||||
|
{
|
||||||
|
m_currentTasks[id] = m_tasks.front();
|
||||||
|
m_tasks.pop_front();
|
||||||
|
|
||||||
|
m_mutex.unlock();
|
||||||
|
m_currentTasks[id]->performTask();
|
||||||
|
m_mutex.lock();
|
||||||
|
|
||||||
|
delete m_currentTasks[id];
|
||||||
|
m_currentTasks[id] = nullptr;
|
||||||
|
++m_tasksPerformed;
|
||||||
|
}
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskThread::waitUntilOver()
|
||||||
|
{
|
||||||
|
for(std::thread * t : m_threads)
|
||||||
|
t->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TaskThread::isOver()
|
||||||
|
{
|
||||||
|
return m_tasksPerformed == m_totalTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TaskThread::getProgressProportion()
|
||||||
|
{
|
||||||
|
float progress = 1.f;
|
||||||
|
m_mutex.lock();
|
||||||
|
if(!isOver())
|
||||||
|
{
|
||||||
|
progress = m_tasksPerformed;
|
||||||
|
for(Task* t : m_currentTasks)
|
||||||
|
{
|
||||||
|
if(t != nullptr)
|
||||||
|
progress += t->getProgressProportion();
|
||||||
|
}
|
||||||
|
progress /= m_totalTasks;
|
||||||
|
}
|
||||||
|
m_mutex.unlock();
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TASK MANAGER
|
||||||
|
void TaskManager::addTask(Task* task)
|
||||||
|
{
|
||||||
|
int flags = task->getFlags();
|
||||||
|
if(flags & Task::GPU)
|
||||||
|
m_gpuTasks.addTask(task);
|
||||||
|
else if(flags & Task::HDD)
|
||||||
|
m_hddTasks.addTask(task);
|
||||||
|
else if(flags & Task::NET)
|
||||||
|
m_netTasks.addTask(task);
|
||||||
|
else
|
||||||
|
m_cpuTasks.addTask(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskManager::start()
|
||||||
|
{
|
||||||
|
m_hddTasks.start(1); // Reading multiple files simultaneously makes no sense
|
||||||
|
m_cpuTasks.start(4);
|
||||||
|
m_gpuTasks.start(1); // GPU tasks must be regouped on only one thread to easily have access to an OpenGL context
|
||||||
|
m_netTasks.start(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskManager::waitUntilOver()
|
||||||
|
{
|
||||||
|
m_hddTasks.waitUntilOver();
|
||||||
|
m_cpuTasks.waitUntilOver();
|
||||||
|
m_gpuTasks.waitUntilOver();
|
||||||
|
m_netTasks.waitUntilOver();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TaskManager::isOver()
|
||||||
|
{
|
||||||
|
return m_hddTasks.isOver()
|
||||||
|
&& m_cpuTasks.isOver()
|
||||||
|
&& m_gpuTasks.isOver()
|
||||||
|
&& m_netTasks.isOver();
|
||||||
|
}
|
||||||
|
|
||||||
|
float TaskManager::getProgress(int flags)
|
||||||
|
{
|
||||||
|
float progress = 0;
|
||||||
|
int nbTypes = 0;
|
||||||
|
if(flags & Task::GPU)
|
||||||
|
progress += m_gpuTasks.getProgressProportion(), ++nbTypes;
|
||||||
|
else if(flags & Task::HDD)
|
||||||
|
progress += m_hddTasks.getProgressProportion(), ++nbTypes;
|
||||||
|
else if(flags & Task::NET)
|
||||||
|
progress += m_netTasks.getProgressProportion(), ++nbTypes;
|
||||||
|
else
|
||||||
|
progress += m_cpuTasks.getProgressProportion(), ++nbTypes;
|
||||||
|
if(nbTypes != 0)
|
||||||
|
return progress/nbTypes;
|
||||||
|
else
|
||||||
|
return 1.f;
|
||||||
|
}
|
66
src/taskmanager.h
Normal file
66
src/taskmanager.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef TASKMANAGER_H
|
||||||
|
#define TASKMANAGER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
class Task
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum TaskTypeFlags
|
||||||
|
{
|
||||||
|
HDD, // saving of loading to the file system
|
||||||
|
CPU, // computing something
|
||||||
|
GPU, // computing something on the GPU or transferring data between the RAM and the GPU RAM
|
||||||
|
NET // sending or receiving from the network
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void performTask() = 0;
|
||||||
|
|
||||||
|
virtual int getProgressInt() = 0;
|
||||||
|
virtual int getProgressTotal() { return 1; }
|
||||||
|
virtual float getProgressProportion() { return float(getProgressInt())/float(getProgressTotal()); }
|
||||||
|
|
||||||
|
virtual TaskTypeFlags getFlags() = 0;
|
||||||
|
virtual const std::string &getLabel() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskThread
|
||||||
|
{
|
||||||
|
std::list<Task*> m_tasks;
|
||||||
|
std::vector<std::thread*> m_threads;
|
||||||
|
std::vector<Task*> m_currentTasks;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
int m_tasksPerformed;
|
||||||
|
int m_totalTasks;
|
||||||
|
|
||||||
|
void run(int id);
|
||||||
|
public:
|
||||||
|
~TaskThread();
|
||||||
|
|
||||||
|
void addTask(Task* task);
|
||||||
|
void start(int nbThreads = 1);
|
||||||
|
void waitUntilOver();
|
||||||
|
bool isOver();
|
||||||
|
float getProgressProportion();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaskManager
|
||||||
|
{
|
||||||
|
TaskThread m_hddTasks;
|
||||||
|
TaskThread m_cpuTasks;
|
||||||
|
TaskThread m_gpuTasks;
|
||||||
|
TaskThread m_netTasks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void addTask(Task* task);
|
||||||
|
void start();
|
||||||
|
void waitUntilOver();
|
||||||
|
bool isOver();
|
||||||
|
float getProgress(int flags = Task::CPU | Task::GPU | Task::HDD | Task::NET);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TASKMANAGER_H
|
Loading…
x
Reference in New Issue
Block a user