aboutsummaryrefslogtreecommitdiff
path: root/src/3rdParty/efsw/Thread.hpp
blob: b60373c2075c53c9e1fdf825f2dfa73c6f7afd7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#ifndef EFSW_THREAD_HPP
#define EFSW_THREAD_HPP

#include <efsw/base.hpp>

namespace efsw {

namespace Platform {
class ThreadImpl;
}
namespace Private {
struct ThreadFunc;
}

/** @brief Thread manager class */
class Thread {
  public:
	typedef void ( *FuncType )( void* );

	template <typename F> Thread( F function );

	template <typename F, typename A> Thread( F function, A argument );

	template <typename C> Thread( void ( C::*function )(), C* object );

	virtual ~Thread();

	/** Launch the thread */
	virtual void launch();

	/** Wait the thread until end */
	void wait();

	/** Terminate the thread */
	void terminate();

  protected:
	Thread();

  private:
	friend class Platform::ThreadImpl;

	/** The virtual function to run in the thread */
	virtual void run();

	Platform::ThreadImpl* mThreadImpl; ///< OS-specific implementation of the thread
	Private::ThreadFunc* mEntryPoint;  ///< Abstraction of the function to run
};

//! NOTE: Taken from SFML2 threads
namespace Private {

// Base class for abstract thread functions
struct ThreadFunc {
	virtual ~ThreadFunc() {}
	virtual void run() = 0;
};

// Specialization using a functor (including free functions) with no argument
template <typename T> struct ThreadFunctor : ThreadFunc {
	ThreadFunctor( T functor ) : m_functor( functor ) {}
	virtual void run() { m_functor(); }
	T m_functor;
};

// Specialization using a functor (including free functions) with one argument
template <typename F, typename A> struct ThreadFunctorWithArg : ThreadFunc {
	ThreadFunctorWithArg( F function, A arg ) : m_function( function ), m_arg( arg ) {}
	virtual void run() { m_function( m_arg ); }
	F m_function;
	A m_arg;
};

// Specialization using a member function
template <typename C> struct ThreadMemberFunc : ThreadFunc {
	ThreadMemberFunc( void ( C::*function )(), C* object ) :
		m_function( function ), m_object( object ) {}
	virtual void run() { ( m_object->*m_function )(); }
	void ( C::*m_function )();
	C* m_object;
};

} // namespace Private

template <typename F>
Thread::Thread( F functor ) :
	mThreadImpl( NULL ), mEntryPoint( new Private::ThreadFunctor<F>( functor ) ) {}

template <typename F, typename A>
Thread::Thread( F function, A argument ) :
	mThreadImpl( NULL ),
	mEntryPoint( new Private::ThreadFunctorWithArg<F efCOMMA A>( function, argument ) ) {}

template <typename C>
Thread::Thread( void ( C::*function )(), C* object ) :
	mThreadImpl( NULL ), mEntryPoint( new Private::ThreadMemberFunc<C>( function, object ) ) {}

} // namespace efsw

#endif