diff --git a/Engine/source/platform/profiler.cpp b/Engine/source/platform/profiler.cpp index c978b9ac2..7460ad315 100644 --- a/Engine/source/platform/profiler.cpp +++ b/Engine/source/platform/profiler.cpp @@ -27,7 +27,7 @@ #endif #if defined(TORQUE_OS_MAC) -#include // For high resolution timer +#include #endif #include "core/stream/fileStream.h" @@ -135,20 +135,26 @@ U32 endHighResolutionTimer(U32 time[2]) void startHighResolutionTimer(U32 time[2]) { - UnsignedWide t; - Microseconds(&t); - time[0] = t.lo; - time[1] = t.hi; + U64 now = mach_absolute_time(); + AssertFatal(sizeof(U32[2]) == sizeof(U64), "Can't pack mach_absolute_time into U32[2]"); + memcpy(time, &now, sizeof(U64)); } U32 endHighResolutionTimer(U32 time[2]) { - UnsignedWide t; - Microseconds(&t); - return t.lo - time[0]; - // given that we're returning a 32 bit integer, and this is unsigned subtraction... - // it will just wrap around, we don't need the upper word of the time. - // NOTE: the code assumes that more than 3 hrs will not go by between calls to startHighResolutionTimer() and endHighResolutionTimer(). - // I mean... that damn well better not happen anyway. + static mach_timebase_info_data_t sTimebaseInfo = {0, 0}; + + U64 now = mach_absolute_time(); + AssertFatal(sizeof(U32[2]) == sizeof(U64), "Can't pack mach_absolute_time into U32[2]"); + U64 then; + memcpy(&then, time, sizeof(U64)); + + if(sTimebaseInfo.denom == 0){ + mach_timebase_info(&sTimebaseInfo); + } + // Handle the micros/nanos conversion first, because shedding a few bits is better than overflowing. + U64 elapsedMicros = ((now - then) / 1000) * sTimebaseInfo.numer / sTimebaseInfo.denom; + + return (U32)elapsedMicros; // Just truncate, and hope we didn't overflow } #else diff --git a/Engine/source/platformMac/macFileIO.mm b/Engine/source/platformMac/macFileIO.mm index 26dca66bb..2815b5af4 100644 --- a/Engine/source/platformMac/macFileIO.mm +++ b/Engine/source/platformMac/macFileIO.mm @@ -68,46 +68,54 @@ bool dFileTouch(const char *path) //----------------------------------------------------------------------------- bool dPathCopy(const char* source, const char* dest, bool nooverwrite) { - NSFileManager *manager = [NSFileManager defaultManager]; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *nsource = [[NSString stringWithUTF8String:source] stringByStandardizingPath]; - NSString *ndest = [[NSString stringWithUTF8String:dest] stringByStandardizingPath]; - NSString *ndestFolder = [ndest stringByDeletingLastPathComponent]; - - if(! [manager fileExistsAtPath:nsource]) - { - Con::errorf("dPathCopy: no file exists at %s",source); - return false; - } - - if( [manager fileExistsAtPath:ndest] ) - { - if(nooverwrite) - { - Con::errorf("dPathCopy: file already exists at %s",dest); - return false; - } - Con::warnf("Deleting files at path: %s", dest); - bool deleted = [manager removeFileAtPath:ndest handler:nil]; - if(!deleted) - { - Con::errorf("Copy failed! Could not delete files at path: %s", dest); - return false; - } - } - - if([manager fileExistsAtPath:ndestFolder] == NO) - { - ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash - Platform::createPath([ndestFolder UTF8String]); - } - - bool ret = [manager copyPath:nsource toPath:ndest handler:nil]; - - [pool release]; - return ret; - + if(source == NULL || dest == NULL) + return false; + + @autoreleasepool { + NSFileManager *manager = [NSFileManager defaultManager]; + + NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; + NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; + NSString *ndestFolder = [ndest stringByDeletingLastPathComponent]; + + if(! [manager fileExistsAtPath:nsource]) + { + Con::errorf("dPathCopy: no file exists at %s",source); + return false; + } + + if( [manager fileExistsAtPath:ndest] ) + { + if(nooverwrite) + { + Con::errorf("dPathCopy: file already exists at %s",dest); + return false; + } + Con::warnf("Deleting files at path: %s", dest); + if(![manager removeItemAtPath:ndest error:nil] || [manager fileExistsAtPath:ndest]) + { + Con::errorf("Copy failed! Could not delete files at path: %s", dest); + return false; + } + } + + if([manager fileExistsAtPath:ndestFolder] == NO) + { + ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash + Platform::createPath([ndestFolder UTF8String]); + } + + bool ret = [manager copyItemAtPath:nsource toPath:ndest error:nil]; + // n.b.: The "success" semantics don't guarantee a copy actually took place, so we'll verify + // because this is surprising behavior for a method called copy. + if( ![manager fileExistsAtPath:ndest] ) + { + Con::warnf("The filemanager returned success, but the file was not copied. Something strange is happening"); + ret = false; + } + return ret; + } + } //----------------------------------------------------------------------------- @@ -116,26 +124,36 @@ bool dFileRename(const char *source, const char *dest) { if(source == NULL || dest == NULL) return false; - - NSFileManager *manager = [NSFileManager defaultManager]; - - NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; - NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; - - if(! [manager fileExistsAtPath:nsource]) - { - Con::errorf("dFileRename: no file exists at %s",source); - return false; - } - - if( [manager fileExistsAtPath:ndest] ) - { - Con::warnf("dFileRename: Deleting files at path: %s", dest); - } - - bool ret = [manager movePath:nsource toPath:ndest handler:nil]; - - return ret; + + @autoreleasepool { + NSFileManager *manager = [NSFileManager defaultManager]; + + NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; + NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; + + if(! [manager fileExistsAtPath:nsource]) + { + Con::errorf("dFileRename: no file exists at %s",source); + return false; + } + + if( [manager fileExistsAtPath:ndest] ) + { + Con::warnf("dFileRename: Deleting files at path: %s", dest); + } + + bool ret = [manager moveItemAtPath:nsource toPath:ndest error:nil]; + // n.b.: The "success" semantics don't guarantee a move actually took place, so we'll verify + // because this is surprising behavior for a method called rename. + + if( ![manager fileExistsAtPath:ndest] ) + { + Con::warnf("The filemanager returned success, but the file was not moved. Something strange is happening"); + ret = false; + } + + return ret; + } } //-----------------------------------------------------------------------------