Removed dependencies to OS-specific headers in sfml-system

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1023 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-02-27 15:03:20 +00:00
parent 2228419caf
commit 9a7fcc04be
21 changed files with 531 additions and 306 deletions

View File

@ -655,7 +655,8 @@ EXCLUDE_PATTERNS = .svn \
Linux \ Linux \
Unix \ Unix \
Attic \ Attic \
OSX* OSX* \
Win32
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the # (namespaces, classes, functions, etc.) that should be excluded from the

View File

@ -105,18 +105,20 @@
<Unit filename="..\..\include\SFML\System\Vector2.inl" /> <Unit filename="..\..\include\SFML\System\Vector2.inl" />
<Unit filename="..\..\include\SFML\System\Vector3.hpp" /> <Unit filename="..\..\include\SFML\System\Vector3.hpp" />
<Unit filename="..\..\include\SFML\System\Vector3.inl" /> <Unit filename="..\..\include\SFML\System\Vector3.inl" />
<Unit filename="..\..\include\SFML\System\Win32\Mutex.hpp" />
<Unit filename="..\..\include\SFML\System\Win32\Thread.hpp" />
<Unit filename="..\..\src\SFML\System\Clock.cpp" /> <Unit filename="..\..\src\SFML\System\Clock.cpp" />
<Unit filename="..\..\src\SFML\System\Lock.cpp" /> <Unit filename="..\..\src\SFML\System\Lock.cpp" />
<Unit filename="..\..\src\SFML\System\Mutex.cpp" />
<Unit filename="..\..\src\SFML\System\Platform.hpp" /> <Unit filename="..\..\src\SFML\System\Platform.hpp" />
<Unit filename="..\..\src\SFML\System\Randomizer.cpp" /> <Unit filename="..\..\src\SFML\System\Randomizer.cpp" />
<Unit filename="..\..\src\SFML\System\Sleep.cpp" /> <Unit filename="..\..\src\SFML\System\Sleep.cpp" />
<Unit filename="..\..\src\SFML\System\Thread.cpp" />
<Unit filename="..\..\src\SFML\System\Unicode.cpp" /> <Unit filename="..\..\src\SFML\System\Unicode.cpp" />
<Unit filename="..\..\src\SFML\System\Win32\Mutex.cpp" /> <Unit filename="..\..\src\SFML\System\Win32\MutexImpl.cpp" />
<Unit filename="..\..\src\SFML\System\Win32\MutexImpl.hpp" />
<Unit filename="..\..\src\SFML\System\Win32\Platform.cpp" /> <Unit filename="..\..\src\SFML\System\Win32\Platform.cpp" />
<Unit filename="..\..\src\SFML\System\Win32\Platform.hpp" /> <Unit filename="..\..\src\SFML\System\Win32\Platform.hpp" />
<Unit filename="..\..\src\SFML\System\Win32\Thread.cpp" /> <Unit filename="..\..\src\SFML\System\Win32\ThreadImpl.cpp" />
<Unit filename="..\..\src\SFML\System\Win32\ThreadImpl.hpp" />
<Extensions> <Extensions>
<code_completion /> <code_completion />
<envvars /> <envvars />

View File

@ -342,11 +342,11 @@
Name="Win32" Name="Win32"
> >
<File <File
RelativePath="..\..\src\SFML\System\Win32\Mutex.cpp" RelativePath="..\..\src\SFML\System\Win32\MutexImpl.cpp"
> >
</File> </File>
<File <File
RelativePath="..\..\include\SFML\System\Win32\Mutex.hpp" RelativePath="..\..\src\SFML\System\Win32\MutexImpl.hpp"
> >
</File> </File>
<File <File
@ -358,11 +358,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\SFML\System\Win32\Thread.cpp" RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.cpp"
> >
</File> </File>
<File <File
RelativePath="..\..\include\SFML\System\Win32\Thread.hpp" RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.hpp"
> >
</File> </File>
</Filter> </Filter>
@ -382,6 +382,46 @@
RelativePath="..\..\include\SFML\System\Lock.hpp" RelativePath="..\..\include\SFML\System\Lock.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\System\Mutex.cpp"
>
<FileConfiguration
Name="Debug DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Release DLL|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug static|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
<FileConfiguration
Name="Release static|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\..\include\SFML\System\Mutex.hpp" RelativePath="..\..\include\SFML\System\Mutex.hpp"
> >
@ -422,6 +462,10 @@
RelativePath="..\..\include\SFML\System\Sleep.hpp" RelativePath="..\..\include\SFML\System\Sleep.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\System\Thread.cpp"
>
</File>
<File <File
RelativePath="..\..\include\SFML\System\Thread.hpp" RelativePath="..\..\include\SFML\System\Thread.hpp"
> >

View File

@ -335,11 +335,11 @@
Name="Win32" Name="Win32"
> >
<File <File
RelativePath="..\..\src\SFML\System\Win32\Mutex.cpp" RelativePath="..\..\src\SFML\System\Win32\MutexImpl.cpp"
> >
</File> </File>
<File <File
RelativePath="..\..\src\SFML\System\Win32\Mutex.hpp" RelativePath="..\..\src\SFML\System\Win32\MutexImpl.hpp"
> >
</File> </File>
<File <File
@ -351,11 +351,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\src\SFML\System\Win32\Thread.cpp" RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.cpp"
> >
</File> </File>
<File <File
RelativePath="..\..\src\SFML\System\Win32\Thread.hpp" RelativePath="..\..\src\SFML\System\Win32\ThreadImpl.hpp"
> >
</File> </File>
</Filter> </Filter>
@ -375,6 +375,10 @@
RelativePath="..\..\src\SFML\System\Lock.hpp" RelativePath="..\..\src\SFML\System\Lock.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\System\Mutex.cpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\System\Mutex.hpp" RelativePath="..\..\src\SFML\System\Mutex.hpp"
> >
@ -415,6 +419,10 @@
RelativePath="..\..\src\SFML\System\Sleep.hpp" RelativePath="..\..\src\SFML\System\Sleep.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\SFML\System\Thread.cpp"
>
</File>
<File <File
RelativePath="..\..\src\SFML\System\Thread.hpp" RelativePath="..\..\src\SFML\System\Thread.hpp"
> >

View File

@ -29,17 +29,59 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Config.hpp> #include <SFML/Config.hpp>
#include <SFML/System/NonCopyable.hpp>
#ifdef SFML_SYSTEM_WINDOWS namespace sf
{
namespace priv
{
class MutexImpl;
}
#include <SFML/System/Win32/Mutex.hpp> ////////////////////////////////////////////////////////////
/// Mutex defines a mutex (MUTual EXclusion) object,
/// that allows a thread to lock critical instructions
/// to avoid simultaneous access with other threads.
/// See Lock for an efficient way of using it.
////////////////////////////////////////////////////////////
class SFML_API Mutex : NonCopyable
{
public :
#else ////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Mutex();
#include <SFML/System/Unix/Mutex.hpp> ////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~Mutex();
#endif ////////////////////////////////////////////////////////////
/// Lock the mutex
///
////////////////////////////////////////////////////////////
void Lock();
////////////////////////////////////////////////////////////
/// Unlock the mutex
///
////////////////////////////////////////////////////////////
void Unlock();
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::MutexImpl* myMutexImpl; ///< OS-specific implementation
};
} // namespace sf
#endif // SFML_MUTEX_HPP #endif // SFML_MUTEX_HPP

View File

@ -79,13 +79,6 @@ public :
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static int Random(int Begin, int End); static int Random(int Begin, int End);
private :
////////////////////////////////////////////////////////////
// Static member variables
////////////////////////////////////////////////////////////
static unsigned int ourSeed;
}; };
} // namespace sf } // namespace sf

View File

@ -33,13 +33,13 @@
namespace sf namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Make the current thread sleep for a given time /// Make the current thread sleep for a given time
/// ///
/// \param Duration : Time to sleep, in seconds (must be >= 0) /// \param Duration : Time to sleep, in seconds (must be >= 0)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void SFML_API Sleep(float Duration); void SFML_API Sleep(float Duration);
} // namespace sf } // namespace sf

View File

@ -29,17 +29,93 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Config.hpp> #include <SFML/Config.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <cstdlib>
#ifdef SFML_SYSTEM_WINDOWS namespace sf
{
namespace priv
{
class ThreadImpl;
}
#include <SFML/System/Win32/Thread.hpp> ////////////////////////////////////////////////////////////
/// Thread defines an easy way to manipulate a thread.
/// There are two ways to use Thread :
/// - Inherit from it and override the Run() virtual function
/// - Construct a Thread instance and pass it a function
/// pointer to call
////////////////////////////////////////////////////////////
class SFML_API Thread : NonCopyable
{
public :
#else typedef void (*FuncType)(void*);
#include <SFML/System/Unix/Thread.hpp> ////////////////////////////////////////////////////////////
/// Construct the thread from a function pointer
///
/// \param Function : Entry point of the thread
/// \param UserData : Data to pass to the thread function (NULL by default)
///
////////////////////////////////////////////////////////////
Thread(FuncType Function, void* UserData = NULL);
#endif ////////////////////////////////////////////////////////////
/// Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Thread();
////////////////////////////////////////////////////////////
/// Create and run the thread
///
////////////////////////////////////////////////////////////
void Launch();
////////////////////////////////////////////////////////////
/// Wait until the thread finishes
///
////////////////////////////////////////////////////////////
void Wait();
////////////////////////////////////////////////////////////
/// Terminate the thread
/// Terminating a thread with this function is not safe,
/// you should rather try to make the thread function
/// terminate by itself
///
////////////////////////////////////////////////////////////
void Terminate();
protected :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Thread();
private :
friend class priv::ThreadImpl;
////////////////////////////////////////////////////////////
/// Function called as the thread entry point
///
////////////////////////////////////////////////////////////
virtual void Run();
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
priv::ThreadImpl* myThreadImpl; ///< OS-specific implementation of the thread
FuncType myFunction; ///< Function to call as the thread entry point
void* myUserData; ///< Data to pass to the thread function
};
} // namespace sf
#endif // SFML_THREAD_HPP #endif // SFML_THREAD_HPP

View File

@ -31,11 +31,11 @@ void PlaySound()
// Loop while the sound is playing // Loop while the sound is playing
while (Sound.GetStatus() == sf::Sound::Playing) while (Sound.GetStatus() == sf::Sound::Playing)
{ {
// Display the playing position
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << Sound.GetPlayingOffset() << " sec ";
// Leave some CPU time for other processes // Leave some CPU time for other processes
sf::Sleep(0.1f); sf::Sleep(0.1f);
// Display the playing position
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << Sound.GetPlayingOffset() << " sec ";
} }
std::cout << std::endl << std::endl; std::cout << std::endl << std::endl;
} }
@ -64,11 +64,11 @@ void PlayMusic()
// Loop while the music is playing // Loop while the music is playing
while (Music.GetStatus() == sf::Music::Playing) while (Music.GetStatus() == sf::Music::Playing)
{ {
// Display the playing position
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << Music.GetPlayingOffset() << " sec ";
// Leave some CPU time for other processes // Leave some CPU time for other processes
sf::Sleep(0.1f); sf::Sleep(0.1f);
// Display the playing position
std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << Music.GetPlayingOffset() << " sec ";
} }
std::cout << std::endl; std::cout << std::endl;
} }

View File

@ -25,7 +25,18 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Win32/Mutex.hpp> #include <SFML/System/Mutex.hpp>
#if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/System/Win32/MutexImpl.hpp>
#else
#include <SFML/System/Unix/MutexImpl.hpp>
#endif
namespace sf namespace sf
@ -35,7 +46,7 @@ namespace sf
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex::Mutex() Mutex::Mutex()
{ {
InitializeCriticalSection(&myHandle); myMutexImpl = new priv::MutexImpl;
} }
@ -44,7 +55,7 @@ Mutex::Mutex()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex::~Mutex() Mutex::~Mutex()
{ {
DeleteCriticalSection(&myHandle); delete myMutexImpl;
} }
@ -53,7 +64,7 @@ Mutex::~Mutex()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Mutex::Lock() void Mutex::Lock()
{ {
EnterCriticalSection(&myHandle); myMutexImpl->Lock();
} }
@ -62,7 +73,7 @@ void Mutex::Lock()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Mutex::Unlock() void Mutex::Unlock()
{ {
LeaveCriticalSection(&myHandle); myMutexImpl->Unlock();
} }
} // namespace sf } // namespace sf

View File

@ -35,7 +35,7 @@
#include <SFML/System/Win32/Platform.hpp> #include <SFML/System/Win32/Platform.hpp>
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_MACOS) || defined(SFML_SYSTEM_FREEBSD) #else
#include <SFML/System/Unix/Platform.hpp> #include <SFML/System/Unix/Platform.hpp>

View File

@ -33,23 +33,20 @@
namespace namespace
{ {
// Set the random numbers sequence seed with the current system time, so that it is always different // Set the random numbers sequence seed with the current system time, so that it is always different
unsigned int SetRandomSeed() unsigned int InitializeSeed()
{ {
unsigned int Seed = static_cast<unsigned int>(sf::priv::Platform::GetSystemTime() * 1000); unsigned int Seed = static_cast<unsigned int>(sf::priv::Platform::GetSystemTime() * 1000);
srand(Seed); srand(Seed);
return Seed; return Seed;
} }
// Global storing the current seed
unsigned int GlobalSeed = InitializeSeed();
} }
namespace sf namespace sf
{ {
////////////////////////////////////////////////////////////
// Static member variables
////////////////////////////////////////////////////////////
unsigned int Randomizer::ourSeed = SetRandomSeed();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Set the seed for the generator. Using a known seed /// Set the seed for the generator. Using a known seed
/// allows you to reproduce the same sequence of random number /// allows you to reproduce the same sequence of random number
@ -57,7 +54,7 @@ unsigned int Randomizer::ourSeed = SetRandomSeed();
void Randomizer::SetSeed(unsigned int Seed) void Randomizer::SetSeed(unsigned int Seed)
{ {
srand(Seed); srand(Seed);
ourSeed = Seed; GlobalSeed = Seed;
} }
@ -66,7 +63,7 @@ void Randomizer::SetSeed(unsigned int Seed)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int Randomizer::GetSeed() unsigned int Randomizer::GetSeed()
{ {
return ourSeed; return GlobalSeed;
} }

View File

@ -25,9 +25,18 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Win32/Thread.hpp> #include <SFML/System/Thread.hpp>
#include <process.h>
#include <iostream>
#if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/System/Win32/ThreadImpl.hpp>
#else
#include <SFML/System/Unix/ThreadImpl.hpp>
#endif
namespace sf namespace sf
@ -36,9 +45,9 @@ namespace sf
/// Default constructor /// Default constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Thread::Thread() : Thread::Thread() :
myHandle (NULL), myThreadImpl(NULL),
myFunction(NULL), myFunction (NULL),
myUserData(NULL) myUserData (NULL)
{ {
} }
@ -48,9 +57,9 @@ myUserData(NULL)
/// Construct the thread from a function pointer /// Construct the thread from a function pointer
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Thread::Thread(Thread::FuncType Function, void* UserData) : Thread::Thread(Thread::FuncType Function, void* UserData) :
myHandle (NULL), myThreadImpl(NULL),
myFunction(Function), myFunction (Function),
myUserData(UserData) myUserData (UserData)
{ {
} }
@ -62,8 +71,10 @@ myUserData(UserData)
Thread::~Thread() Thread::~Thread()
{ {
// Wait for the thread to finish before destroying the instance // Wait for the thread to finish before destroying the instance
if (myHandle) Wait();
Wait();
// Destroy the implementation
delete myThreadImpl;
} }
@ -72,12 +83,8 @@ Thread::~Thread()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Launch() void Thread::Launch()
{ {
// Create the thread delete myThreadImpl;
myHandle = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &Thread::ThreadFunc, this, 0, NULL)); myThreadImpl = new priv::ThreadImpl(this);
// Error ?
if (myHandle == NULL)
std::cerr << "Failed to create thread" << std::endl;
} }
@ -86,15 +93,8 @@ void Thread::Launch()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Wait() void Thread::Wait()
{ {
if (myHandle) if (myThreadImpl)
{ myThreadImpl->Wait();
// Wait for the thread to finish, no timeout
WaitForSingleObject(myHandle, INFINITE);
// Don't forget to close the thread handle (__endthreadex doesn't do it)
CloseHandle(myHandle);
myHandle = NULL;
}
} }
@ -106,11 +106,8 @@ void Thread::Wait()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Terminate() void Thread::Terminate()
{ {
if (myHandle) if (myThreadImpl)
{ myThreadImpl->Terminate();
TerminateThread(myHandle, 0);
myHandle = NULL;
}
} }
@ -123,22 +120,4 @@ void Thread::Run()
myFunction(myUserData); myFunction(myUserData);
} }
////////////////////////////////////////////////////////////
/// Actual thread entry point, dispatches to instances
////////////////////////////////////////////////////////////
unsigned int __stdcall Thread::ThreadFunc(void* UserData)
{
// The Thread instance is stored in the user data
Thread* ThreadInstance = reinterpret_cast<Thread*>(UserData);
// Forward to the instance
ThreadInstance->Run();
// Optional, but it is cleaner
_endthreadex(0);
return 0;
}
} // namespace sf } // namespace sf

View File

@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software. // In no event will the authors be held liable for any damages arising from the use of this software.
@ -25,15 +25,17 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Unix/Mutex.hpp> #include <SFML/System/Unix/MutexImpl.hpp>
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Default constructor /// Default constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex::Mutex() MutexImpl::MutexImpl()
{ {
pthread_mutex_init(&myMutex, NULL); pthread_mutex_init(&myMutex, NULL);
} }
@ -42,7 +44,7 @@ Mutex::Mutex()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Destructor /// Destructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex::~Mutex() MutexImpl::~MutexImpl()
{ {
pthread_mutex_destroy(&myMutex); pthread_mutex_destroy(&myMutex);
} }
@ -51,7 +53,7 @@ Mutex::~Mutex()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Lock the mutex /// Lock the mutex
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Mutex::Lock() void MutexImpl::Lock()
{ {
pthread_mutex_lock(&myMutex); pthread_mutex_lock(&myMutex);
} }
@ -60,9 +62,11 @@ void Mutex::Lock()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Unlock the mutex /// Unlock the mutex
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Mutex::Unlock() void MutexImpl::Unlock()
{ {
pthread_mutex_unlock(&myMutex); pthread_mutex_unlock(&myMutex);
} }
} // namespace priv
} // namespace sf } // namespace sf

View File

@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software. // In no event will the authors be held liable for any damages arising from the use of this software.
@ -22,8 +22,8 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifndef SFML_MUTEXUNIX_HPP #ifndef SFML_MUTEXIMPL_HPP
#define SFML_MUTEXUNIX_HPP #define SFML_MUTEXIMPL_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
@ -34,13 +34,12 @@
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Mutex defines a mutex (MUTual EXclusion) object, /// Unix implementation of mutexes
/// that allows a thread to lock critical instructions
/// to avoid simultaneous access with other threads.
/// See Lock for an efficient way of using it.
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_API Mutex : NonCopyable class MutexImpl : NonCopyable
{ {
public : public :
@ -48,13 +47,13 @@ public :
/// Default constructor /// Default constructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex(); MutexImpl();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Destructor /// Destructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~Mutex(); ~MutexImpl();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Lock the mutex /// Lock the mutex
@ -73,10 +72,12 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
pthread_mutex_t myMutex; ///< pthread instance of the mutex pthread_mutex_t myMutex; ///< pthread handle of the mutex
}; };
} // namespace priv
} // namespace sf } // namespace sf
#endif // SFML_MUTEXUNIX_HPP #endif // SFML_MUTEXIMPL_HPP

View File

@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software. // In no event will the authors be held liable for any damages arising from the use of this software.
@ -25,78 +25,35 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Unix/Thread.hpp> #include <SFML/System/Unix/ThreadImpl.hpp>
#include <SFML/System/Thread.hpp>
#include <iostream> #include <iostream>
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Default constructor /// Default constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Thread::Thread() : ThreadImpl::ThreadImpl(Thread* Owner) :
myIsActive(false), myIsActive(true)
myFunction(NULL),
myUserData(NULL)
{ {
myIsActive = pthread_create(&myThread, NULL, &ThreadFunc, Owner) == 0;
} if (!myIsActive)
////////////////////////////////////////////////////////////
/// Construct the thread from a function pointer
////////////////////////////////////////////////////////////
Thread::Thread(Thread::FuncType Function, void* UserData) :
myIsActive(false),
myFunction(Function),
myUserData(UserData)
{
}
////////////////////////////////////////////////////////////
/// Virtual destructor
////////////////////////////////////////////////////////////
Thread::~Thread()
{
// Wait for the thread to finish before destroying the instance
if (myIsActive)
Wait();
}
////////////////////////////////////////////////////////////
/// Create and run the thread
////////////////////////////////////////////////////////////
void Thread::Launch()
{
// Create the thread
myIsActive = true;
int Error = pthread_create(&myThread, NULL, &Thread::ThreadFunc, this);
// Error ?
if (Error != 0)
{
std::cerr << "Failed to create thread" << std::endl; std::cerr << "Failed to create thread" << std::endl;
myIsActive = false;
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Wait until the thread finishes /// Wait until the thread finishes
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Wait() void ThreadImpl::Wait()
{ {
if (myIsActive) if (myIsActive)
{
// Wait for the thread to finish, no timeout
pthread_join(myThread, NULL); pthread_join(myThread, NULL);
// Reset the thread state
myIsActive = false;
}
} }
@ -106,41 +63,30 @@ void Thread::Wait()
/// you should rather try to make the thread function /// you should rather try to make the thread function
/// terminate by itself /// terminate by itself
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Terminate() void ThreadImpl::Terminate()
{ {
if (myIsActive) if (myIsActive)
{
pthread_cancel(myThread); pthread_cancel(myThread);
myIsActive = false;
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Function called as the thread entry point /// Global entry point for all threads
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Thread::Run() void* ThreadFunc(void* UserData)
{ {
if (myFunction) // The Thread instance is stored in the user data
myFunction(myUserData); Thread* Owner = static_cast<Thread*>(UserData);
}
////////////////////////////////////////////////////////////
/// Actual thread entry point, dispatches to instances
////////////////////////////////////////////////////////////
void* Thread::ThreadFunc(void* UserData)
{
// The sfThread instance is stored in the user data
Thread* ThreadToRun = reinterpret_cast<Thread*>(UserData);
// Tell the thread to handle cancel requests immediatly // Tell the thread to handle cancel requests immediatly
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
// Forward to the instance // Forward to the owner
ThreadToRun->Run(); Owner->Run();
return NULL; return NULL;
} }
} // namespace priv
} // namespace sf } // namespace sf

View File

@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software. // In no event will the authors be held liable for any damages arising from the use of this software.
@ -22,8 +22,8 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifndef SFML_THREADUNIX_HPP #ifndef SFML_THREADIMPL_HPP
#define SFML_THREADUNIX_HPP #define SFML_THREADIMPL_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
@ -34,39 +34,24 @@
namespace sf namespace sf
{ {
class Thread;
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Thread defines a thread. /// Unix implementation of threads
/// There is two ways to use Thread :
/// - Inherit from it and override the Run() virtual function
/// - Construct a sfThread instance and pass it a function
/// pointer to call
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_API Thread : NonCopyable class ThreadImpl : NonCopyable
{ {
public : public :
typedef void (*FuncType)(void*);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Construct the thread from a function pointer /// Default constructor, launch the thread
/// ///
/// \param Function : Entry point of the thread /// \param Owner : Owner Thread instance to run
/// \param UserData : Data to pass to the thread function (NULL by default)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Thread(FuncType Function, void* UserData = NULL); ThreadImpl(Thread* Owner);
////////////////////////////////////////////////////////////
/// Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Thread();
////////////////////////////////////////////////////////////
/// Create and run the thread
///
////////////////////////////////////////////////////////////
void Launch();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Wait until the thread finishes /// Wait until the thread finishes
@ -83,42 +68,28 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Terminate(); void Terminate();
protected :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Thread();
private : private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Function called as the thread entry point /// Global entry point for all threads
/// ///
//////////////////////////////////////////////////////////// /// \param UserData : User-defined data (contains the Thread instance)
virtual void Run();
////////////////////////////////////////////////////////////
/// Actual thread entry point, dispatches to instances
///
/// \param UserData : Data to pass to the thread function
/// ///
/// \return Error code /// \return Error code
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static void* ThreadFunc(void* UserData); static void* EntryPoint(void* UserData);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
pthread_t myThread; ///< Unix thread instance pthread_t myThread; ///< pthread thread instance
bool myIsActive; ///< Thread state (active or inactive) bool myIsActive; ///< Thread state (active or inactive)
FuncType myFunction; ///< Function to call as the thread entry point
void* myUserData; ///< Data to pass to the thread function
}; };
} // namespace priv
} // namespace sf } // namespace sf
#endif // SFML_THREADUNIX_HPP #endif // SFML_THREADIMPL_HPP

View File

@ -0,0 +1,72 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/Win32/MutexImpl.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
MutexImpl::MutexImpl()
{
InitializeCriticalSection(&myMutex);
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
MutexImpl::~MutexImpl()
{
DeleteCriticalSection(&myMutex);
}
////////////////////////////////////////////////////////////
/// Lock the mutex
////////////////////////////////////////////////////////////
void MutexImpl::Lock()
{
EnterCriticalSection(&myMutex);
}
////////////////////////////////////////////////////////////
/// Unlock the mutex
////////////////////////////////////////////////////////////
void MutexImpl::Unlock()
{
LeaveCriticalSection(&myMutex);
}
} // namespace priv
} // namespace sf

View File

@ -22,8 +22,8 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifndef SFML_MUTEXWIN32_HPP #ifndef SFML_MUTEXIMPL_HPP
#define SFML_MUTEXWIN32_HPP #define SFML_MUTEXIMPL_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
@ -34,15 +34,12 @@
namespace sf namespace sf
{ {
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Mutex defines a mutex (MUTual EXclusion) object, /// Windows implementation of mutexes
/// that allows a thread to lock critical instructions
/// to avoid simultaneous access with other threads.
/// The Win32 version uses critical sections, as it is
/// faster than mutexes.<br/>
/// See Lock for an efficient way of using it.
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_API Mutex : NonCopyable class MutexImpl : NonCopyable
{ {
public : public :
@ -50,13 +47,13 @@ public :
/// Default constructor /// Default constructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Mutex(); MutexImpl();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Destructor /// Destructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~Mutex(); ~MutexImpl();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Lock the mutex /// Lock the mutex
@ -75,10 +72,12 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
CRITICAL_SECTION myHandle; ///< Win32 handle of the mutex CRITICAL_SECTION myMutex; ///< Win32 handle of the mutex
}; };
} // namespace priv
} // namespace sf } // namespace sf
#endif // SFML_MUTEXWIN32_HPP #endif // SFML_MUTEXIMPL_HPP

View File

@ -0,0 +1,102 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/Win32/ThreadImpl.hpp>
#include <SFML/System/Thread.hpp>
#include <process.h>
#include <iostream>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
ThreadImpl::ThreadImpl(Thread* Owner)
{
myThread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &ThreadImpl::EntryPoint, Owner, 0, NULL));
if (!myThread)
std::cerr << "Failed to create thread" << std::endl;
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
ThreadImpl::~ThreadImpl()
{
if (myThread)
CloseHandle(myThread);
}
////////////////////////////////////////////////////////////
/// Wait until the thread finishes
////////////////////////////////////////////////////////////
void ThreadImpl::Wait()
{
if (myThread)
WaitForSingleObject(myThread, INFINITE);
}
////////////////////////////////////////////////////////////
/// Terminate the thread
/// Terminating a thread with this function is not safe,
/// you should rather try to make the thread function
/// terminate by itself
////////////////////////////////////////////////////////////
void ThreadImpl::Terminate()
{
if (myThread)
TerminateThread(myThread, 0);
}
////////////////////////////////////////////////////////////
/// Global entry point for all threads
////////////////////////////////////////////////////////////
unsigned int __stdcall ThreadImpl::EntryPoint(void* UserData)
{
// The Thread instance is stored in the user data
Thread* Owner = static_cast<Thread*>(UserData);
// Forward to the owner
Owner->Run();
// Optional, but it is cleaner
_endthreadex(0);
return 0;
}
} // namespace priv
} // namespace sf

View File

@ -22,8 +22,8 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifndef SFML_THREADWIN32_HPP #ifndef SFML_THREADIMPL_HPP
#define SFML_THREADWIN32_HPP #define SFML_THREADIMPL_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
@ -34,39 +34,30 @@
namespace sf namespace sf
{ {
class Thread;
namespace priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Thread defines an easy way to manipulate a thread. /// Windows implementation of threads
/// There are two ways to use Thread :
/// - Inherit from it and override the Run() virtual function
/// - Construct a Thread instance and pass it a function
/// pointer to call
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class SFML_API Thread : NonCopyable class ThreadImpl : NonCopyable
{ {
public : public :
typedef void (*FuncType)(void*); ////////////////////////////////////////////////////////////
/// Default constructor, launch the thread
///
/// \param Owner : Owner Thread instance to run
///
////////////////////////////////////////////////////////////
ThreadImpl(Thread* Owner);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Construct the thread from a function pointer /// Destructor
///
/// \param Function : Entry point of the thread
/// \param UserData : Data to pass to the thread function (NULL by default)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Thread(FuncType Function, void* UserData = NULL); ~ThreadImpl();
////////////////////////////////////////////////////////////
/// Virtual destructor
///
////////////////////////////////////////////////////////////
virtual ~Thread();
////////////////////////////////////////////////////////////
/// Create and run the thread
///
////////////////////////////////////////////////////////////
void Launch();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Wait until the thread finishes /// Wait until the thread finishes
@ -83,41 +74,27 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Terminate(); void Terminate();
protected :
////////////////////////////////////////////////////////////
/// Default constructor
///
////////////////////////////////////////////////////////////
Thread();
private : private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Function called as the thread entry point /// Global entry point for all threads
/// ///
//////////////////////////////////////////////////////////// /// \param UserData : User-defined data (contains the Thread instance)
virtual void Run();
////////////////////////////////////////////////////////////
/// Actual thread entry point, dispatches to instances
///
/// \param UserData : Data to pass to the thread function
/// ///
/// \return Error code /// \return Error code
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static unsigned int __stdcall ThreadFunc(void* UserData); static unsigned int __stdcall EntryPoint(void* UserData);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
HANDLE myHandle; ///< Win32 thread handle HANDLE myThread; ///< Win32 thread handle
FuncType myFunction; ///< Function to call as the thread entry point
void* myUserData; ///< Data to pass to the thread function
}; };
} // namespace priv
} // namespace sf } // namespace sf
#endif // SFML_THREADWIN32_HPP #endif // SFML_THREADIMPL_HPP