Fixed a minor warning and a compile error and improved consistency in comments

This commit is contained in:
Marco Antognini 2011-07-06 03:47:19 +02:00
parent a55ae4b758
commit 26d4c533ee
7 changed files with 166 additions and 77 deletions

View File

@ -38,7 +38,6 @@ namespace
{ {
// OpenGL resources counter and its mutex // OpenGL resources counter and its mutex
unsigned long count = 0; unsigned long count = 0;
bool initialized = false;
sf::Mutex mutex; sf::Mutex mutex;
} }

View File

@ -23,6 +23,21 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// \brief Ensure at least one autorelease pool is available on this thread.
///
/// Increment a retain count.
/// See SPECIAL CONSIDERATION in implementation file.
///
////////////////////////////////////////////////////////////
void RetainPool(void); void RetainPool(void);
////////////////////////////////////////////////////////////
/// \brief Release the pool.
///
/// Drain the pool if it is no more needed (retain count is zero).
/// See SPECIAL CONSIDERATION in implementation file.
///
////////////////////////////////////////////////////////////
void ReleasePool(void); void ReleasePool(void);

View File

@ -23,102 +23,172 @@
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/ThreadLocalPtr.hpp> #include <SFML/System/ThreadLocalPtr.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#import "AutoreleasePoolWrapper.h"
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
// Here we manage one and only one pool by thread. This prevents draining one
// pool and making other pools invalid which can lead to a crash on 10.5 and an
// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool).
// Because NSAutoreleasePool cannot be retain we have to do it ourself. ////////////////////////////////////////////////////////////
// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread. /// Here we manage one and only one pool by thread. This prevents draining one
/// pool and making other pools invalid which can lead to a crash on 10.5 and an
/// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool).
///
/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
///
/// SPECIAL CONSIDERATION :
/// =======================
/// This implies that if RetainPool is called X times in a thread Y then
/// ReleasePool must be called X times too in the same thread Y.
///
////////////////////////////////////////////////////////////
// This implies that if RetainPool is called X times in a thread Y then namespace sf
// ReleasePool must be called X times too in the same thread Y. {
namespace priv
class PoolWrapper { {
public: ////////////////////////////////////////////////////////////
PoolWrapper() /// \brief C++ Wrapper of Obj-C Autorelease Pool.
: count(0) ///
, pool(0) ////////////////////////////////////////////////////////////
{ class PoolWrapper : NonCopyable {
/* Nothing else */ public :
}
~PoolWrapper() ////////////////////////////////////////////////////////////
{ /// \brief Default constructor
#ifdef SFML_DEBUG ///
if (count < 0) { ////////////////////////////////////////////////////////////
sf::Err() << "~PoolWrapper : count is less than zero! " PoolWrapper();
"You called ReleasePool from a thread too many times."
<< std::endl;
} else if (count > 0) {
sf::Err() << "~PoolWrapper : count is greater than zero! "
"You called ReleasePool from a thread to few times."
<< std::endl;
} else { // count == 0
sf::Err() << "~PoolWrapper is HAPPY!" << std::endl;
}
#endif
}
void Retain() ////////////////////////////////////////////////////////////
{ /// \brief Default destructor
// Increase counter. ///
++count; ////////////////////////////////////////////////////////////
~PoolWrapper();
// Allocate pool if required.
if (pool == 0) {
pool = [[NSAutoreleasePool alloc] init];
}
#ifdef SFML_DEBUG
if (count <= 0) {
sf::Err() << "PoolWrapper::Retain : count <= 0! " << std::endl;
}
#endif
}
void Release() ////////////////////////////////////////////////////////////
{ /// \brief Increment retain count and allocate memory if needed
// Decrease counter. ///
--count; ////////////////////////////////////////////////////////////
void Retain();
// Drain pool if required.
if (count == 0) {
[pool drain];
pool = 0;
}
#ifdef SFML_DEBUG
if (count < 0) {
sf::Err() << "PoolWrapper::Release : count < 0! " << std::endl;
}
#endif
}
////////////////////////////////////////////////////////////
/// \brief Decrement retain count and releasing memory if needed
///
////////////////////////////////////////////////////////////
void Release();
private: private:
int count; ///< How many times the pool was retained ?
NSAutoreleasePool* pool; ///< Our pool. ////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
int count; ///< How many times was the pool retained ?
NSAutoreleasePool* pool; ///< Our dedicated pool
}; };
// Thread shared variable but with local-only shared content.
sf::ThreadLocalPtr<PoolWrapper> localPool;
////////////////////////////////////////////////////////////
PoolWrapper::PoolWrapper()
: count(0)
, pool(0)
{
/* Nothing else */
}
////////////////////////////////////////////////////////////
PoolWrapper::~PoolWrapper()
{
#ifdef SFML_DEBUG
if (count < 0) {
sf::Err() << "~PoolWrapper : count is less than zero! "
"You called ReleasePool from a thread too many times."
<< std::endl;
} else if (count > 0) {
sf::Err() << "~PoolWrapper : count is greater than zero! "
"You called ReleasePool from a thread to few times."
<< std::endl;
} else { // count == 0
sf::Err() << "~PoolWrapper is HAPPY!" << std::endl;
}
#endif
}
////////////////////////////////////////////////////////////
void PoolWrapper::Retain()
{
// Increase counter.
++count;
// Allocate pool if required.
if (pool == 0) {
pool = [[NSAutoreleasePool alloc] init];
}
#ifdef SFML_DEBUG
if (count <= 0) {
sf::Err() << "PoolWrapper::Retain : count <= 0! " << std::endl;
}
#endif
}
////////////////////////////////////////////////////////////
void PoolWrapper::Release()
{
// Decrease counter.
--count;
// Drain pool if required.
if (count == 0) {
[pool drain];
pool = 0;
}
#ifdef SFML_DEBUG
if (count < 0) {
sf::Err() << "PoolWrapper::Release : count < 0! " << std::endl;
}
#endif
}
} // namespace priv
} // namespace sf
////////////////////////////////////////////////////////////
// Private data
////////////////////////////////////////////////////////////
namespace
{
// This per-thread variable holds the current autorelease pool for each thread
sf::ThreadLocalPtr<sf::priv::PoolWrapper> localPool;
}
////////////////////////////////////////////////////////////
void RetainPool(void) void RetainPool(void)
{ {
// First, Check that we have a valid PoolWrapper object in our local pool. // First, Check that we have a valid PoolWrapper object in our local pool.
if (localPool == NULL) { if (localPool == NULL) {
localPool = new PoolWrapper(); localPool = new sf::priv::PoolWrapper();
} }
// Then retains! // Then retains!
localPool->Retain(); localPool->Retain();
} }
////////////////////////////////////////////////////////////
void ReleasePool(void) void ReleasePool(void)
{ {
#ifdef SFML_DEBUG #ifdef SFML_DEBUG
@ -136,3 +206,4 @@ void ReleasePool(void)
} }
#endif #endif
} }

View File

@ -1,7 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
// 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.

View File

@ -1,7 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
// 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.
@ -27,7 +28,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/InputImpl.hpp> #include <SFML/Window/OSX/InputImpl.hpp>
#include <SFML/Window/VideoMode.hpp> #include <SFML/Window/VideoMode.hpp>
#import <Cocoa/Cocoa.h> #import <AppKit/AppKit.h>
namespace sf namespace sf
{ {

View File

@ -1,7 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
// 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.

View File

@ -1,7 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
// 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.