macVolume.mm
Engine/source/platformMac/macVolume.mm
Classes:
Public Functions
Detailed Description
Public Functions
fsNotifyCallback(ConstFSEventStreamRef stream, void * callbackInfo, size_t numEvents, void * eventPaths, const FSEventStreamEventFlags eventFlags, const FSEventStreamEventId eventIds)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#import <CoreServices/CoreServices.h> 25#import "platform/platform.h" 26#import "platformMac/macVolume.h" 27#import "platform/platformVolume.h" 28#import "console/console.h" 29 30struct MacFileSystemChangeNotifier::Event 31{ 32 FSEventStreamRef mStream; 33 Torque::Path mDir; 34 bool mHasChanged; 35}; 36 37static void fsNotifyCallback( 38 ConstFSEventStreamRef stream, 39 void* callbackInfo, 40 size_t numEvents, 41 void* eventPaths, 42 const FSEventStreamEventFlags eventFlags[], 43 const FSEventStreamEventId eventIds[] ) 44{ 45 MacFileSystemChangeNotifier::Event* event = 46 reinterpret_cast< MacFileSystemChangeNotifier::Event* >( callbackInfo ); 47 48 // Defer handling this to internalProcessOnce() so we stay in 49 // line with how the volume system expects notifications to 50 // be reported. 51 52 event->mHasChanged = true; 53} 54 55//----------------------------------------------------------------------------- 56// Change notifications. 57//----------------------------------------------------------------------------- 58 59 60MacFileSystemChangeNotifier::MacFileSystemChangeNotifier( MacFileSystem* fs ) 61 : Parent( fs ) 62{ 63 VECTOR_SET_ASSOCIATION( mEvents ); 64} 65 66MacFileSystemChangeNotifier::~MacFileSystemChangeNotifier() 67{ 68 for( U32 i = 0, num = mEvents.size(); i < num; ++ i ) 69 { 70 FSEventStreamStop( mEvents[ i ]->mStream ); 71 FSEventStreamInvalidate( mEvents[ i ]->mStream ); 72 FSEventStreamRelease( mEvents[ i ]->mStream ); 73 74 SAFE_DELETE( mEvents[ i ] ); 75 } 76} 77 78void MacFileSystemChangeNotifier::internalProcessOnce() 79{ 80 for( U32 i = 0; i < mEvents.size(); ++ i ) 81 if( mEvents[ i ]->mHasChanged ) 82 { 83 // Signal the change. 84 85 #ifdef DEBUG_SPEW 86 Platform::outputDebugString( "[MacFileSystemChangeNotifier] Directory %i changed: '%s'", 87 i + 1, mEvents[ i ]->mDir.getFullPath().c_str() ); 88 #endif 89 90 internalNotifyDirChanged( mEvents[ i ]->mDir ); 91 mEvents[i ]->mHasChanged = false; 92 } 93} 94 95bool MacFileSystemChangeNotifier::internalAddNotification( const Torque::Path& dir ) 96{ 97 // Map the path. 98 99 Torque::Path fullFSPath = mFS->mapTo( dir ); 100 String osPath = PathToOS( fullFSPath ); 101 102 // Create event stream. 103 104 Event* event = new Event; 105 106 CFStringRef path = CFStringCreateWithCharacters( NULL, osPath.utf16(), osPath.numChars() ); 107 CFArrayRef paths = CFArrayCreate( NULL, ( const void** ) &path, 1, NULL ); 108 109 FSEventStreamRef stream; 110 CFAbsoluteTime latency = 3.f; 111 112 FSEventStreamContext context; 113 dMemset( &context, 0, sizeof( context ) ); 114 context.info = event; 115 116 stream = FSEventStreamCreate( 117 NULL, 118 &fsNotifyCallback, 119 &context, 120 paths, 121 kFSEventStreamEventIdSinceNow, 122 latency, 123 kFSEventStreamCreateFlagNone 124 ); 125 126 event->mStream = stream; 127 event->mDir = dir; 128 event->mHasChanged = false; 129 130 mEvents.push_back( event ); 131 132 // Put it in the run loop and start the stream. 133 134 FSEventStreamScheduleWithRunLoop( stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode ); 135 FSEventStreamStart( stream ); 136 137 CFRelease( path ); 138 CFRelease( paths ); 139 140 #ifdef DEBUG_SPEW 141 Platform::outputDebugString( "[MacFileSystemChangeNotifier] Added change notification %i to '%s' (full path: %s)", 142 mEvents.size(), dir.getFullPath().c_str(), osPath.c_str() ); 143 #endif 144 145 return true; 146} 147 148bool MacFileSystemChangeNotifier::internalRemoveNotification( const Torque::Path& dir ) 149{ 150 for( U32 i = 0, num = mEvents.size(); i < num; ++ i ) 151 if( mEvents[ i ]->mDir == dir ) 152 { 153 #ifdef DEBUG_SPEW 154 Platform::outputDebugString( "[MacFileSystemChangeNotifier] Removing change notification %i from '%s'", 155 i + 1, dir.getFullPath().c_str() ); 156 #endif 157 158 FSEventStreamStop( mEvents[ i ]->mStream ); 159 FSEventStreamInvalidate( mEvents[ i ]->mStream ); 160 FSEventStreamRelease( mEvents[ i ]->mStream ); 161 162 SAFE_DELETE( mEvents[ i ] ); 163 164 mEvents.erase( i ); 165 166 return true; 167 } 168 169 return false; 170} 171 172//----------------------------------------------------------------------------- 173// Platform API. 174//----------------------------------------------------------------------------- 175 176Torque::FS::FileSystemRef Platform::FS::createNativeFS( const String &volume ) 177{ 178 return new MacFileSystem( volume ); 179} 180 181bool Torque::FS::VerifyWriteAccess(const Torque::Path &path) 182{ 183 return true; 184} 185