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)
|
||||
|
||||
# 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)
|
||||
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