macCarbVolume.cpp 5.7 KB

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