@@ -85,7 +85,7 @@ struct ThreadJobType | |||||
class ThreadJob | class ThreadJob | ||||
{ | { | ||||
friend class ThreadManager; | |||||
friend class BaseThreadManager; | |||||
public: | public: | ||||
ThreadJob() { m_type = ThreadJobType::NONE; } | ThreadJob() { m_type = ThreadJobType::NONE; } | ||||
@@ -99,11 +99,14 @@ protected: | |||||
ThreadJobType m_type; | ThreadJobType m_type; | ||||
}; | }; | ||||
class ThreadManager : public Entity | |||||
//Base class for thread manager | |||||
class BaseThreadManager : public Entity | |||||
{ | { | ||||
public: | public: | ||||
ThreadManager(int thread_count); | |||||
~ThreadManager(); | |||||
BaseThreadManager(int thread_count); | |||||
~BaseThreadManager(); | |||||
char const *GetName() { return "<BaseThreadManager>"; } | |||||
//Initialize, Ticker::Ref and start the thread | //Initialize, Ticker::Ref and start the thread | ||||
bool Start(); | bool Start(); | ||||
@@ -111,15 +114,14 @@ public: | |||||
bool Stop(); | bool Stop(); | ||||
//Work stuff | //Work stuff | ||||
bool AddWork(ThreadJob* job); | bool AddWork(ThreadJob* job); | ||||
protected: | |||||
bool FetchResult(Array<ThreadJob*>& results); | bool FetchResult(Array<ThreadJob*>& results); | ||||
//Base thread work function | //Base thread work function | ||||
static void *BaseThreadWork(void* data); | static void *BaseThreadWork(void* data); | ||||
virtual void TickGame(float seconds); | virtual void TickGame(float seconds); | ||||
virtual void TreatResult(ThreadJob* result) { } | |||||
//Default behaviour : delete the job result | |||||
virtual void TreatResult(ThreadJob* result) { delete(result); } | |||||
char const *GetName() { return "<ThreadManager>"; } | |||||
protected: | |||||
/* Worker threads */ | /* Worker threads */ | ||||
int m_thread_count; | int m_thread_count; | ||||
Array<Thread*> m_threads; | Array<Thread*> m_threads; | ||||
@@ -128,6 +130,28 @@ protected: | |||||
Queue<ThreadJob*> m_resultqueue; | Queue<ThreadJob*> m_resultqueue; | ||||
Array<ThreadJob*> m_job_dispatch; | Array<ThreadJob*> m_job_dispatch; | ||||
}; | }; | ||||
//Generic class for thread manager, executes work and store results, for you to use | |||||
class GenericThreadManager : public BaseThreadManager | |||||
{ | |||||
public: | |||||
GenericThreadManager(int thread_count) | |||||
: BaseThreadManager(thread_count) { } | |||||
char const *GetName() { return "<GenericThreadManager>"; } | |||||
bool GetWorkResult(Array<ThreadJob*>& results) | |||||
{ | |||||
results += m_job_result; | |||||
m_job_result.Empty(); | |||||
return results.Count() > 0; | |||||
} | |||||
protected: | |||||
virtual void TreatResult(ThreadJob* result) { m_job_result << result; } | |||||
Array<ThreadJob*> m_job_result; | |||||
}; | |||||
#endif | #endif | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -19,17 +19,17 @@ namespace lol | |||||
{ | { | ||||
#if LOL_FEATURE_THREADS | #if LOL_FEATURE_THREADS | ||||
ThreadManager::ThreadManager(int thread_count) | |||||
BaseThreadManager::BaseThreadManager(int thread_count) | |||||
{ | { | ||||
m_thread_count = thread_count; | m_thread_count = thread_count; | ||||
} | } | ||||
ThreadManager::~ThreadManager() | |||||
BaseThreadManager::~BaseThreadManager() | |||||
{ | { | ||||
Stop(); | Stop(); | ||||
} | } | ||||
//Initialize, Ticker::Ref and start the thread | //Initialize, Ticker::Ref and start the thread | ||||
bool ThreadManager::Start() | |||||
bool BaseThreadManager::Start() | |||||
{ | { | ||||
if (m_threads.Count() > 0) | if (m_threads.Count() > 0) | ||||
return false; | return false; | ||||
@@ -45,7 +45,7 @@ bool ThreadManager::Start() | |||||
} | } | ||||
//Stop the threads | //Stop the threads | ||||
bool ThreadManager::Stop() | |||||
bool BaseThreadManager::Stop() | |||||
{ | { | ||||
if (m_threads.Count() <= 0) | if (m_threads.Count() <= 0) | ||||
return false; | return false; | ||||
@@ -62,13 +62,13 @@ bool ThreadManager::Stop() | |||||
} | } | ||||
//Work stuff | //Work stuff | ||||
bool ThreadManager::AddWork(ThreadJob* job) | |||||
bool BaseThreadManager::AddWork(ThreadJob* job) | |||||
{ | { | ||||
if (m_jobqueue.TryPush(job)) | if (m_jobqueue.TryPush(job)) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
bool ThreadManager::FetchResult(Array<ThreadJob*>& results) | |||||
bool BaseThreadManager::FetchResult(Array<ThreadJob*>& results) | |||||
{ | { | ||||
ThreadJob* result; | ThreadJob* result; | ||||
while (m_resultqueue.TryPop(result)) | while (m_resultqueue.TryPop(result)) | ||||
@@ -77,9 +77,9 @@ bool ThreadManager::FetchResult(Array<ThreadJob*>& results) | |||||
} | } | ||||
//Base thread work function | //Base thread work function | ||||
void *ThreadManager::BaseThreadWork(void* data) | |||||
void *BaseThreadManager::BaseThreadWork(void* data) | |||||
{ | { | ||||
ThreadManager *that = (ThreadManager *)data; | |||||
BaseThreadManager *that = (BaseThreadManager *)data; | |||||
that->m_spawnqueue.Push(ThreadStatus::THREAD_STARTED); | that->m_spawnqueue.Push(ThreadStatus::THREAD_STARTED); | ||||
for ( ; ; ) | for ( ; ; ) | ||||
{ | { | ||||
@@ -99,7 +99,7 @@ void *ThreadManager::BaseThreadWork(void* data) | |||||
return NULL; | return NULL; | ||||
} | } | ||||
void ThreadManager::TickGame(float seconds) | |||||
void BaseThreadManager::TickGame(float seconds) | |||||
{ | { | ||||
//Start if needed | //Start if needed | ||||
Start(); | Start(); | ||||
@@ -117,7 +117,6 @@ void ThreadManager::TickGame(float seconds) | |||||
ThreadJob* job = result[i]; | ThreadJob* job = result[i]; | ||||
if (job->GetJobType() == ThreadJobType::WORK_DONE) | if (job->GetJobType() == ThreadJobType::WORK_DONE) | ||||
TreatResult(job); | TreatResult(job); | ||||
delete(job); | |||||
} | } | ||||
} | } | ||||
} | } | ||||