From 34492d909693c1aa306b1bf1e8ca8cce2632afc2 Mon Sep 17 00:00:00 2001 From: xawotihs Date: Mon, 3 Feb 2014 23:08:17 +0100 Subject: [PATCH] Adds Threading implementation on SDL --- JGE/include/Threading.h | 222 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 221 insertions(+), 1 deletion(-) diff --git a/JGE/include/Threading.h b/JGE/include/Threading.h index 73036a27d..b08ce582c 100644 --- a/JGE/include/Threading.h +++ b/JGE/include/Threading.h @@ -1,7 +1,7 @@ #ifndef THREADING_H #define THREADING_H -#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L) +#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L) && !defined(SDL_CONFIG) #include #ifdef WIN32 @@ -611,6 +611,226 @@ namespace boost } } +#elif defined(SDL_CONFIG) +#include "SDL_thread.h" +#include "SDL_timer.h" + +#include +#include + +#include "../include/JLogger.h" + +namespace boost +{ + template + struct unique_lock + { + unique_lock(Mutex& inMutex) : mMutex(&inMutex) + { + mMutex->lock(); + } + + ~unique_lock() + { + mMutex->unlock(); + } + + Mutex* mMutex; + }; + + class mutex + { + public: + + typedef unique_lock scoped_lock; + + mutex() + : mpSDLMutex(0) + { + mpSDLMutex = SDL_CreateMutex(); + } + + ~mutex() + { + SDL_DestroyMutex(mpSDLMutex); + } + + void lock() + { + SDL_mutexP(mpSDLMutex); + } + + void unlock() + { + SDL_mutexV(mpSDLMutex); + } + + SDL_mutex* mpSDLMutex; + + private: + mutex(mutex const&); + mutex& operator=(mutex const&); + }; + + + + class recursive_mutex + { + public: + + typedef unique_lock scoped_lock; + + recursive_mutex() + : mpSDLMutex(0) + { + mpSDLMutex = SDL_CreateMutex(); + } + + ~recursive_mutex() + { + SDL_DestroyMutex(mpSDLMutex); + } + + void lock() + { + SDL_mutexP(mpSDLMutex); + } + + void unlock() + { + SDL_mutexV(mpSDLMutex); + } + + SDL_mutex* mpSDLMutex; + + private: + recursive_mutex(recursive_mutex const&); + recursive_mutex& operator=(recursive_mutex const&); + }; + + + /** + ** Emulating boost::thread configuration glue, with some shortcuts + ** This detail namespace is a distillation of boost's thread.hpp, thread_data.hpp. + */ + namespace detail + { + struct thread_data_base + { + thread_data_base() + { + } + + virtual ~thread_data_base() + { + } + + virtual void run() = 0; + }; + + typedef boost::shared_ptr thread_data_ptr; + + template + class thread_data : public detail::thread_data_base + { + public: + thread_data(F f_) : f(f_) + { + } + + void run() + { + f(); + } + + private: + F f; + + void operator=(thread_data&); + thread_data(thread_data&); + }; + + } //namespace detail + + /** + ** A simplistic implementation of boost::thread, using QThread. + ** + */ + class thread + { + /* + ** Helper class for sceKernelStartThread, which passes args by value, not by reference + ** We use this struct to wrap any pointers that we want to pass to the worker thread. + */ + struct CallbackData + { + CallbackData(detail::thread_data_ptr inThreadInfo) + : mThreadInfo(inThreadInfo) + { + } + + detail::thread_data_ptr mThreadInfo; + }; + + public: + + thread() + { + } + + template + thread(F f, A1 a1) : mThreadInfo(make_thread_info(boost::bind(boost::type(), f, a1))) + { + mpSDLThread = SDL_CreateThread(ThreadProc, &mThreadInfo); + } + + ~thread() + { + } + + void join() + { + int status; + SDL_WaitThread(mpSDLThread, &status); + } + + private: + static int ThreadProc(void *inParam) + { + detail::thread_data_ptr* threadInfo = reinterpret_cast(inParam); + CallbackData callbackData(*threadInfo); + + LOG("Entering thread::ThreadProc"); + callbackData.mThreadInfo->run(); + return 0; + } + + template + static inline detail::thread_data_ptr make_thread_info(F f) + { + return detail::thread_data_ptr(new detail::thread_data(f)); + } + + detail::thread_data_ptr mThreadInfo; + SDL_Thread* mpSDLThread; + }; + + namespace posix_time + { + typedef unsigned int milliseconds; + } + + /** + ** boost's platform neutral sleep call. + */ + namespace this_thread + { + inline void sleep(boost::posix_time::milliseconds const& time) + { + SDL_Delay(time); + } + } +} #endif #endif // THREADING_H