Skip to content

Commit

Permalink
fallback into date mode in 10.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Antoine Mercadal committed Nov 4, 2011
1 parent 791a1eb commit 7a9fded
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 14 deletions.
8 changes: 8 additions & 0 deletions Tools/xcodecapp-cocoa/AppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ @implementation AppController
*/
- (void)awakeFromNib
{
#if (ACTIVATE_DATE_BASED_MODE == 1)
NSLog(@"XCC is working using the 10.6 mode (dirty)");
#else
NSLog(@"XCC is working using the 10.7+ mode (clean)");
#endif

if (!growlDelegateRef)
growlDelegateRef = [[[PRHEmptyGrowlDelegate alloc] init] autorelease];

Expand Down Expand Up @@ -219,6 +225,7 @@ - (IBAction)openXCode:(id)aSender
- (void)updateErrorTable
{
[errorsTable reloadData];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[errorsPanel orderFront:self];
}

Expand All @@ -241,6 +248,7 @@ - (IBAction)openHelp:(id)aSender
[helpTextView readRTFDFromFile:[[NSBundle mainBundle] pathForResource:@"help" ofType:@"rtfd"]];

[helpWindow center];
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[helpWindow makeKeyAndOrderFront:aSender];
}

Expand Down
2 changes: 2 additions & 0 deletions Tools/xcodecapp-cocoa/FSEventCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#define xcodecapp_cocoa_FSEventCallback_h

#import "TNXCodeCapp.h"
#import <Cocoa/Cocoa.h>
#import "defines.h"

void fsevents_callback(ConstFSEventStreamRef, void*, size_t, void*, const FSEventStreamEventFlags*, const FSEventStreamEventId*);

Expand Down
67 changes: 54 additions & 13 deletions Tools/xcodecapp-cocoa/FSEventCallback.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@

#import "FSEventCallback.h"

#if (ACTIVATE_DATE_BASED_MODE == 0)

/*!
This is the FSEvent callback
This is the FSEvent callback for 10.7
*/
void fsevents_callback(ConstFSEventStreamRef streamRef,
void *userData,
Expand All @@ -34,12 +36,6 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,
for(i = 0; i < numEvents; i++)
{
NSString *path = [(NSArray *)eventPaths objectAtIndex:i];

// /!\ IMPORTANT /!\
//
// This is a test. Maybe these values where present as
// private API in 10.6, and maybe not
// If not, we will drop support for 10.6

// kFSEventStreamEventFlagItemIsFile = 0x00010000
if (!(eventFlags[i] & 0x00010000)
Expand All @@ -49,14 +45,59 @@ void fsevents_callback(ConstFSEventStreamRef streamRef,

// kFSEventStreamEventFlagItemRemoved = 0x00000200
if (eventFlags[i] & 0x00000200)
{
[xcc handleFileRemoval:path];
}
else
{
NSLog(@"this file has been modified or created");
[xcc handleFileModification:path notify:YES];
}

[xcc updateLastEventId:eventIds[i]];
}
}
}


#else

/*!
This is the FSEvent callback for 10.6
*/
void fsevents_callback(ConstFSEventStreamRef streamRef,
void *userData,
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
TNXCodeCapp *xcc = (TNXCodeCapp *)userData;
size_t i;

for(i = 0; i < numEvents; i++)
{
NSString *path = [(NSArray *)eventPaths objectAtIndex:i];

// TEST on 10.7
// BOOL isDir;
// [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
// if (!isDir)
// continue;
// END TEST

NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];

for(NSString *currentPath in subpaths)
{
[xcc updateLastModificationDateForPath:currentPath];

currentPath = [NSString stringWithFormat:@"%@/%@", path, currentPath];

NSDate *lastModifiedDate = [xcc lastModificationDateForPath:currentPath];
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:currentPath error:nil];
NSDate *fileModDate = [fileAttributes objectForKey:NSFileModificationDate];

if([fileModDate compare:lastModifiedDate] == NSOrderedDescending)
[xcc handleFileModification:currentPath notify:YES];

[xcc updateLastEventId:eventIds[i]];
}
}
}

#endif
16 changes: 16 additions & 0 deletions Tools/xcodecapp-cocoa/TNXCodeCapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#import <Foundation/Foundation.h>
#import "PRHEmptyGrowlDelegate.h"
#import "FSEventCallback.h"
#import "defines.h"

extern NSString * const XCCDidPopulateProjectNotification;
extern NSString * const XCCConversionStartNotification;
Expand All @@ -45,6 +46,11 @@ extern NSString * const XCCListeningStartNotification;
NSURL *XCodeSupportProjectSources;
PRHEmptyGrowlDelegate *growlDelegateRef;
NSObject *delegate;
NSDate *appStartedTimestamp;

#if (ACTIVATE_DATE_BASED_MODE == 1)
NSMutableDictionary *pathModificationDates;
#endif
}

@property (retain) NSObject* delegate;
Expand All @@ -69,5 +75,15 @@ extern NSString * const XCCListeningStartNotification;
- (void)clear;
- (void)start;

@end


#if (ACTIVATE_DATE_BASED_MODE == 1)
@interface TNXCodeCapp (SnowLeopard)

- (void)updateLastModificationDateForPath:(NSString *)path;
- (NSDate*)lastModificationDateForPath:(NSString *)path;

@end
#endif

54 changes: 53 additions & 1 deletion Tools/xcodecapp-cocoa/TNXCodeCapp.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ - (id)init
ignoredFilePaths = [NSMutableArray new];
parserPath = [[NSBundle mainBundle] pathForResource:@"parser" ofType:@"j"];
lastEventId = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastEventId"];
appStartedTimestamp = [NSDate date];

if([fm fileExistsAtPath:[@"~/.bash_profile" stringByExpandingTildeInPath]])
profilePath = [@"source ~/.bash_profile" stringByExpandingTildeInPath];
Expand Down Expand Up @@ -101,9 +102,11 @@ - (void)initializeEventStreamWithPath:(NSString*)aPath
NSTimeInterval latency = 2.0;

free(stream);

NSLog(@"Initializing the FSEventStream at file level (clean)");
stream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (CFArrayRef) pathsToWatch,
[lastEventId unsignedLongLongValue], (CFAbsoluteTime) latency, kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer | 0x00000010 );

FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);
}
Expand Down Expand Up @@ -506,3 +509,52 @@ - (void)listenProjectAtPath:(NSString *)path
}

@end


#if (ACTIVATE_DATE_BASED_MODE == 1)
@implementation TNXCodeCapp (SnowLeopard)

- (void)initializeEventStreamWithPath:(NSString*)aPath
{
NSArray *pathsToWatch = [NSArray arrayWithObject:aPath];
void *appPointer = (void *)self;
FSEventStreamContext context = {0, appPointer, NULL, NULL, NULL};
NSTimeInterval latency = 2.0;
free(stream);
NSLog(@"Initializing the FSEventStream at folder level (dirty)");
stream = FSEventStreamCreate(NULL, &fsevents_callback, &context, (CFArrayRef) pathsToWatch,
[lastEventId unsignedLongLongValue], (CFAbsoluteTime) latency, kFSEventStreamCreateFlagUseCFTypes);

FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
FSEventStreamStart(stream);
}

- (void)updateLastModificationDateForPath:(NSString *)path
{
if (!pathModificationDates)
{
pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy];
if (!pathModificationDates)
pathModificationDates = [NSMutableDictionary new];
}

[pathModificationDates setObject:[NSDate date] forKey:path];
[[NSUserDefaults standardUserDefaults] setObject:pathModificationDates forKey:@"pathModificationDates"];
}

- (NSDate*)lastModificationDateForPath:(NSString *)path
{
if (!pathModificationDates)
{
pathModificationDates = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"pathModificationDates"] mutableCopy];
if (!pathModificationDates)
pathModificationDates = [NSMutableDictionary new];
}

if([pathModificationDates valueForKey:path] != nil)
return [pathModificationDates valueForKey:path];
else
return appStartedTimestamp;
}
@end
#endif
18 changes: 18 additions & 0 deletions Tools/xcodecapp-cocoa/defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// defines.h
// xcodecapp-cocoa
//
// Created by Antoine Mercadal on 04/11/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#ifndef xcodecapp_cocoa_defines_h
#define xcodecapp_cocoa_defines_h

#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
#define ACTIVATE_DATE_BASED_MODE 0
#else
#define ACTIVATE_DATE_BASED_MODE 1
#endif

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
027FE4BC1462F7EB00B1AB92 /* FSEventCallback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSEventCallback.m; sourceTree = "<group>"; };
02998CEA1369BF7D006C73DB /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = "<group>"; };
02998CF61369C339006C73DB /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Growl.framework; sourceTree = "<group>"; };
02D00BD514635F9B0071080E /* defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = defines.h; sourceTree = "<group>"; };
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
Expand Down Expand Up @@ -99,6 +100,7 @@
027FE49C1462D74C00B1AB92 /* TNXCodeCapp.m */,
027FE4BB1462F7D600B1AB92 /* FSEventCallback.h */,
027FE4BC1462F7EB00B1AB92 /* FSEventCallback.m */,
02D00BD514635F9B0071080E /* defines.h */,
);
name = Classes;
sourceTree = "<group>";
Expand Down

0 comments on commit 7a9fded

Please sign in to comment.