From 416a5e18a1675f864410151cbd731a87a20dedc6 Mon Sep 17 00:00:00 2001 From: rogerman Date: Mon, 20 Feb 2012 17:00:13 +0000 Subject: [PATCH] Cocoa Port: - Reimplement Objective-C memory management by using the standard patterns for retain/release mechanics. This fixes several real and potential memory leaks. - Additional miscellaneous code cleanup and fixes. --- desmume/src/cocoa/cocoa_cheat.h | 14 +- desmume/src/cocoa/cocoa_cheat.mm | 37 +++-- desmume/src/cocoa/cocoa_core.h | 15 +- desmume/src/cocoa/cocoa_core.mm | 48 ++++++- desmume/src/cocoa/cocoa_file.mm | 10 +- desmume/src/cocoa/cocoa_firmware.h | 4 +- desmume/src/cocoa/cocoa_firmware.mm | 128 ++++++++++-------- desmume/src/cocoa/cocoa_hid.h | 7 +- desmume/src/cocoa/cocoa_hid.mm | 76 ++++++++--- desmume/src/cocoa/cocoa_input.h | 14 +- desmume/src/cocoa/cocoa_input.mm | 36 +++-- desmume/src/cocoa/cocoa_output.h | 9 +- desmume/src/cocoa/cocoa_output.mm | 58 ++++---- desmume/src/cocoa/cocoa_rom.h | 8 +- desmume/src/cocoa/cocoa_rom.mm | 34 ++--- desmume/src/cocoa/cocoa_util.h | 4 +- desmume/src/cocoa/cocoa_util.mm | 12 +- desmume/src/cocoa/cocoa_videofilter.mm | 2 +- .../src/cocoa/userinterface/appDelegate.mm | 7 +- .../cocoa/userinterface/cheatWindowDelegate.h | 8 +- .../userinterface/cheatWindowDelegate.mm | 2 + desmume/src/cocoa/userinterface/displayView.h | 10 +- .../src/cocoa/userinterface/displayView.mm | 10 +- .../cocoa/userinterface/emuWindowDelegate.h | 8 +- .../cocoa/userinterface/emuWindowDelegate.mm | 16 +-- .../userinterface/preferencesWindowDelegate.h | 2 +- .../preferencesWindowDelegate.mm | 6 +- 27 files changed, 355 insertions(+), 230 deletions(-) diff --git a/desmume/src/cocoa/cocoa_cheat.h b/desmume/src/cocoa/cocoa_cheat.h index b0672e0c8..530c77e7b 100644 --- a/desmume/src/cocoa/cocoa_cheat.h +++ b/desmume/src/cocoa/cocoa_cheat.h @@ -96,15 +96,15 @@ @property (readonly) CHEATS *listData; @property (readonly) NSMutableArray *list; -@property (assign) CocoaDSCore *cdsCore; +@property (retain) CocoaDSCore *cdsCore; @property (assign) NSUInteger untitledCount; -@property (assign) NSString *dbTitle; -@property (assign) NSString *dbDate; +@property (copy) NSString *dbTitle; +@property (copy) NSString *dbDate; - (id) initWithCore:(CocoaDSCore *)core; -- (id) initWithURL:(CocoaDSCore *)core fileURL:(NSURL *)fileURL; -- (id) initWithExistingList:(CocoaDSCore *)core listData:(CHEATS *)cheatList; -- (id) initWithURL:(CocoaDSCore *)core fileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList; +- (id) initWithCore:(CocoaDSCore *)core fileURL:(NSURL *)fileURL; +- (id) initWithCore:(CocoaDSCore *)core listData:(CHEATS *)cheatList; +- (id) initWithCore:(CocoaDSCore *)core fileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList; - (BOOL) add:(CocoaDSCheatItem *)cheatItem; - (void) remove:(CocoaDSCheatItem *)cheatItem; @@ -133,7 +133,7 @@ @property (readonly) CHEATSEARCH *listData; @property (readonly) NSMutableArray *addressList; -@property (assign) CocoaDSCore *cdsCore; +@property (retain) CocoaDSCore *cdsCore; @property (readonly) NSUInteger searchCount; - (id) initWithCore:(CocoaDSCore *)core; diff --git a/desmume/src/cocoa/cocoa_cheat.mm b/desmume/src/cocoa/cocoa_cheat.mm index ad1dac665..be958ab6e 100644 --- a/desmume/src/cocoa/cocoa_cheat.mm +++ b/desmume/src/cocoa/cocoa_cheat.mm @@ -105,8 +105,7 @@ static NSImage *iconCodeBreaker = nil; - (void) dealloc { - [workingCopy release]; - workingCopy = nil; + [self destroyWorkingCopy]; free(internalData); internalData = NULL; @@ -626,7 +625,7 @@ static NSImage *iconCodeBreaker = nil; [NSNumber numberWithInteger:self.freezeType], @"freezeType", [NSNumber numberWithUnsignedInteger:self.codeCount], @"codeCount", [NSNumber numberWithUnsignedInteger:self.bytes], @"bytes", - self.memAddress, @"memAddress", + [NSNumber numberWithUnsignedInt:self.memAddress], @"memAddress", self.memAddressString, @"memAddressString", [NSNumber numberWithInteger:self.value], @"value", self.code, @"code", @@ -648,25 +647,25 @@ static NSImage *iconCodeBreaker = nil; - (id)init { - return [self initWithURL:nil fileURL:nil listData:nil]; + return [self initWithCore:nil fileURL:nil listData:nil]; } - (id) initWithCore:(CocoaDSCore *)core { - return [self initWithURL:core fileURL:nil listData:nil]; + return [self initWithCore:core fileURL:nil listData:nil]; } -- (id) initWithURL:(CocoaDSCore *)core fileURL:(NSURL *)fileURL +- (id) initWithCore:(CocoaDSCore *)core fileURL:(NSURL *)fileURL { - return [self initWithURL:core fileURL:fileURL listData:nil]; + return [self initWithCore:core fileURL:fileURL listData:nil]; } -- (id) initWithExistingList:(CocoaDSCore *)core listData:(CHEATS *)cheatList +- (id) initWithCore:(CocoaDSCore *)core listData:(CHEATS *)cheatList { - return [self initWithURL:core fileURL:nil listData:cheatList]; + return [self initWithCore:core fileURL:nil listData:cheatList]; } -- (id) initWithURL:(CocoaDSCore *)core fileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList +- (id) initWithCore:(CocoaDSCore *)core fileURL:(NSURL *)fileURL listData:(CHEATS *)cheatList { self = [super init]; if(self == nil) @@ -706,7 +705,7 @@ static NSImage *iconCodeBreaker = nil; } } - cdsCore = core; + cdsCore = [core retain]; untitledCount = 0; dbTitle = nil; dbDate = nil; @@ -716,8 +715,12 @@ static NSImage *iconCodeBreaker = nil; - (void)dealloc { - [self.list release]; + self.dbTitle = nil; + self.dbDate = nil; + self.cdsCore = nil; + [list release]; delete self.listData; + [super dealloc]; } @@ -1084,7 +1087,7 @@ static NSImage *iconCodeBreaker = nil; listData = newListData; addressList = nil; - cdsCore = core; + cdsCore = [core retain]; searchCount = 0; return self; @@ -1092,8 +1095,14 @@ static NSImage *iconCodeBreaker = nil; - (void)dealloc { - [self reset]; + pthread_mutex_lock(self.cdsCore.mutexCoreExecute); + self.listData->close(); + pthread_mutex_unlock(self.cdsCore.mutexCoreExecute); + + [addressList release]; + self.cdsCore = nil; delete self.listData; + [super dealloc]; } diff --git a/desmume/src/cocoa/cocoa_core.h b/desmume/src/cocoa/cocoa_core.h index acb36bee4..b6d67157c 100644 --- a/desmume/src/cocoa/cocoa_core.h +++ b/desmume/src/cocoa/cocoa_core.h @@ -22,7 +22,6 @@ #import "cocoa_util.h" -@class CocoaDSRom; @class CocoaDSController; @class CocoaDSFirmware; @class CocoaDSOutput; @@ -30,6 +29,7 @@ typedef struct { void *cdsCore; + void *cdsController; int state; bool isFrameSkipEnabled; unsigned int frameCount; @@ -65,15 +65,16 @@ typedef struct BOOL emuFlagEmulateEnsata; pthread_mutex_t *mutexCoreExecute; + OSSpinLock spinlockCdsController; OSSpinLock spinlockMasterExecute; OSSpinLock spinlockExecutionChange; OSSpinLock spinlockCheatEnableFlag; OSSpinLock spinlockEmulationFlags; } -@property (assign) CocoaDSController *cdsController; -@property (assign) CocoaDSFirmware *cdsFirmware; -@property (assign) NSMutableArray *cdsOutputList; +@property (retain) CocoaDSController *cdsController; +@property (retain) CocoaDSFirmware *cdsFirmware; +@property (readonly) NSMutableArray *cdsOutputList; @property (assign) BOOL masterExecute; @property (assign) BOOL isFrameSkipEnabled; @@ -93,9 +94,9 @@ typedef struct @property (assign) BOOL emuFlagDebugConsole; @property (assign) BOOL emuFlagEmulateEnsata; -@property (assign) NSURL *arm9ImageURL; -@property (assign) NSURL *arm7ImageURL; -@property (assign) NSURL *firmwareImageURL; +@property (copy) NSURL *arm9ImageURL; +@property (copy) NSURL *arm7ImageURL; +@property (copy) NSURL *firmwareImageURL; @property (readonly) pthread_mutex_t *mutexCoreExecute; diff --git a/desmume/src/cocoa/cocoa_core.mm b/desmume/src/cocoa/cocoa_core.mm index 1899f4462..6f0e5be59 100644 --- a/desmume/src/cocoa/cocoa_core.mm +++ b/desmume/src/cocoa/cocoa_core.mm @@ -33,7 +33,7 @@ volatile bool execute = true; @implementation CocoaDSCore -@synthesize cdsController; +@dynamic cdsController; @synthesize cdsFirmware; @synthesize cdsOutputList; @@ -87,6 +87,7 @@ static BOOL isCoreStarted = NO; mutexCoreExecute = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mutexCoreExecute, NULL); spinlockMasterExecute = OS_SPINLOCK_INIT; + spinlockCdsController = OS_SPINLOCK_INIT; spinlockExecutionChange = OS_SPINLOCK_INIT; spinlockCheatEnableFlag = OS_SPINLOCK_INIT; spinlockEmulationFlags = OS_SPINLOCK_INIT; @@ -96,6 +97,7 @@ static BOOL isCoreStarted = NO; prevCoreState = CORESTATE_PAUSE; threadParam.cdsCore = self; + threadParam.cdsController = cdsController; threadParam.state = CORESTATE_PAUSE; threadParam.isFrameSkipEnabled = true; threadParam.frameCount = 0; @@ -140,6 +142,10 @@ static BOOL isCoreStarted = NO; free(self.mutexCoreExecute); mutexCoreExecute = nil; + self.cdsController = nil; + self.cdsFirmware = nil; + [cdsOutputList release]; + [super dealloc]; } @@ -210,6 +216,39 @@ static BOOL isCoreStarted = NO; return theState; } +- (void) setCdsController:(CocoaDSController *)theController +{ + OSSpinLockLock(&spinlockCdsController); + + if (theController == cdsController) + { + OSSpinLockUnlock(&spinlockCdsController); + return; + } + + if (theController != nil) + { + [theController retain]; + } + + pthread_mutex_lock(&threadParam.mutexThreadExecute); + [cdsController release]; + cdsController = theController; + threadParam.cdsController = theController; + pthread_mutex_unlock(&threadParam.mutexThreadExecute); + + OSSpinLockUnlock(&spinlockCdsController); +} + +- (CocoaDSController *) cdsController +{ + OSSpinLockLock(&spinlockCdsController); + CocoaDSController *theController = cdsController; + OSSpinLockUnlock(&spinlockCdsController); + + return theController; +} + - (void) setIsFrameSkipEnabled:(BOOL)theState { pthread_mutex_lock(&threadParam.mutexThreadExecute); @@ -221,6 +260,7 @@ static BOOL isCoreStarted = NO; else { threadParam.isFrameSkipEnabled = false; + threadParam.framesToSkip = 0; } pthread_mutex_unlock(&threadParam.mutexThreadExecute); @@ -618,7 +658,7 @@ void* RunCoreThread(void *arg) // Get the user's input, execute a single emulation frame, and generate // the frame output. - [cdsCore.cdsController update]; + [(CocoaDSController *)param->cdsController update]; NDS_beginProcessingInput(); // Shouldn't need to do any special processing steps in between. @@ -635,14 +675,14 @@ void* RunCoreThread(void *arg) NDS_exec(); pthread_mutex_unlock(param->mutexCoreExecute); - if (param->framesToSkip == 0 || !param->isFrameSkipEnabled) + if (param->framesToSkip == 0) { param->frameCount++; } for(CocoaDSOutput *cdsOutput in cdsOutputList) { - if (param->isFrameSkipEnabled && param->framesToSkip > 0 && [cdsOutput isMemberOfClass:[CocoaDSDisplay class]]) + if (param->framesToSkip > 0 && [cdsOutput isMemberOfClass:[CocoaDSDisplay class]]) { pthread_mutex_unlock(cdsOutput.mutexOutputFrame); continue; diff --git a/desmume/src/cocoa/cocoa_file.mm b/desmume/src/cocoa/cocoa_file.mm index 2fcf05df5..f0365fad9 100644 --- a/desmume/src/cocoa/cocoa_file.mm +++ b/desmume/src/cocoa/cocoa_file.mm @@ -870,8 +870,6 @@ return result; } - NSFileManager *fileManager = [[NSFileManager alloc] init]; - NSString *newLocationPath = [[CocoaDSFile directoryURLByKind:[CocoaDSFile fileKindByURL:fileURL]] path]; if (newLocationPath == nil) { @@ -880,8 +878,9 @@ NSString *filePath = [fileURL path]; newLocationPath = [newLocationPath stringByAppendingPathComponent:[filePath lastPathComponent]]; - result = [fileManager moveItemAtPath:filePath toPath:newLocationPath error:nil]; + NSFileManager *fileManager = [[NSFileManager alloc] init]; + result = [fileManager moveItemAtPath:filePath toPath:newLocationPath error:nil]; [fileManager release]; return result; @@ -896,8 +895,6 @@ return result; } - NSFileManager *fileManager = [[NSFileManager alloc] init]; - NSString *newLocationPath = [[CocoaDSFile directoryURLByKind:[CocoaDSFile fileKindByURL:fileURL]] path]; if (newLocationPath == nil) { @@ -906,8 +903,9 @@ NSString *filePath = [fileURL path]; newLocationPath = [newLocationPath stringByAppendingPathComponent:[filePath lastPathComponent]]; - result = [fileManager copyItemAtPath:filePath toPath:newLocationPath error:nil]; + NSFileManager *fileManager = [[NSFileManager alloc] init]; + result = [fileManager copyItemAtPath:filePath toPath:newLocationPath error:nil]; [fileManager release]; return result; diff --git a/desmume/src/cocoa/cocoa_firmware.h b/desmume/src/cocoa/cocoa_firmware.h index ac526ca3c..c39fb0277 100644 --- a/desmume/src/cocoa/cocoa_firmware.h +++ b/desmume/src/cocoa/cocoa_firmware.h @@ -45,8 +45,8 @@ @property (assign) struct NDS_fw_config_data *data; @property (assign) NSInteger consoleType; -@property (assign) NSString *nickname; -@property (assign) NSString *message; +@property (copy) NSString *nickname; +@property (copy) NSString *message; @property (assign) NSInteger favoriteColor; @property (assign) NSDate *birthday; @property (assign) NSInteger language; diff --git a/desmume/src/cocoa/cocoa_firmware.mm b/desmume/src/cocoa/cocoa_firmware.mm index 10d9be38a..ee93898a7 100644 --- a/desmume/src/cocoa/cocoa_firmware.mm +++ b/desmume/src/cocoa/cocoa_firmware.mm @@ -122,29 +122,32 @@ - (void) setNickname:(NSString *)theNickname { - if (theNickname == nil) - { - return; - } - pthread_mutex_lock(&mutex); - - NSRange characterRange = {0, [theNickname length]}; - if (characterRange.length > MAX_FW_NICKNAME_LENGTH) + if (theNickname != nil) { - characterRange.length = MAX_FW_NICKNAME_LENGTH; + NSRange characterRange = {0, [theNickname length]}; + + if (characterRange.length > MAX_FW_NICKNAME_LENGTH) + { + characterRange.length = MAX_FW_NICKNAME_LENGTH; + } + + [theNickname getBytes:&data->nickname[0] + maxLength:(sizeof(UInt16) * characterRange.length) + usedLength:NULL + encoding:NSUTF16LittleEndianStringEncoding + options:NSStringEncodingConversionAllowLossy + range:characterRange + remainingRange:NULL]; + + data->nickname_len = (u8)characterRange.length; + } + else + { + memset(&data->nickname[0], 0, sizeof(data->nickname)); + data->nickname_len = 0; } - - [theNickname getBytes:&data->nickname[0] - maxLength:(sizeof(UInt16) * characterRange.length) - usedLength:NULL - encoding:NSUTF16LittleEndianStringEncoding - options:NSStringEncodingConversionAllowLossy - range:characterRange - remainingRange:NULL]; - - data->nickname_len = (u8)characterRange.length; pthread_mutex_unlock(&mutex); } @@ -160,29 +163,32 @@ - (void) setMessage:(NSString *)theMessage { - if (theMessage == nil) - { - return; - } - pthread_mutex_lock(&mutex); - - NSRange characterRange = {0, [theMessage length]}; - if (characterRange.length > MAX_FW_MESSAGE_LENGTH) + if (theMessage != nil) { - characterRange.length = MAX_FW_MESSAGE_LENGTH; + NSRange characterRange = {0, [theMessage length]}; + + if (characterRange.length > MAX_FW_MESSAGE_LENGTH) + { + characterRange.length = MAX_FW_MESSAGE_LENGTH; + } + + [theMessage getBytes:&data->message[0] + maxLength:(sizeof(UInt16) * characterRange.length) + usedLength:NULL + encoding:NSUTF16LittleEndianStringEncoding + options:NSStringEncodingConversionAllowLossy + range:characterRange + remainingRange:NULL]; + + data->message_len = (u8)characterRange.length; + } + else + { + memset(&data->message[0], 0, sizeof(data->message)); + data->message_len = 0; } - - [theMessage getBytes:&data->message[0] - maxLength:(sizeof(UInt16) * characterRange.length) - usedLength:NULL - encoding:NSUTF16LittleEndianStringEncoding - options:NSStringEncodingConversionAllowLossy - range:characterRange - remainingRange:NULL]; - - data->message_len = (u8)characterRange.length; pthread_mutex_unlock(&mutex); } @@ -214,29 +220,33 @@ - (void) setBirthday:(NSDate *)theDate { - if (theDate == nil) - { - return; - } - pthread_mutex_lock(&mutex); + + if (theDate != nil) + { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - - [dateFormatter setDateFormat:@"M"]; - NSInteger theMonth = [[dateFormatter stringFromDate:theDate] integerValue]; - - [dateFormatter setDateFormat:@"d"]; - NSInteger theDay = [[dateFormatter stringFromDate:theDate] integerValue]; - - [dateFormatter setDateFormat:@"Y"]; - NSInteger theYear = [[dateFormatter stringFromDate:theDate] integerValue]; - - [dateFormatter release]; - - data->birth_month = (u8)theMonth; - data->birth_day = (u8)theDay; - birth_year = theYear; + [dateFormatter setDateFormat:@"M"]; + NSInteger theMonth = [[dateFormatter stringFromDate:theDate] integerValue]; + + [dateFormatter setDateFormat:@"d"]; + NSInteger theDay = [[dateFormatter stringFromDate:theDate] integerValue]; + + [dateFormatter setDateFormat:@"Y"]; + NSInteger theYear = [[dateFormatter stringFromDate:theDate] integerValue]; + + [dateFormatter release]; + + data->birth_month = (u8)theMonth; + data->birth_day = (u8)theDay; + birth_year = theYear; + } + else + { + data->birth_month = 1; + data->birth_day = 1; + birth_year = 1970; + } pthread_mutex_unlock(&mutex); } diff --git a/desmume/src/cocoa/cocoa_hid.h b/desmume/src/cocoa/cocoa_hid.h index 3740c69a4..66cf52022 100644 --- a/desmume/src/cocoa/cocoa_hid.h +++ b/desmume/src/cocoa/cocoa_hid.h @@ -17,6 +17,7 @@ */ #import +#include #include @@ -25,10 +26,11 @@ IOHIDDeviceRef hidDeviceRef; IOHIDQueueRef hidQueueRef; NSRunLoop *runLoop; + OSSpinLock spinlockRunLoop; } @property (readonly) IOHIDDeviceRef hidDeviceRef; -@property (assign) NSRunLoop *runLoop; +@property (retain) NSRunLoop *runLoop; - (id) initWithDevice:(IOHIDDeviceRef)theDevice; @@ -56,11 +58,12 @@ IOHIDManagerRef hidManagerRef; NSRunLoop *runLoop; NSMutableSet *deviceList; + OSSpinLock spinlockRunLoop; } @property (readonly) IOHIDManagerRef hidManagerRef; @property (readonly) NSMutableSet *deviceList; -@property (assign) NSRunLoop *runLoop; +@property (retain) NSRunLoop *runLoop; @end diff --git a/desmume/src/cocoa/cocoa_hid.mm b/desmume/src/cocoa/cocoa_hid.mm index 8a4edc521..56219716f 100644 --- a/desmume/src/cocoa/cocoa_hid.mm +++ b/desmume/src/cocoa/cocoa_hid.mm @@ -63,7 +63,7 @@ extern "C" @implementation CocoaHIDDevice @synthesize hidDeviceRef; -@synthesize runLoop; +@dynamic runLoop; static NSDictionary *hidUsageTable = nil; @@ -105,6 +105,7 @@ static NSDictionary *hidUsageTable = nil; CFRelease(elementArray); + spinlockRunLoop = OS_SPINLOCK_INIT; [self setRunLoop:[NSRunLoop currentRunLoop]]; return self; @@ -127,25 +128,39 @@ static NSDictionary *hidUsageTable = nil; - (void) setRunLoop:(NSRunLoop *)theRunLoop { - if (theRunLoop == nil && runLoop != nil) + OSSpinLockLock(&spinlockRunLoop); + + if (theRunLoop == runLoop) + { + OSSpinLockUnlock(&spinlockRunLoop); + return; + } + + if (theRunLoop == nil) { IOHIDQueueRegisterValueAvailableCallback(hidQueueRef, NULL, NULL); IOHIDQueueUnscheduleFromRunLoop(hidQueueRef, [runLoop getCFRunLoop], kCFRunLoopDefaultMode); - [runLoop release]; } - - runLoop = theRunLoop; - if (runLoop != nil) + else { - [runLoop retain]; + [theRunLoop retain]; IOHIDQueueScheduleWithRunLoop(hidQueueRef, [theRunLoop getCFRunLoop], kCFRunLoopDefaultMode); IOHIDQueueRegisterValueAvailableCallback(hidQueueRef, HandleQueueValueAvailableCallback, self); } + + [runLoop release]; + runLoop = theRunLoop; + + OSSpinLockUnlock(&spinlockRunLoop); } - (NSRunLoop *) runLoop { - return runLoop; + OSSpinLockLock(&spinlockRunLoop); + NSRunLoop *theRunLoop = runLoop; + OSSpinLockUnlock(&spinlockRunLoop); + + return theRunLoop; } - (void) start @@ -707,7 +722,7 @@ static NSDictionary *hidUsageTable = nil; @synthesize hidManagerRef; @synthesize deviceList; -@synthesize runLoop; +@dynamic runLoop; - (id)init { @@ -733,11 +748,16 @@ static NSDictionary *hidUsageTable = nil; CFMutableDictionaryRef cfGamepadMatcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(cfGamepadMatcher, CFSTR(kIOHIDDeviceUsagePageKey), (CFNumberRef)[NSNumber numberWithInteger:kHIDPage_GenericDesktop]); CFDictionarySetValue(cfGamepadMatcher, CFSTR(kIOHIDDeviceUsageKey), (CFNumberRef)[NSNumber numberWithInteger:kHIDUsage_GD_GamePad]); - - NSArray *matcherArray = [NSArray arrayWithObjects:(NSMutableDictionary *)cfJoystickMatcher, (NSMutableDictionary *)cfGamepadMatcher, nil]; + + NSArray *matcherArray = [[NSArray alloc] initWithObjects:(NSMutableDictionary *)cfJoystickMatcher, (NSMutableDictionary *)cfGamepadMatcher, nil]; IOHIDManagerSetDeviceMatchingMultiple(hidManagerRef, (CFArrayRef)matcherArray); + [matcherArray release]; + CFRelease(cfJoystickMatcher); + CFRelease(cfGamepadMatcher); + + spinlockRunLoop = OS_SPINLOCK_INIT; [self setRunLoop:[NSRunLoop currentRunLoop]]; IOReturn result = IOHIDManagerOpen(hidManagerRef, kIOHIDOptionsTypeNone); @@ -752,9 +772,8 @@ static NSDictionary *hidUsageTable = nil; - (void)dealloc { - [self.deviceList release]; - self.runLoop = nil; + [deviceList release]; if (hidManagerRef != NULL) { @@ -768,27 +787,41 @@ static NSDictionary *hidUsageTable = nil; - (void) setRunLoop:(NSRunLoop *)theRunLoop { - if (theRunLoop == nil && runLoop != nil) + OSSpinLockLock(&spinlockRunLoop); + + if (theRunLoop == runLoop) + { + OSSpinLockUnlock(&spinlockRunLoop); + return; + } + + if (theRunLoop == nil) { IOHIDManagerRegisterDeviceMatchingCallback(hidManagerRef, NULL, NULL); IOHIDManagerRegisterDeviceRemovalCallback(hidManagerRef, NULL, NULL); IOHIDManagerUnscheduleFromRunLoop(hidManagerRef, [runLoop getCFRunLoop], kCFRunLoopDefaultMode); - [runLoop release]; } - - runLoop = theRunLoop; - if (runLoop != nil) + else { - [runLoop retain]; + [theRunLoop retain]; IOHIDManagerScheduleWithRunLoop(hidManagerRef, [theRunLoop getCFRunLoop], kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceMatchingCallback(hidManagerRef, HandleDeviceMatchingCallback, self); IOHIDManagerRegisterDeviceRemovalCallback(hidManagerRef, HandleDeviceRemovalCallback, self); } + + [runLoop release]; + runLoop = theRunLoop; + + OSSpinLockUnlock(&spinlockRunLoop); } - (NSRunLoop *) runLoop { - return runLoop; + OSSpinLockLock(&spinlockRunLoop); + NSRunLoop *theRunLoop = runLoop; + OSSpinLockUnlock(&spinlockRunLoop); + + return theRunLoop; } @end @@ -819,6 +852,7 @@ void HandleQueueValueAvailableCallback(void *inContext, IOReturn inResult, void { IOHIDQueueRef hidQueue = (IOHIDQueueRef)inSender; NSMutableArray *inputAttributesList = nil; + NSAutoreleasePool *hidPool = [[NSAutoreleasePool alloc] init]; do { @@ -849,4 +883,6 @@ void HandleQueueValueAvailableCallback(void *inContext, IOReturn inResult, void CFRelease(hidValueRef); } while (1); + + [hidPool release]; } diff --git a/desmume/src/cocoa/cocoa_input.h b/desmume/src/cocoa/cocoa_input.h index fb346f006..1c3dbeddf 100644 --- a/desmume/src/cocoa/cocoa_input.h +++ b/desmume/src/cocoa/cocoa_input.h @@ -29,9 +29,9 @@ NSString *deviceName; } -@property (assign) NSMutableDictionary *map; -@property (assign) NSString *deviceCode; -@property (assign) NSString *deviceName; +@property (retain) NSMutableDictionary *map; +@property (copy) NSString *deviceCode; +@property (copy) NSString *deviceName; - (id) initWithDeviceCode:(NSString *)theCode name:(NSString *)theName; @@ -61,11 +61,13 @@ NSMutableDictionary *inputs; } -@property (assign) NSMutableDictionary *states; -@property (assign) CocoaDSMic *cdsMic; -@property (assign) NSMutableDictionary *inputs; +@property (readonly) NSMutableDictionary *states; +@property (retain) CocoaDSMic *cdsMic; +@property (readonly) NSMutableDictionary *inputs; @property (readonly) pthread_mutex_t *mutexControllerUpdate; +- (id) initWithMic:(CocoaDSMic *)theMic; + - (void) initDefaultMappings; - (BOOL) initUserDefaultMappings; - (void) initControllerMap; diff --git a/desmume/src/cocoa/cocoa_input.mm b/desmume/src/cocoa/cocoa_input.mm index 15bbc9e53..a3aab2d84 100644 --- a/desmume/src/cocoa/cocoa_input.mm +++ b/desmume/src/cocoa/cocoa_input.mm @@ -44,27 +44,36 @@ return self; } - map = [[NSMutableDictionary alloc] init]; - deviceCode = theCode; - deviceName = theName; + map = [[NSMutableDictionary alloc] initWithCapacity:32]; if (theCode == nil) { - deviceCode = [NSString stringWithFormat:@"0x%08X", rand()]; + deviceCode = [[NSString stringWithFormat:@"0x%08X", rand()] retain]; + } + else + { + deviceCode = [theCode copy]; } if (theName == nil) { deviceName = @"Unknown Device "; - deviceName = [deviceName stringByAppendingString:deviceCode]; + deviceName = [[deviceName stringByAppendingString:deviceCode] retain]; } + else + { + deviceName = [theName copy]; + } + return self; } - (void)dealloc { - [self.map release]; + self.map = nil; + self.deviceCode = nil; + self.deviceName = nil; [super dealloc]; } @@ -172,6 +181,11 @@ @synthesize mutexControllerUpdate; - (id)init +{ + return [self initWithMic:nil]; +} + +- (id) initWithMic:(CocoaDSMic *)theMic { self = [super init]; if (self == nil) @@ -182,8 +196,8 @@ mutexControllerUpdate = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mutexControllerUpdate, NULL); + cdsMic = [theMic retain]; states = [[NSMutableDictionary alloc] init]; - cdsMic = [[CocoaDSMic alloc] init]; inputs = [[NSMutableDictionary alloc] initWithCapacity:10]; [self initDefaultMappings]; @@ -200,9 +214,9 @@ { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [self.states release]; - [self.cdsMic release]; - [self.inputs release]; + self.cdsMic = nil; + [states release]; + [inputs release]; pthread_mutex_destroy(self.mutexControllerUpdate); free(self.mutexControllerUpdate); @@ -329,7 +343,7 @@ deviceName = deviceCode; } - input = [[CocoaDSInput alloc] initWithDeviceCode:deviceCode name:deviceName]; + input = [[[CocoaDSInput alloc] initWithDeviceCode:deviceCode name:deviceName] autorelease]; [self.inputs setValue:input forKey:deviceCode]; } diff --git a/desmume/src/cocoa/cocoa_output.h b/desmume/src/cocoa/cocoa_output.h index 09927af1b..819cb75af 100644 --- a/desmume/src/cocoa/cocoa_output.h +++ b/desmume/src/cocoa/cocoa_output.h @@ -35,8 +35,8 @@ @property (assign) BOOL isStateChanged; @property (assign) NSUInteger frameCount; -@property (assign) NSData *frameData; -@property (assign) NSMutableDictionary *property; +@property (retain) NSData *frameData; +@property (readonly) NSMutableDictionary *property; @property (readonly) pthread_mutex_t *mutexOutputFrame; - (void) doCoreEmuFrame; @@ -100,7 +100,7 @@ - (void) doInitVideoOutput:(NSDictionary *)properties; - (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize; -@property (assign) NSPort *sendPortDisplay; +@property (retain) NSPort *sendPortDisplay; @optional - (void) doResizeView:(NSRect)rect; @@ -123,6 +123,7 @@ CocoaVideoFilter *vf; pthread_mutex_t *mutexRender3D; + OSSpinLock spinlockDelegate; OSSpinLock spinlockGpuState; OSSpinLock spinlockDisplayType; OSSpinLock spinlockVideoFilterType; @@ -138,7 +139,7 @@ } @property (assign) UInt32 gpuStateFlags; -@property (assign) id delegate; +@property (retain) id delegate; @property (assign) NSInteger displayType; @property (assign) CocoaVideoFilter *vf; @property (readonly) pthread_mutex_t *mutexRender3D; diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index dbf6095c3..c1f4e31cc 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -89,7 +89,7 @@ SoundInterface_struct *SNDCoreList[] = { } } - [frameData release]; + self.frameData = nil; [property release]; pthread_mutex_destroy(mutexOutputFrame); @@ -124,13 +124,7 @@ SoundInterface_struct *SNDCoreList[] = { - (void) handleEmuFrameProcessed:(NSData *)theData { self.frameCount++; - - if (self.frameData != theData) - { - [self.frameData release]; - self.frameData = theData; - [self.frameData retain]; - } + self.frameData = theData; } @end @@ -521,6 +515,7 @@ static BOOL isSPUStarted = NO; mutexRender3D = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(mutexRender3D, NULL); + spinlockDelegate = OS_SPINLOCK_INIT; spinlockGpuState = OS_SPINLOCK_INIT; spinlockDisplayType = OS_SPINLOCK_INIT; spinlockVideoFilterType = OS_SPINLOCK_INIT; @@ -584,6 +579,7 @@ static BOOL isSPUStarted = NO; - (void)dealloc { + self.delegate = nil; [vf release]; pthread_mutex_destroy(self.mutexRender3D); @@ -595,22 +591,33 @@ static BOOL isSPUStarted = NO; - (void) setDelegate:(id )theDelegate { - if (theDelegate == nil) + OSSpinLockLock(&spinlockDelegate); + + if (theDelegate == delegate) { - [delegate release]; + OSSpinLockUnlock(&spinlockDelegate); + return; } - else + + if (theDelegate != nil) { [theDelegate retain]; [theDelegate setSendPortDisplay:self.receivePort]; } + [delegate release]; delegate = theDelegate; + + OSSpinLockUnlock(&spinlockDelegate); } - (id ) delegate { - return delegate; + OSSpinLockLock(&spinlockDelegate); + id theDelegate = delegate; + OSSpinLockUnlock(&spinlockDelegate); + + return theDelegate; } - (void) setGpuStateFlags:(UInt32)flags @@ -1328,8 +1335,8 @@ static BOOL isSPUStarted = NO; { return; } - - NSData *gpuData = [[NSData alloc] initWithBytes:texData length:dataSize]; + + NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease]; if (gpuData == nil) { return; @@ -1337,7 +1344,6 @@ static BOOL isSPUStarted = NO; [delegate doProcessVideoFrame:texData frameSize:destSize]; - [self.frameData release]; self.frameData = gpuData; free(texData); @@ -1366,7 +1372,7 @@ static BOOL isSPUStarted = NO; memset(texData, 255, dataSize); - NSData *gpuData = [[NSData alloc] initWithBytes:texData length:dataSize]; + NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease]; if (gpuData == nil) { return; @@ -1374,7 +1380,6 @@ static BOOL isSPUStarted = NO; [delegate doProcessVideoFrame:texData frameSize:destSize]; - [self.frameData release]; self.frameData = gpuData; free(texData); @@ -1385,24 +1390,23 @@ static BOOL isSPUStarted = NO; { NSString *fileURLString = [[NSString alloc] initWithData:fileURLStringData encoding:NSUTF8StringEncoding]; NSURL *fileURL = [NSURL URLWithString:fileURLString]; - NSBitmapImageFileType *fileType = (NSBitmapImageFileType *)[fileTypeData bytes]; - NSImage *screenshotImage = [[self image] autorelease]; + NSBitmapImageFileType *fileType = (NSBitmapImageFileType *)[fileTypeData bytes]; - - NSMutableDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: - fileURL, @"fileURL", - [NSNumber numberWithInteger:(NSInteger)*fileType], @"fileType", - screenshotImage, @"screenshotImage", - nil]; + NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys: + fileURL, @"fileURL", + [NSNumber numberWithInteger:(NSInteger)*fileType], @"fileType", + [self image], @"screenshotImage", + nil]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"com.DeSmuME.DeSmuME.requestScreenshotDidFinish" object:self userInfo:userInfo]; + [userInfo release]; [fileURLString release]; } - (void) handleCopyToPasteboard { - NSImage *screenshot = [[self image] autorelease]; + NSImage *screenshot = [self image]; if (screenshot == nil) { return; @@ -1433,7 +1437,7 @@ static BOOL isSPUStarted = NO; // Attach the rendered frame to the NSImageRep [newImage addRepresentation:newImageRep]; - return newImage; + return [newImage autorelease]; } - (NSBitmapImageRep *) bitmapImageRep diff --git a/desmume/src/cocoa/cocoa_rom.h b/desmume/src/cocoa/cocoa_rom.h index fa46604b4..8e60fc721 100644 --- a/desmume/src/cocoa/cocoa_rom.h +++ b/desmume/src/cocoa/cocoa_rom.h @@ -33,10 +33,10 @@ NSMutableArray *xmlCharacterStack; } -@property (assign) NSMutableDictionary *header; -@property (assign) NSMutableDictionary *bindings; -@property (assign) NSURL *fileURL; -@property (assign) BOOL isDataLoaded; +@property (readonly) NSMutableDictionary *header; +@property (readonly) NSMutableDictionary *bindings; +@property (readonly) NSURL *fileURL; +@property (readonly) BOOL isDataLoaded; @property (assign) NSInteger saveType; - (id) initWithURL:(NSURL *)theURL; diff --git a/desmume/src/cocoa/cocoa_rom.mm b/desmume/src/cocoa/cocoa_rom.mm index 85699bbf8..d4bbffd41 100644 --- a/desmume/src/cocoa/cocoa_rom.mm +++ b/desmume/src/cocoa/cocoa_rom.mm @@ -69,7 +69,7 @@ static NSMutableDictionary *saveTypeValues = nil; nil]; } - header = [[NSMutableDictionary alloc] init]; + header = [[NSMutableDictionary alloc] initWithCapacity:32]; if (header == nil) { [self release]; @@ -104,23 +104,17 @@ static NSMutableDictionary *saveTypeValues = nil; - (void)dealloc { - if (self.isDataLoaded) + if (isDataLoaded) { NDS_FreeROM(); - self.isDataLoaded = NO; + isDataLoaded = NO; } [xmlElementStack release]; [xmlCharacterStack release]; - - [self.header release]; - self.header = nil; - - [self.bindings release]; - self.bindings = nil; - - [self.fileURL release]; - self.fileURL = nil; + [header release]; + [bindings release]; + [fileURL release]; [super dealloc]; } @@ -216,13 +210,14 @@ static NSMutableDictionary *saveTypeValues = nil; BOOL result = [CocoaDSFile loadRom:theURL]; if (!result) { - NSMutableDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], @"DidLoad", nil]; + NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:NO], @"DidLoad", nil]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"com.DeSmuME.DeSmuME.loadRomDidFinish" object:self userInfo:userInfo]; + [userInfo release]; return result; } - self.fileURL = [theURL copyWithZone:nil]; - self.isDataLoaded = YES; + fileURL = [theURL copy]; + isDataLoaded = YES; [self initHeader]; NSString *advscDBPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"Advanscene_DatabasePath"]; @@ -236,21 +231,26 @@ static NSMutableDictionary *saveTypeValues = nil; [xmlError release]; } - NSMutableDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"DidLoad", self.fileURL, @"URL", nil]; + NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"DidLoad", self.fileURL, @"URL", nil]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"com.DeSmuME.DeSmuME.loadRomDidFinish" object:self userInfo:userInfo]; + [userInfo release]; return result; } - (void) loadDataOnThread:(id)object { - NSURL *theURL = [(NSURL *)object copyWithZone:nil]; + [self retain]; + + NSURL *theURL = [(NSURL *)object copy]; NSAutoreleasePool *threadPool = [[NSAutoreleasePool alloc] init]; [self loadData:theURL]; [threadPool release]; [theURL release]; + + [self release]; } - (NSString *) getRomTitle diff --git a/desmume/src/cocoa/cocoa_util.h b/desmume/src/cocoa/cocoa_util.h index 7aa26912f..86d9e36c0 100644 --- a/desmume/src/cocoa/cocoa_util.h +++ b/desmume/src/cocoa/cocoa_util.h @@ -58,10 +58,10 @@ NSPort *receivePort; } -@property (assign) NSThread *thread; +@property (retain) NSThread *thread; @property (assign) BOOL threadExit; @property (assign) NSTimeInterval autoreleaseInterval; -@property (assign) NSPort *sendPort; +@property (retain) NSPort *sendPort; @property (readonly) NSPort *receivePort; - (id) initWithAutoreleaseInterval:(NSTimeInterval)interval; diff --git a/desmume/src/cocoa/cocoa_util.mm b/desmume/src/cocoa/cocoa_util.mm index 44a28c029..c93a79aaa 100644 --- a/desmume/src/cocoa/cocoa_util.mm +++ b/desmume/src/cocoa/cocoa_util.mm @@ -31,9 +31,7 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; { NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:sendPort receivePort:nil components:nil]; [message setMsgid:msgID]; - NSDate *sendDate = [[NSDate alloc] init]; [message sendBeforeDate:distantFutureDate]; - [sendDate release]; [message release]; } @@ -41,9 +39,7 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; { NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:sendPort receivePort:nil components:msgDataArray]; [message setMsgid:msgID]; - NSDate *sendDate = [[NSDate alloc] init]; [message sendBeforeDate:distantFutureDate]; - [sendDate release]; [message release]; } @@ -176,8 +172,9 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; } } - [self.sendPort release]; - [self.receivePort release]; + self.sendPort = nil; + [receivePort release]; + [super dealloc]; } @@ -187,7 +184,7 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; NSRunLoop *runLoop = [[NSRunLoop currentRunLoop] retain]; [runLoop addPort:self.receivePort forMode:NSDefaultRunLoopMode]; - self.thread = [[NSThread currentThread] retain]; + self.thread = [NSThread currentThread]; do { @@ -198,7 +195,6 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; [runLoopPool release]; } while (!self.threadExit); - [self.thread release]; self.thread = nil; [runLoop release]; diff --git a/desmume/src/cocoa/cocoa_videofilter.mm b/desmume/src/cocoa/cocoa_videofilter.mm index 27c6db268..207096cdc 100644 --- a/desmume/src/cocoa/cocoa_videofilter.mm +++ b/desmume/src/cocoa/cocoa_videofilter.mm @@ -100,7 +100,7 @@ [newImage addRepresentation:newImageRep]; - return newImage; + return [newImage autorelease]; } - (NSBitmapImageRep *) bitmapImageRep diff --git a/desmume/src/cocoa/userinterface/appDelegate.mm b/desmume/src/cocoa/userinterface/appDelegate.mm index 3e010f6ba..d4c6f24fe 100644 --- a/desmume/src/cocoa/userinterface/appDelegate.mm +++ b/desmume/src/cocoa/userinterface/appDelegate.mm @@ -146,7 +146,7 @@ [self setHidManager:[[[CocoaHIDManager alloc] init] autorelease]]; // Set the display view delegate. - DisplayViewDelegate *newDispViewDelegate = [[DisplayViewDelegate alloc] init]; + DisplayViewDelegate *newDispViewDelegate = [[[DisplayViewDelegate alloc] init] autorelease]; [newDispViewDelegate setView:[mainWindowDelegate displayView]]; [mainWindowDelegate setDispViewDelegate:newDispViewDelegate]; [[mainWindowDelegate displayView] setDispViewDelegate:newDispViewDelegate]; @@ -156,7 +156,8 @@ [cdsCoreController setContent:newCore]; // Init the DS controller and microphone. - CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease]; + CocoaDSMic *newMic = [[[CocoaDSMic alloc] init] autorelease]; + CocoaDSController *newController = [[[CocoaDSController alloc] initWithMic:newMic] autorelease]; [newCore setCdsController:newController]; [inputPrefsView setCdsController:newController]; [newDispViewDelegate setCdsController:newController]; @@ -399,7 +400,7 @@ [[NSUserDefaults standardUserDefaults] objectForKey:@"FirmwareConfig_Language"], @"Language", nil]; - CocoaDSFirmware *newFirmware = [[CocoaDSFirmware alloc] initWithDictionary:newFWDict]; + CocoaDSFirmware *newFirmware = [[[CocoaDSFirmware alloc] initWithDictionary:newFWDict] autorelease]; [cdsCore setCdsFirmware:newFirmware]; [newFirmware update]; diff --git a/desmume/src/cocoa/userinterface/cheatWindowDelegate.h b/desmume/src/cocoa/userinterface/cheatWindowDelegate.h index c40634c55..0c91b2282 100644 --- a/desmume/src/cocoa/userinterface/cheatWindowDelegate.h +++ b/desmume/src/cocoa/userinterface/cheatWindowDelegate.h @@ -92,10 +92,10 @@ @property (readonly) IBOutlet NSWindow *cheatDatabaseSheet; @property (assign) NSUInteger untitledCount; -@property (assign) NSMutableDictionary *bindings; -@property (assign) CocoaDSCheatItem *workingCheat; -@property (assign) CocoaDSCheatManager *cdsCheats; -@property (assign) CocoaDSCheatSearch *cdsCheatSearch; +@property (readonly) NSMutableDictionary *bindings; +@property (retain) CocoaDSCheatItem *workingCheat; +@property (retain) CocoaDSCheatManager *cdsCheats; +@property (readonly) CocoaDSCheatSearch *cdsCheatSearch; - (IBAction) addToList:(id)sender; - (IBAction) removeFromList:(id)sender; diff --git a/desmume/src/cocoa/userinterface/cheatWindowDelegate.mm b/desmume/src/cocoa/userinterface/cheatWindowDelegate.mm index a1233c88e..758741a08 100644 --- a/desmume/src/cocoa/userinterface/cheatWindowDelegate.mm +++ b/desmume/src/cocoa/userinterface/cheatWindowDelegate.mm @@ -99,6 +99,8 @@ - (void)dealloc { + self.workingCheat = nil; + self.cdsCheats = nil; [cdsCheatSearch release]; [bindings release]; diff --git a/desmume/src/cocoa/userinterface/displayView.h b/desmume/src/cocoa/userinterface/displayView.h index 264fc8e1d..fafaec1dc 100644 --- a/desmume/src/cocoa/userinterface/displayView.h +++ b/desmume/src/cocoa/userinterface/displayView.h @@ -65,11 +65,15 @@ OSSpinLock spinlockUseBilinearOutput; } -@property (assign) NSView *view; -@property (assign) NSPort *sendPortInput; +@property (retain) NSView *view; +@property (retain) NSPort *sendPortInput; @property (retain) CocoaDSController *cdsController; @property (readonly) NSSize normalSize; -@property (assign) NSMutableDictionary *bindings; +@property (assign) double scale; +@property (assign) double rotation; +@property (assign) BOOL useBilinearOutput; +@property (assign) NSInteger displayType; +@property (readonly) NSMutableDictionary *bindings; - (void) setGpuStateFlags:(UInt32)flags; - (UInt32) gpuStateFlags; diff --git a/desmume/src/cocoa/userinterface/displayView.mm b/desmume/src/cocoa/userinterface/displayView.mm index 9e2b8fabc..80b0fc2c2 100644 --- a/desmume/src/cocoa/userinterface/displayView.mm +++ b/desmume/src/cocoa/userinterface/displayView.mm @@ -37,7 +37,11 @@ @synthesize cdsController; @synthesize isHudEnabled; @synthesize isHudEditingModeEnabled; -@synthesize normalSize; +@dynamic normalSize; +@dynamic scale; +@dynamic rotation; +@dynamic useBilinearOutput; +@dynamic displayType; @synthesize bindings; - (id)init @@ -105,6 +109,10 @@ - (void)dealloc { + self.view = nil; + self.cdsController = nil; + [bindings release]; + [super dealloc]; } diff --git a/desmume/src/cocoa/userinterface/emuWindowDelegate.h b/desmume/src/cocoa/userinterface/emuWindowDelegate.h index 1ee043d76..190ab803a 100644 --- a/desmume/src/cocoa/userinterface/emuWindowDelegate.h +++ b/desmume/src/cocoa/userinterface/emuWindowDelegate.h @@ -89,9 +89,9 @@ @property (readonly) IBOutlet NSView *displayView; @property (readonly) IBOutlet NSView *exportRomSavePanelAccessoryView; @property (readonly) IBOutlet NSView *saveScreenshotPanelAccessoryView; -@property (assign) CocoaDSRom *currentRom; -@property (assign) CocoaDSSpeaker *cdsSpeaker; -@property (assign) CocoaDSCheatManager *cdsCheats; +@property (retain) CocoaDSRom *currentRom; +@property (retain) CocoaDSSpeaker *cdsSpeaker; +@property (retain) CocoaDSCheatManager *cdsCheats; @property (retain) DisplayViewDelegate *dispViewDelegate; @property (readonly) IBOutlet CheatWindowDelegate *cheatWindowDelegate; @@ -110,7 +110,7 @@ @property (assign) BOOL isShowingFileMigrationSheet; @property (assign) NSInteger selectedRomSaveTypeID; -@property (assign) NSMutableDictionary *bindings; +@property (readonly) NSMutableDictionary *bindings; - (void) setContentScalar:(double)s; - (void) setContentRotation:(double)angleDegrees; diff --git a/desmume/src/cocoa/userinterface/emuWindowDelegate.mm b/desmume/src/cocoa/userinterface/emuWindowDelegate.mm index 085661e4b..13995a92c 100644 --- a/desmume/src/cocoa/userinterface/emuWindowDelegate.mm +++ b/desmume/src/cocoa/userinterface/emuWindowDelegate.mm @@ -139,7 +139,11 @@ [iconVolumeOneThird release]; [iconVolumeMute release]; [bindings release]; + [self setDispViewDelegate:nil]; + [self setCdsCheats:nil]; + [self setCdsSpeaker:nil]; + [self setCurrentRom:nil]; [super dealloc]; } @@ -1151,7 +1155,7 @@ // Need to pause the core before loading the ROM. [self pauseCore]; - CocoaDSRom *newRom = [[CocoaDSRom alloc] init]; + CocoaDSRom *newRom = [[[CocoaDSRom alloc] init] autorelease]; if (newRom != nil) { isRomLoading = YES; @@ -1180,11 +1184,6 @@ [self restoreCoreState]; } - if (theRom != nil) - { - [theRom release]; - } - [self setStatus:NSSTRING_STATUS_ROM_LOADING_FAILED]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isWorking"]; @@ -1199,7 +1198,7 @@ // If the ROM has an associated cheat file, load it now. NSString *cheatsPath = [[CocoaDSFile fileURLFromRomURL:[theRom fileURL] toKind:@"Cheat"] path]; CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; - CocoaDSCheatManager *newCheatList = [[CocoaDSCheatManager alloc] initWithURL:cdsCore fileURL:[NSURL fileURLWithPath:cheatsPath]]; + CocoaDSCheatManager *newCheatList = [[[CocoaDSCheatManager alloc] initWithCore:cdsCore fileURL:[NSURL fileURLWithPath:cheatsPath]] autorelease]; if (newCheatList != nil) { NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; @@ -1263,7 +1262,6 @@ } [cheatWindowDelegate setCdsCheats:newCheatList]; - [[cheatWindowDelegate cdsCheats] setCdsCore:cdsCore]; [[cheatWindowDelegate cdsCheatSearch] setCdsCore:cdsCore]; [cheatWindowDelegate setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_EXACT_VALUE]; } @@ -1316,11 +1314,9 @@ [window displayIfNeeded]; // Unload the ROM. - [[self currentRom] release]; [self setCurrentRom:nil]; // Release the current cheat list and assign the empty list. - [[self cdsCheats] release]; [self setCdsCheats:nil]; if (dummyCheatList == nil) { diff --git a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.h b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.h index 7d1794b77..468b83495 100644 --- a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.h +++ b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.h @@ -81,7 +81,7 @@ @property (readonly) IBOutlet NSImageView *previewImageView; -@property (assign) NSMutableDictionary *bindings; +@property (readonly) NSMutableDictionary *bindings; - (IBAction) showGeneralView:(id)sender; - (IBAction) showInputView:(id)sender; diff --git a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm index edb3acf41..ad5ce3355 100644 --- a/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm +++ b/desmume/src/cocoa/userinterface/preferencesWindowDelegate.mm @@ -806,19 +806,19 @@ NSRect newFrame = [window frameRectForContentRect:[theView frame]]; newFrame.origin.x = [window frame].origin.x; newFrame.origin.y = [window frame].origin.y + [[window contentView] frame].size.height - [theView frame].size.height; - - [[window contentView] retain]; NSView *tempView = [[NSView alloc] initWithFrame:[[window contentView] frame]]; [window setContentView:tempView]; [window setFrame:newFrame display:YES animate:YES]; [window setContentView:theView]; + + [tempView release]; } - (void)windowDidBecomeKey:(NSNotification *)notification { - [prefWindowController setContent:self.bindings]; + [prefWindowController setContent:bindings]; } @end