mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Change handling of NSAutoreleasePool
GUI toolkits such as wxWidgets and Qt provide their own NSAutoreleasePool objects. To avoid pool corruption, it is required that the pools be nested, which the previous implementation did not guarantee. Furthermore, autorelease pools should always be drained in the same context (function, loop, etc.) that they are created, which was not the case with the previous implementation (https://developer.apple.com/documentation/foundation/nsautoreleasepool). This commit removes long-lived autorelease pools, and instead each function that calls into the Cocoa API creates its own autorelease pool (using the new C++ AutoreleasePool wrapper object). Should fix crashes in issue #1549 and similar.
This commit is contained in:
parent
eeeda74ec1
commit
c80cbb9c97
@ -182,7 +182,7 @@ elseif(SFML_OS_MACOSX)
|
||||
${SRCROOT}/OSX/WindowImplCocoa.hpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.mm
|
||||
${SRCROOT}/OSX/WindowImplDelegateProtocol.h
|
||||
${SRCROOT}/OSX/AutoreleasePoolWrapper.h
|
||||
${SRCROOT}/OSX/AutoreleasePoolWrapper.hpp
|
||||
${SRCROOT}/OSX/AutoreleasePoolWrapper.mm
|
||||
)
|
||||
source_group("mac" FILES ${PLATFORM_SRC})
|
||||
|
@ -23,15 +23,54 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Ensure one autorelease pool is available on this thread
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void ensureThreadHasPool(void);
|
||||
|
||||
#ifndef SFML_AUTORELEASEPOOL_HPP
|
||||
#define SFML_AUTORELEASEPOOL_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Drain the thread's pool but keep it alive
|
||||
/// Predefine OBJ-C classes
|
||||
////////////////////////////////////////////////////////////
|
||||
#ifdef __OBJC__
|
||||
|
||||
@class NSAutoreleasePool;
|
||||
typedef NSAutoreleasePool* NSAutoreleasePoolRef;
|
||||
|
||||
#else // If C++
|
||||
|
||||
typedef void* NSAutoreleasePoolRef;
|
||||
|
||||
#endif
|
||||
|
||||
namespace sf
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Wraps an NSAutoreleasePool that is created when the object is
|
||||
/// constructed and is drained when the object is destroyed.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void drainThreadPool(void);
|
||||
class AutoreleasePool
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct a new NSAutoreleasePool.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
AutoreleasePool();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor. Drains the autorelease pool.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~AutoreleasePool();
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
NSAutoreleasePoolRef pool; ///< The autorelease pool.
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
||||
#endif // SFML_AUTORELEASEPOOL_HPP
|
@ -26,80 +26,25 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <cassert>
|
||||
#include <pthread.h>
|
||||
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
|
||||
#import <Foundation/Foundation.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).
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Private data
|
||||
////////////////////////////////////////////////////////////
|
||||
static pthread_key_t poolKey;
|
||||
static pthread_once_t initOnceToken = PTHREAD_ONCE_INIT;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief (local function) Drain one more time the pool
|
||||
/// but this time don't create a new one.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void destroyPool(void* data)
|
||||
namespace sf
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
AutoreleasePool::AutoreleasePool()
|
||||
{
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
AutoreleasePool::~AutoreleasePool()
|
||||
{
|
||||
NSAutoreleasePool* pool = (NSAutoreleasePool*)data;
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief (local function) Init the pthread key for the pool
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void createPoolKey(void)
|
||||
{
|
||||
pthread_key_create(&poolKey, destroyPool);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief (local function) Store a new pool for this thread
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void createNewPool(void)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
pthread_setspecific(poolKey, pool);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void ensureThreadHasPool(void)
|
||||
{
|
||||
pthread_once(&initOnceToken, createPoolKey);
|
||||
if (pthread_getspecific(poolKey) == NULL)
|
||||
{
|
||||
createNewPool();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void drainThreadPool(void)
|
||||
{
|
||||
void* data = pthread_getspecific(poolKey);
|
||||
assert(data != NULL);
|
||||
|
||||
// Drain the pool but keep it alive by creating a new one
|
||||
destroyPool(data);
|
||||
createNewPool();
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
@ -25,6 +25,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
#include <SFML/Window/OSX/ClipboardImpl.hpp>
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
@ -37,6 +38,7 @@ namespace priv
|
||||
////////////////////////////////////////////////////////////
|
||||
String ClipboardImpl::getString()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
NSPasteboard* pboard = [NSPasteboard generalPasteboard];
|
||||
NSString* data = [pboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
@ -50,6 +52,7 @@ String ClipboardImpl::getString()
|
||||
////////////////////////////////////////////////////////////
|
||||
void ClipboardImpl::setString(const String& text)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
std::basic_string<Uint8> utf8 = text.toUtf8();
|
||||
NSString* data = [[NSString alloc] initWithBytes:utf8.data()
|
||||
length:utf8.length()
|
||||
|
@ -27,8 +27,8 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/CursorImpl.hpp>
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
#import <SFML/Window/OSX/NSImage+raw.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@ -53,17 +53,13 @@ namespace priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
CursorImpl::CursorImpl() :
|
||||
m_cursor(nil)
|
||||
{
|
||||
// Just ask for a pool
|
||||
ensureThreadHasPool();
|
||||
}
|
||||
CursorImpl::CursorImpl() : m_cursor(nil) {}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
CursorImpl::~CursorImpl()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_cursor release];
|
||||
}
|
||||
|
||||
@ -71,6 +67,7 @@ CursorImpl::~CursorImpl()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (m_cursor)
|
||||
{
|
||||
[m_cursor release];
|
||||
@ -89,6 +86,7 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot
|
||||
////////////////////////////////////////////////////////////
|
||||
bool CursorImpl::loadFromSystem(Cursor::Type type)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
NSCursor* newCursor = nil;
|
||||
|
||||
switch (type)
|
||||
|
@ -28,6 +28,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/VideoMode.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
#include <SFML/Window/OSX/InputImpl.hpp>
|
||||
#include <SFML/Window/OSX/HIDInputManager.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
@ -125,6 +126,7 @@ SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const WindowBase& window)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isKeyPressed(Keyboard::Key key)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
return HIDInputManager::getInstance().isKeyPressed(key);
|
||||
}
|
||||
|
||||
@ -139,6 +141,7 @@ void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
NSUInteger state = [NSEvent pressedMouseButtons];
|
||||
NSUInteger flag = 1 << button;
|
||||
return (state & flag) != 0;
|
||||
@ -148,6 +151,7 @@ bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2i InputImpl::getMousePosition()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Reverse Y axis to match SFML coord.
|
||||
NSPoint pos = [NSEvent mouseLocation];
|
||||
pos.y = sf::VideoMode::getDesktopMode().height - pos.y;
|
||||
@ -160,6 +164,7 @@ Vector2i InputImpl::getMousePosition()
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||
|
||||
// No view ?
|
||||
@ -177,6 +182,7 @@ Vector2i InputImpl::getMousePosition(const WindowBase& relativeTo)
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setMousePosition(const Vector2i& position)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Here we don't need to reverse the coordinates.
|
||||
int scale = [[NSScreen mainScreen] backingScaleFactor];
|
||||
CGPoint pos = CGPointMake(position.x / scale, position.y / scale);
|
||||
@ -195,6 +201,7 @@ void InputImpl::setMousePosition(const Vector2i& position)
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputImpl::setMousePosition(const Vector2i& position, const WindowBase& relativeTo)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||
|
||||
// No view ?
|
||||
|
@ -27,6 +27,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/JoystickImpl.hpp>
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
#include <SFML/Window/OSX/HIDInputManager.hpp>
|
||||
#include <SFML/Window/OSX/HIDJoystickManager.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
@ -106,6 +107,7 @@ void JoystickImpl::cleanup()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool JoystickImpl::isConnected(unsigned int index)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
bool state = false; // Is the index-th joystick connected?
|
||||
|
||||
// First, let's check if the device was previously detected:
|
||||
@ -180,6 +182,7 @@ bool JoystickImpl::isConnected(unsigned int index)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool JoystickImpl::open(unsigned int index)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
m_index = index;
|
||||
m_hat = NULL;
|
||||
Location deviceLoc = m_locationIDs[index]; // The device we need to load
|
||||
@ -325,6 +328,7 @@ bool JoystickImpl::open(unsigned int index)
|
||||
////////////////////////////////////////////////////////////
|
||||
void JoystickImpl::close()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
|
||||
CFRelease(*it);
|
||||
m_buttons.clear();
|
||||
@ -345,6 +349,7 @@ void JoystickImpl::close()
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickCaps JoystickImpl::getCapabilities() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
JoystickCaps caps;
|
||||
|
||||
// Buttons:
|
||||
@ -364,6 +369,7 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
||||
////////////////////////////////////////////////////////////
|
||||
Joystick::Identification JoystickImpl::getIdentification() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
return m_identification;
|
||||
}
|
||||
|
||||
@ -371,6 +377,7 @@ Joystick::Identification JoystickImpl::getIdentification() const
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState JoystickImpl::update()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
static const JoystickState disconnectedState; // return this if joystick was disconnected
|
||||
JoystickState state; // otherwise return that
|
||||
state.connected = true;
|
||||
|
@ -52,6 +52,8 @@
|
||||
////////////////////////////////////////////////////////
|
||||
+(void)setUpMenuBar
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[SFApplication sharedApplication]; // Make sure NSApp exists
|
||||
|
||||
// Set the main menu bar
|
||||
@ -76,6 +78,8 @@
|
||||
NSMenu* windowMenu = [[SFApplication newWindowMenu] autorelease];
|
||||
[windowItem setSubmenu:windowMenu];
|
||||
[NSApp setWindowsMenu:windowMenu];
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
|
||||
@ -98,6 +102,8 @@
|
||||
// --------------------
|
||||
// Quit AppName Command+Q
|
||||
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSString* appName = [SFApplication applicationName];
|
||||
|
||||
// APPLE MENU
|
||||
@ -154,6 +160,8 @@
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"];
|
||||
|
||||
[pool drain];
|
||||
|
||||
return appleMenu;
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,13 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
#include <SFML/Window/OSX/SFContext.hpp>
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <dlfcn.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
@ -46,9 +45,7 @@ m_context(0),
|
||||
m_view(0),
|
||||
m_window(0)
|
||||
{
|
||||
// Ask for a pool.
|
||||
ensureThreadHasPool();
|
||||
|
||||
AutoreleasePool pool;
|
||||
// Create the context
|
||||
createContext(shared,
|
||||
VideoMode::getDesktopMode().bitsPerPixel,
|
||||
@ -63,9 +60,7 @@ m_context(0),
|
||||
m_view(0),
|
||||
m_window(0)
|
||||
{
|
||||
// Ask for a pool.
|
||||
ensureThreadHasPool();
|
||||
|
||||
AutoreleasePool pool;
|
||||
// Create the context.
|
||||
createContext(shared, bitsPerPixel, settings);
|
||||
|
||||
@ -82,12 +77,10 @@ m_context(0),
|
||||
m_view(0),
|
||||
m_window(0)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Ensure the process is setup in order to create a valid window.
|
||||
WindowImplCocoa::setUpProcess();
|
||||
|
||||
// Ask for a pool.
|
||||
ensureThreadHasPool();
|
||||
|
||||
// Create the context.
|
||||
createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
|
||||
|
||||
@ -106,6 +99,7 @@ m_window(0)
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext::~SFContext()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Notify unshared OpenGL resources of context destruction
|
||||
cleanupUnsharedResources();
|
||||
|
||||
@ -124,6 +118,7 @@ SFContext::~SFContext()
|
||||
////////////////////////////////////////////////////////////
|
||||
GlFunctionPointer SFContext::getFunction(const char* name)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
static void* image = NULL;
|
||||
|
||||
if (!image)
|
||||
@ -136,6 +131,7 @@ GlFunctionPointer SFContext::getFunction(const char* name)
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SFContext::makeCurrent(bool current)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (current)
|
||||
{
|
||||
[m_context makeCurrentContext];
|
||||
@ -152,6 +148,7 @@ bool SFContext::makeCurrent(bool current)
|
||||
////////////////////////////////////////////////////////////
|
||||
void SFContext::display()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_context flushBuffer];
|
||||
}
|
||||
|
||||
@ -159,6 +156,7 @@ void SFContext::display()
|
||||
////////////////////////////////////////////////////////////
|
||||
void SFContext::setVerticalSyncEnabled(bool enabled)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
GLint swapInterval = enabled ? 1 : 0;
|
||||
|
||||
[m_context setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||
@ -170,6 +168,7 @@ void SFContext::createContext(SFContext* shared,
|
||||
unsigned int bitsPerPixel,
|
||||
const ContextSettings& settings)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Save the settings. (OpenGL version is updated elsewhere.)
|
||||
m_settings = settings;
|
||||
|
||||
|
@ -26,10 +26,10 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/AutoreleasePoolWrapper.hpp>
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
#import <SFML/Window/OSX/cpp_objc_conversion.h>
|
||||
#import <SFML/Window/OSX/Scaling.h>
|
||||
#import <SFML/Window/OSX/SFApplication.h>
|
||||
@ -59,6 +59,7 @@ namespace
|
||||
////////////////////////////////////////////////////////
|
||||
void hideMouseCursor()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (!isCursorHidden)
|
||||
{
|
||||
[NSCursor hide];
|
||||
@ -70,6 +71,7 @@ void hideMouseCursor()
|
||||
////////////////////////////////////////////////////////
|
||||
void showMouseCursor()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (isCursorHidden)
|
||||
{
|
||||
[NSCursor unhide];
|
||||
@ -84,9 +86,7 @@ void showMouseCursor()
|
||||
WindowImplCocoa::WindowImplCocoa(WindowHandle handle) :
|
||||
m_showCursor(true)
|
||||
{
|
||||
// Ask for a pool.
|
||||
ensureThreadHasPool();
|
||||
|
||||
AutoreleasePool pool;
|
||||
// Treat the handle as it real type
|
||||
id nsHandle = (id)handle;
|
||||
if ([nsHandle isKindOfClass:[NSWindow class]])
|
||||
@ -126,12 +126,10 @@ WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
||||
const ContextSettings& /*settings*/) :
|
||||
m_showCursor(true)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
// Transform the app process.
|
||||
setUpProcess();
|
||||
|
||||
// Ask for a pool.
|
||||
ensureThreadHasPool();
|
||||
|
||||
// Use backing size
|
||||
scaleInWidthHeight(mode, nil);
|
||||
|
||||
@ -147,8 +145,12 @@ m_showCursor(true)
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::~WindowImplCocoa()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate closeWindow];
|
||||
|
||||
// Tell the window/view controller (and the OpenGL view) that the delegate
|
||||
// (this object) no longer exists to prevent events being sent to the window
|
||||
// after it has been deleted.
|
||||
[m_delegate setRequesterTo:0];
|
||||
[m_delegate release];
|
||||
|
||||
// Put the next window in front, if any.
|
||||
@ -159,16 +161,13 @@ WindowImplCocoa::~WindowImplCocoa()
|
||||
if ([nextWindow isVisible])
|
||||
[nextWindow makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
drainThreadPool(); // Make sure everything was freed
|
||||
// This solve some issue when sf::Window::Create is called for the
|
||||
// second time (nothing was render until the function was called again)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::applyContext(NSOpenGLContextRef context) const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate applyContext:context];
|
||||
}
|
||||
|
||||
@ -176,6 +175,7 @@ void WindowImplCocoa::applyContext(NSOpenGLContextRef context) const
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setUpProcess(void)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
static bool isTheProcessSetAsApplication = false;
|
||||
|
||||
if (!isTheProcessSetAsApplication)
|
||||
@ -398,8 +398,8 @@ void WindowImplCocoa::textEntered(unichar charcode)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::processEvents()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate processEvent];
|
||||
drainThreadPool(); // Reduce memory footprint
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
@ -408,6 +408,7 @@ void WindowImplCocoa::processEvents()
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowHandle WindowImplCocoa::getSystemHandle() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
return [m_delegate getSystemHandle];
|
||||
}
|
||||
|
||||
@ -415,6 +416,7 @@ WindowHandle WindowImplCocoa::getSystemHandle() const
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2i WindowImplCocoa::getPosition() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
NSPoint pos = [m_delegate position];
|
||||
sf::Vector2i ret(pos.x, pos.y);
|
||||
scaleOutXY(ret, m_delegate);
|
||||
@ -425,6 +427,7 @@ Vector2i WindowImplCocoa::getPosition() const
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setPosition(const Vector2i& position)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
sf::Vector2i backingPosition = position;
|
||||
scaleInXY(backingPosition, m_delegate);
|
||||
[m_delegate setWindowPositionToX:backingPosition.x Y:backingPosition.y];
|
||||
@ -434,6 +437,7 @@ void WindowImplCocoa::setPosition(const Vector2i& position)
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2u WindowImplCocoa::getSize() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
NSSize size = [m_delegate size];
|
||||
Vector2u ret(size.width, size.height);
|
||||
scaleOutXY(ret, m_delegate);
|
||||
@ -453,6 +457,7 @@ void WindowImplCocoa::setSize(const Vector2u& size)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setTitle(const String& title)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate changeTitle:sfStringToNSString(title)];
|
||||
}
|
||||
|
||||
@ -460,6 +465,7 @@ void WindowImplCocoa::setTitle(const String& title)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setIcon(unsigned int width, unsigned int height, const Uint8* pixels)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate setIconTo:width by:height with:pixels];
|
||||
}
|
||||
|
||||
@ -467,6 +473,7 @@ void WindowImplCocoa::setIcon(unsigned int width, unsigned int height, const Uin
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setVisible(bool visible)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (visible)
|
||||
[m_delegate showWindow];
|
||||
else
|
||||
@ -477,6 +484,7 @@ void WindowImplCocoa::setVisible(bool visible)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setMouseCursorVisible(bool visible)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
m_showCursor = visible;
|
||||
|
||||
// If the mouse is over the window, we apply the new setting
|
||||
@ -493,6 +501,7 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate setCursorGrabbed:grabbed];
|
||||
}
|
||||
|
||||
@ -500,6 +509,7 @@ void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setMouseCursor(const CursorImpl& cursor)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate setCursor:cursor.m_cursor];
|
||||
}
|
||||
|
||||
@ -507,6 +517,7 @@ void WindowImplCocoa::setMouseCursor(const CursorImpl& cursor)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
if (enabled)
|
||||
[m_delegate enableKeyRepeat];
|
||||
else
|
||||
@ -517,6 +528,7 @@ void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::requestFocus()
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
[m_delegate requestFocus];
|
||||
}
|
||||
|
||||
@ -524,6 +536,7 @@ void WindowImplCocoa::requestFocus()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowImplCocoa::hasFocus() const
|
||||
{
|
||||
AutoreleasePool pool;
|
||||
return [m_delegate hasFocus];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user