From 6b4337558dc077718eb5a0d7bb634752eccd83b5 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Tue, 1 Dec 2015 22:50:53 -0500 Subject: [PATCH 1/1] Rewrite variable and property loading. This removes the -[VariableNode dynamicChildren] hack and replaces it with controller-driven loading. --- English.lproj/Debugger.xib | 2 +- Source/DebuggerBackEnd.h | 11 +++--- Source/DebuggerBackEnd.m | 68 +++++++++++++++++++++++-------------- Source/DebuggerController.h | 2 -- Source/DebuggerController.m | 16 ++------- Source/VariableNode.h | 3 -- Source/VariableNode.m | 16 +++------ 7 files changed, 56 insertions(+), 62 deletions(-) diff --git a/English.lproj/Debugger.xib b/English.lproj/Debugger.xib index 6175676..a8174ca 100644 --- a/English.lproj/Debugger.xib +++ b/English.lproj/Debugger.xib @@ -401,7 +401,7 @@ - + value name diff --git a/Source/DebuggerBackEnd.h b/Source/DebuggerBackEnd.h index c000a14..08bdf0b 100644 --- a/Source/DebuggerBackEnd.h +++ b/Source/DebuggerBackEnd.h @@ -67,15 +67,14 @@ // Evaluates a given string in the current execution context. - (void)evalScript:(NSString*)str callback:(void (^)(NSString*))callback; -// Gets a property by name from the debugger engine. Properties must be -// retrieved at a certain stack depth. -- (void)getChildrenOfProperty:(VariableNode*)property - atDepth:(NSInteger)depth - callback:(void (^)(NSArray*))callback; - // Takes a partially loaded stack frame and fetches the rest of the information. - (void)loadStackFrame:(StackFrame*)frame; +// Ensures that a variable node's immediate children are loaded, and fetches +// any that are not. This is done within the scope of the given stack frame. +- (void)loadVariableNode:(VariableNode*)variable + forStackFrame:(StackFrame*)frame; + @end // Delegate //////////////////////////////////////////////////////////////////// diff --git a/Source/DebuggerBackEnd.m b/Source/DebuggerBackEnd.m index 435d858..f9f64cd 100644 --- a/Source/DebuggerBackEnd.m +++ b/Source/DebuggerBackEnd.m @@ -149,32 +149,6 @@ self.status = @"Stopped"; } -/** - * Tells the debugger engine to get a specifc property. This also takes in the NSXMLElement - * that requested it so that the child can be attached. - */ -- (void)getChildrenOfProperty:(VariableNode*)property - atDepth:(NSInteger)depth - callback:(void (^)(NSArray*))callback { - ProtocolClientMessageHandler handler = ^(NSXMLDocument* message) { - /* - - - - - - */ - - // Detach all the children so we can insert them into another document. - NSXMLElement* parent = (NSXMLElement*)[[message rootElement] childAtIndex:0]; - NSArray* children = [parent children]; - [parent setChildren:nil]; - - callback(children); - }; - [_client sendCommandWithFormat:@"property_get -d %d -n %@" handler:handler, depth, [property fullName]]; -} - - (void)loadStackFrame:(StackFrame*)frame { if (frame.loaded) return; @@ -199,6 +173,48 @@ frame.loaded = YES; } +- (void)loadVariableNode:(VariableNode*)variable + forStackFrame:(StackFrame*)frame { + if (variable.children.count == variable.childCount) + return; + + [self loadVariableNode:variable forStackFrame:frame dataPage:0 loadedData:@[]]; +} + +- (void)loadVariableNode:(VariableNode*)variable + forStackFrame:(StackFrame*)frame + dataPage:(unsigned int)dataPage + loadedData:(NSArray*)loadedData { + ProtocolClientMessageHandler handler = ^(NSXMLDocument* message) { + /* + + + + + + */ + + // Detach all the children so we can insert them into another document. + NSXMLElement* parent = (NSXMLElement*)[[message rootElement] childAtIndex:0]; + NSArray* children = [parent children]; + [parent setChildren:nil]; + + // Check to see if there are more children to load. + NSArray* newLoadedData = [loadedData arrayByAddingObjectsFromArray:children]; + + unsigned int totalChildren = [[[parent attributeForName:@"numchildren"] stringValue] integerValue]; + if ([newLoadedData count] < totalChildren) { + [self loadVariableNode:variable + forStackFrame:frame + dataPage:dataPage + 1 + loadedData:newLoadedData]; + } else { + [variable setChildrenFromXMLChildren:newLoadedData]; + } + }; + [_client sendCommandWithFormat:@"property_get -d %d -n %@ -p %u" handler:handler, frame.index, variable.fullName, dataPage]; +} + // Breakpoint Management /////////////////////////////////////////////////////// #pragma mark Breakpoints diff --git a/Source/DebuggerController.h b/Source/DebuggerController.h index cb8f036..352d548 100644 --- a/Source/DebuggerController.h +++ b/Source/DebuggerController.h @@ -63,6 +63,4 @@ - (IBAction)stepOver:(id)sender; - (IBAction)stop:(id)sender; -- (void)fetchChildProperties:(VariableNode*)node; - @end diff --git a/Source/DebuggerController.m b/Source/DebuggerController.m index 9de5466..c97dcc1 100644 --- a/Source/DebuggerController.m +++ b/Source/DebuggerController.m @@ -243,19 +243,6 @@ [connection stop]; } -- (void)fetchChildProperties:(VariableNode*)node -{ - NSArray* selection = [stackArrayController selectedObjects]; - if (![selection count]) - return; - assert([selection count] == 1); - NSInteger depth = [[selection objectAtIndex:0] index]; - [connection getChildrenOfProperty:node atDepth:depth callback:^(NSArray* properties) { - [node setChildrenFromXMLChildren:properties]; - [variablesTreeController rearrangeObjects]; - }]; -} - /** * NSTableView delegate method that informs the controller that the stack selection did change and that * we should update the source viewer @@ -283,6 +270,9 @@ { NSTreeNode* node = [[notif userInfo] objectForKey:@"NSObject"]; [expandedVariables addObject:[[node representedObject] fullName]]; + + [connection loadVariableNode:[node representedObject] + forStackFrame:[[stackArrayController selectedObjects] lastObject]]; } /** diff --git a/Source/VariableNode.h b/Source/VariableNode.h index 7752128..c9d7f4b 100644 --- a/Source/VariableNode.h +++ b/Source/VariableNode.h @@ -49,9 +49,6 @@ // the children on a node from the list of children from the XML response. - (void)setChildrenFromXMLChildren:(NSArray*)children; -// Returns the children and requests any unloaded ones. -- (NSArray*)dynamicChildren; - // Whether or not this is a leaf node (i.e. does not have child properties). - (BOOL)isLeaf; diff --git a/Source/VariableNode.m b/Source/VariableNode.m index 5e38c07..6775747 100644 --- a/Source/VariableNode.m +++ b/Source/VariableNode.m @@ -16,7 +16,6 @@ #import "VariableNode.h" -#import "AppDelegate.h" #include "NSXMLElementAdditions.h" // Private Properties ////////////////////////////////////////////////////////// @@ -78,6 +77,10 @@ - (void)setChildrenFromXMLChildren:(NSArray*)children { + [self willChangeValueForKey:@"children"]; + + [children_ removeAllObjects]; + for (NSXMLNode* child in children) { // Other child nodes may be the string value. if ([child isKindOfClass:[NSXMLElement class]]) { @@ -89,17 +92,8 @@ [node release]; } } -} -- (NSArray*)dynamicChildren -{ - NSArray* children = self.children; - if (![self isLeaf] && (NSInteger)[children count] < self.childCount) { - // If this node has children but they haven't been loaded from the backend, - // request them asynchronously. - [[AppDelegate instance].debugger fetchChildProperties:self]; - } - return children; + [self didChangeValueForKey:@"children"]; } - (BOOL)isLeaf -- 2.22.5