From a4fc7eaede8b2109137d0d2dc1dcec04ff6e0178 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Sun, 5 Apr 2009 17:32:37 +0200 Subject: [PATCH] Vim talks only to app controller - dialog support not implemented yet - live resizing not supported --- src/MacVim/MMAppController.h | 2 ++ src/MacVim/MMAppController.m | 55 +++++++++++++++++++++++++++++++++++++++----- src/MacVim/MMBackend.h | 3 ++- src/MacVim/MMBackend.m | 23 +++++++++--------- src/MacVim/MMVimController.h | 6 ++++- src/MacVim/MMVimController.m | 12 +++++++++- src/MacVim/MacVim.h | 9 +++++--- 7 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/MacVim/MMAppController.h b/src/MacVim/MMAppController.h index 10a9e238..a0c1a48f 100644 --- a/src/MacVim/MMAppController.h +++ b/src/MacVim/MMAppController.h @@ -30,6 +30,8 @@ BOOL shouldActivateWhenNextWindowOpens; int numChildProcesses; + NSMutableDictionary *inputQueues; + #if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4) FSEventStreamRef fsEventStream; #endif diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 114eb2d3..1d58140c 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -125,6 +125,7 @@ typedef struct - (void)loadDefaultFont; - (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args; - (void)reapChildProcesses:(id)sender; +- (void)processInputQueues:(id)sender; #ifdef MM_ENABLE_PLUGINS - (void)removePlugInMenu; @@ -208,6 +209,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, cachedVimControllers = [NSMutableArray new]; preloadPid = -1; pidArguments = [NSMutableDictionary new]; + inputQueues = [NSMutableDictionary new]; #ifdef MM_ENABLE_PLUGINS NSString *plugInTitle = NSLocalizedString(@"Plug-In", @@ -249,6 +251,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, //NSLog(@"MMAppController dealloc"); [connection release]; connection = nil; + [inputQueues release]; inputQueues = nil; [pidArguments release]; pidArguments = nil; [vimControllers release]; vimControllers = nil; [cachedVimControllers release]; cachedVimControllers = nil; @@ -1093,9 +1096,8 @@ fsEventCallback(ConstFSEventStreamRef streamRef, } } -- (byref id ) - connectBackend:(byref in id )backend - pid:(int)pid +- (unsigned)connectBackend:(byref in id )backend + pid:(int)pid { //NSLog(@"Connect backend (pid=%d)", pid); NSNumber *pidKey = [NSNumber numberWithInt:pid]; @@ -1116,7 +1118,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, [cachedVimControllers addObject:vc]; [self scheduleVimControllerPreloadAfterDelay:1]; - return vc; + return [vc identifier]; } [vimControllers addObject:vc]; @@ -1136,7 +1138,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, if (args) [pidArguments removeObjectForKey:pidKey]; - return vc; + return [vc identifier]; } @catch (NSException *e) { @@ -1148,7 +1150,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, [pidArguments removeObjectForKey:pidKey]; } - return nil; + return 0; } - (NSArray *)serverList @@ -1165,6 +1167,26 @@ fsEventCallback(ConstFSEventStreamRef streamRef, return array; } +- (oneway void)processInput:(in bycopy NSArray *)queue + forIdentifier:(unsigned)identifier +{ + if (!queue) + return; + + NSNumber *key = [NSNumber numberWithUnsignedInt:identifier]; + NSArray *q = [inputQueues objectForKey:key]; + if (q) { + q = [q arrayByAddingObjectsFromArray:queue]; + [inputQueues setObject:q forKey:key]; + } else { + [inputQueues setObject:queue forKey:key]; + } + + [self performSelector:@selector(processInputQueues:) + withObject:nil + afterDelay:0]; +} + - (MMVimController *)keyVimController { NSWindow *keyWindow = [NSApp keyWindow]; @@ -2115,4 +2137,25 @@ fsEventCallback(ConstFSEventStreamRef streamRef, } } +- (void)processInputQueues:(id)sender +{ + MMVimController *vc; + NSEnumerator *e = [vimControllers objectEnumerator]; + while ((vc = [e nextObject])) { + NSNumber *key = [NSNumber numberWithUnsignedInt:[vc identifier]]; + NSArray *q = [inputQueues objectForKey:key]; + if (q) { + // Remove queue from the dictionary before processing it because + // more input may arrive during processing of the queue (we have to + // retain/release the queue otherwise it will be deallocated when + // we remove it from the dictionary). + [q retain]; + [inputQueues removeObjectForKey:key]; + + [vc processInputQueue:q]; + [q release]; + } + } +} + @end // MMAppController (Private) diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 9cff7a0f..2a202288 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -21,7 +21,8 @@ NSMutableArray *inputQueue; NSMutableData *drawData; NSConnection *connection; - id frontendProxy; + id appProxy; + unsigned identifier; NSDictionary *colorDict; NSDictionary *sysColorDict; NSDictionary *actionDict; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 5806e09b..8bafaf5a 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -178,7 +178,6 @@ extern GuiFont gui_mch_retain_font(GuiFont font); [inputQueue release]; inputQueue = nil; [outputQueue release]; outputQueue = nil; [drawData release]; drawData = nil; - [frontendProxy release]; frontendProxy = nil; [connection release]; connection = nil; [actionDict release]; actionDict = nil; [sysColorDict release]; sysColorDict = nil; @@ -334,17 +333,14 @@ extern GuiFont gui_mch_retain_font(GuiFont font); selector:@selector(connectionDidDie:) name:NSConnectionDidDieNotification object:connection]; - id proxy = [connection rootProxy]; - [proxy setProtocolForProxy:@protocol(MMAppProtocol)]; + appProxy = [[connection rootProxy] retain]; + [appProxy setProtocolForProxy:@protocol(MMAppProtocol)]; int pid = [[NSProcessInfo processInfo] processIdentifier]; - frontendProxy = [proxy connectBackend:self pid:pid]; - if (frontendProxy) { - [frontendProxy retain]; - [frontendProxy setProtocolForProxy:@protocol(MMFrontendProtocol)]; + identifier = [appProxy connectBackend:self pid:pid]; + if (identifier != 0) ok = YES; - } } @catch (NSException *e) { NSLog(@"Exception caught when trying to connect backend: \"%@\"", e); @@ -506,7 +502,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); [self insertVimStateMessage]; @try { - [frontendProxy processCommandQueue:outputQueue]; + [appProxy processInput:outputQueue forIdentifier:identifier]; } @catch (NSException *e) { NSLog(@"Exception caught when processing command queue: \"%@\"", e); @@ -575,7 +571,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); // Flush the entire queue in case a VimLeave autocommand added // something to the queue. [self queueMessage:CloseWindowMsgID data:nil]; - [frontendProxy processCommandQueue:outputQueue]; + [appProxy processInput:outputQueue forIdentifier:identifier]; } @catch (NSException *e) { NSLog(@"Exception caught when sending CloseWindowMsgID: \"%@\"", e); @@ -695,6 +691,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); { char_u *s = NULL; +#if 0 @try { [frontendProxy showSavePanelWithAttributes:attr]; @@ -708,7 +705,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); @catch (NSException *e) { NSLog(@"Exception caught when showing save panel: \"%@\"", e); } - +#endif return (char *)s; } @@ -734,6 +731,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); { int retval = 0; +#if 0 @try { [frontendProxy presentDialogWithAttributes:attr]; @@ -760,6 +758,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); @catch (NSException *e) { NSLog(@"Exception caught while showing alert dialog: \"%@\"", e); } +#endif return retval; } @@ -1453,7 +1452,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); if (waitForAck) { // Never received a connection acknowledgement, so die. [[NSNotificationCenter defaultCenter] removeObserver:self]; - [frontendProxy release]; frontendProxy = nil; + [appProxy release]; appProxy = nil; // NOTE: We intentionally do not call mch_exit() since this in turn // will lead to -[MMBackend exit] getting called which we want to diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index e8754d50..e5c2c43f 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -20,7 +20,7 @@ -@interface MMVimController : NSObject +@interface MMVimController : NSObject // { BOOL isInitialized; MMWindowController *windowController; @@ -40,9 +40,12 @@ #endif BOOL isPreloading; NSDate *creationDate; + + unsigned identifier; } - (id)initWithBackend:(id)backend pid:(int)processIdentifier; +- (unsigned)identifier; - (id)backendProxy; - (int)pid; - (void)setServerName:(NSString *)name; @@ -66,6 +69,7 @@ - (void)addVimInput:(NSString *)string; - (NSString *)evaluateVimExpression:(NSString *)expr; - (id)evaluateVimExpressionCocoa:(NSString *)expr errorString:(NSString **)errstr; +- (void)processInputQueue:(NSArray *)queue; #ifdef MM_ENABLE_PLUGINS - (MMPlugInInstanceMediator *)instanceMediator; #endif diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 7fad01a9..62fe0e1f 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -55,6 +55,8 @@ static int MMReceiveQueueCap = 100; static BOOL isUnsafeMessage(int msgid); +static unsigned identifierCounter = 1; + @interface MMAlert : NSAlert { NSTextField *textField; @@ -107,6 +109,7 @@ static BOOL isUnsafeMessage(int msgid); if (!(self = [super init])) return nil; + identifier = identifierCounter++; windowController = [[MMWindowController alloc] initWithVimController:self]; backendProxy = [backend retain]; @@ -183,6 +186,11 @@ static BOOL isUnsafeMessage(int msgid); [super dealloc]; } +- (unsigned)identifier +{ + return identifier; +} + - (MMWindowController *)windowController { return windowController; @@ -431,6 +439,7 @@ static BOOL isUnsafeMessage(int msgid); [windowController cleanup]; } +#if 0 - (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr { if (!isInitialized) return; @@ -565,8 +574,9 @@ static BOOL isUnsafeMessage(int msgid); [alert release]; } +#endif -- (oneway void)processCommandQueue:(in bycopy NSArray *)queue +- (void)processInputQueue:(NSArray *)queue { if (!isInitialized) return; diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index de68bf14..c2d10c59 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -42,6 +42,7 @@ - (oneway void)acknowledgeConnection; @end +#if 0 // // This is the protocol MMVimController implements. // @@ -55,6 +56,7 @@ - (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr; - (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr; @end +#endif // @@ -63,10 +65,11 @@ // It handles connections between MacVim and Vim. // @protocol MMAppProtocol -- (byref id ) - connectBackend:(byref in id )backend - pid:(int)pid; +- (unsigned)connectBackend:(byref in id )backend + pid:(int)pid; - (NSArray *)serverList; +- (oneway void)processInput:(in bycopy NSArray *)queue + forIdentifier:(unsigned)identifier; @end -- 2.11.4.GIT