Updated OS X Pool Wrapper

This commit is contained in:
Marco Antognini 2014-08-03 18:43:53 +01:00
parent dcba593e8f
commit 6d122f428a
3 changed files with 44 additions and 65 deletions

View File

@ -26,26 +26,24 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Ensure at least one autorelease pool is available on this thread /// \brief Ensure at least one autorelease pool is available on this thread
/// ///
/// Increment a retain count. /// Increment a retain count for *this* thread.
/// See SPECIAL CONSIDERATION in implementation file.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void retainPool(void); void retainPool(void);
////////////////////////////////////////////////////////////
/// \brief Drain the pool
///
/// The pool retain count should be absolutely positive before calling this function on this thread.
///
////////////////////////////////////////////////////////////
void drainCurrentPool(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Release the pool. /// \brief Release the pool.
/// ///
/// Drain the pool if it is no more needed (retain count is zero) /// Decrease the retain count for *this* thread.
/// See SPECIAL CONSIDERATION in implementation file.
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void releasePool(void); void releasePool(void);
////////////////////////////////////////////////////////////
/// \brief Drain the pool
///
/// releasePool must be called at least once before drainPool.
///
////////////////////////////////////////////////////////////
void drainPool();

View File

@ -30,6 +30,8 @@
#include <SFML/System/NonCopyable.hpp> #include <SFML/System/NonCopyable.hpp>
#include <SFML/System/ThreadLocalPtr.hpp> #include <SFML/System/ThreadLocalPtr.hpp>
#include <cassert>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h> #import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@ -70,6 +72,8 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Default destructor /// \brief Default destructor
/// ///
/// Make sure the pool is drained (if appropriate)
///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~PoolWrapper(); ~PoolWrapper();
@ -82,8 +86,10 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Decrement retain count and releasing memory if needed /// \brief Decrement retain count and releasing memory if needed
/// ///
/// \return true if the pool wrapper can be released
///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void release(); bool release();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Drain the pool /// \brief Drain the pool
@ -104,7 +110,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
PoolWrapper::PoolWrapper() : PoolWrapper::PoolWrapper() :
m_count(0), m_count(0),
m_pool(0) m_pool(nil)
{ {
/* Nothing else */ /* Nothing else */
} }
@ -113,58 +119,37 @@ m_pool(0)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
PoolWrapper::~PoolWrapper() PoolWrapper::~PoolWrapper()
{ {
#ifdef SFML_DEBUG // Make sure everything is drained
if (m_count < 0) m_count = 0;
sf::err() << "~PoolWrapper : m_count is less than zero! " drain();
"You called releasePool from a thread too many times."
<< std::endl;
else if (m_count > 0)
sf::err() << "~PoolWrapper : m_count is greater than zero! "
"You called releasePool from a thread to few times."
<< std::endl;
else // m_count == 0
sf::err() << "~PoolWrapper is HAPPY!" << std::endl;
#endif
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void PoolWrapper::retain() void PoolWrapper::retain()
{ {
// Increase counter. // Increase counter
++m_count; ++m_count;
// Allocate pool if required. // Allocate pool if required
if (m_pool == 0) if (m_pool == nil)
m_pool = [[NSAutoreleasePool alloc] init]; m_pool = [[NSAutoreleasePool alloc] init];
#ifdef SFML_DEBUG
if (m_count <= 0)
sf::err() << "PoolWrapper::retain : m_count <= 0! " << std::endl;
#endif
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void PoolWrapper::release() bool PoolWrapper::release()
{ {
// Decrease counter. // Decrease counter
--m_count; --m_count;
// Drain pool if required. return m_count == 0;
if (m_count == 0)
drain();
#ifdef SFML_DEBUG
if (m_count < 0)
sf::err() << "PoolWrapper::release : m_count < 0! " << std::endl;
#endif
} }
void PoolWrapper::drain() void PoolWrapper::drain()
{ {
[m_pool drain]; [m_pool drain];
m_pool = 0; m_pool = nil;
if (m_count != 0) if (m_count != 0)
m_pool = [[NSAutoreleasePool alloc] init]; m_pool = [[NSAutoreleasePool alloc] init];
@ -198,28 +183,23 @@ void retainPool(void)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void releasePool(void) void drainCurrentPool(void)
{ {
if (localPool != NULL) assert(localPool != NULL);
localPool->release(); localPool->drain();
#ifdef SFML_DEBUG
else
sf::err() << "releasePool : You must call retainPool at least once "
"in this thread before calling releasePool."
<< std::endl;
#endif
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void drainPool() void releasePool(void)
{ {
if (localPool != NULL) assert(localPool != NULL);
localPool->drain();
#ifdef SFML_DEBUG // If we're done with the pool, let's release the memory
else if (localPool->release())
sf::err() << "releasePool must be called at least one before drainPool" {
<< std::endl; delete localPool;
#endif localPool = NULL;
}
} }

View File

@ -191,11 +191,11 @@ WindowImplCocoa::~WindowImplCocoa()
if ([windows count] > 0) if ([windows count] > 0)
[[windows objectAtIndex:0] makeKeyAndOrderFront:nil]; [[windows objectAtIndex:0] makeKeyAndOrderFront:nil];
releasePool(); drainCurrentPool(); // Make sure everything was freed
drainPool(); // Make sure everything was freed
// This solve some issue when sf::Window::Create is called for the // This solve some issue when sf::Window::Create is called for the
// second time (nothing was render until the function was called again) // second time (nothing was render until the function was called again)
releasePool();
} }
@ -416,6 +416,7 @@ void WindowImplCocoa::textEntered(unichar charcode)
void WindowImplCocoa::processEvents() void WindowImplCocoa::processEvents()
{ {
[m_delegate processEvent]; [m_delegate processEvent];
drainCurrentPool(); // Reduce memory footprint
} }
#pragma mark #pragma mark