Fix to ignore storyboard instantiation with blank id, refactoring on another branch

This commit is contained in:
Gregory John Casamento 2025-05-12 19:22:08 -04:00
parent 7850f8e61b
commit e97aee7bca

View file

@ -105,13 +105,13 @@ static NSStoryboard *__mainStoryboard = nil;
// Private instance methods... // Private instance methods...
- (id) initWithName: (NSStoryboardName)name - (id) initWithName: (NSStoryboardName)name
bundle: (NSBundle *)bundle bundle: (NSBundle *)bundle
{ {
self = [super init]; self = [super init];
if (self != nil) if (self != nil)
{ {
NSString *path = [bundle pathForResource: name NSString *path = [bundle pathForResource: name
ofType: @"storyboard"]; ofType: @"storyboard"];
NSData *data = [NSData dataWithContentsOfFile: path]; NSData *data = [NSData dataWithContentsOfFile: path];
_transform = [[GSStoryboardTransform alloc] initWithData: data]; _transform = [[GSStoryboardTransform alloc] initWithData: data];
} }
@ -133,10 +133,10 @@ static NSStoryboard *__mainStoryboard = nil;
} }
+ (instancetype) storyboardWithName: (NSStoryboardName)name + (instancetype) storyboardWithName: (NSStoryboardName)name
bundle: (NSBundle *)bundle bundle: (NSBundle *)bundle
{ {
return AUTORELEASE([[NSStoryboard alloc] initWithName: name return AUTORELEASE([[NSStoryboard alloc] initWithName: name
bundle: bundle]); bundle: bundle]);
} }
// Instance methods... // Instance methods...
@ -159,112 +159,112 @@ static NSStoryboard *__mainStoryboard = nil;
- (id) instantiateInitialControllerWithCreator: (NSStoryboardControllerCreator)block - (id) instantiateInitialControllerWithCreator: (NSStoryboardControllerCreator)block
{ {
return [self instantiateControllerWithIdentifier: [_transform initialViewControllerId] return [self instantiateControllerWithIdentifier: [_transform initialViewControllerId]
creator: block]; creator: block];
} }
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier - (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
{ {
if (identifier != nil) return [self instantiateControllerWithIdentifier: identifier
{
return [self instantiateControllerWithIdentifier: identifier
creator: nil]; creator: nil];
}
return nil;
} }
- (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier - (id) instantiateControllerWithIdentifier: (NSStoryboardSceneIdentifier)identifier
creator: (NSStoryboardControllerCreator)block creator: (NSStoryboardControllerCreator)block
{ {
id result = nil; id result = nil;
NSMutableArray *topLevelObjects = [NSMutableArray arrayWithCapacity: 5];
NSDictionary *table = [NSDictionary dictionaryWithObjectsAndKeys: topLevelObjects,
NSNibTopLevelObjects,
NSApp,
NSNibOwner,
nil];
GSModelLoader *loader = [GSModelLoaderFactory modelLoaderForFileType: @"xib"];
BOOL success = [loader loadModelData: [_transform dataForIdentifier: identifier]
externalNameTable: table
withZone: [self zone]];
if (success) if (identifier != nil)
{ {
NSMutableArray *seguesToPerform = [NSMutableArray array]; NSMutableArray *topLevelObjects = [NSMutableArray arrayWithCapacity: 5];
NSMapTable *segueMap = [_transform segueMapForIdentifier: identifier]; NSDictionary *table = [NSDictionary dictionaryWithObjectsAndKeys: topLevelObjects,
NSWindowController *wc = nil; NSNibTopLevelObjects,
NSViewController *vc = nil; NSApp,
NSWindow *w = nil; NSNibOwner,
nil];
GSModelLoader *loader = [GSModelLoaderFactory modelLoaderForFileType: @"xib"];
BOOL success = [loader loadModelData: [_transform dataForIdentifier: identifier]
externalNameTable: table
withZone: [self zone]];
FOR_IN(id, o, topLevelObjects) if (success)
if ([o isKindOfClass: [NSWindowController class]]) {
{ NSMutableArray *seguesToPerform = [NSMutableArray array];
wc = (NSWindowController *)o; NSMapTable *segueMap = [_transform segueMapForIdentifier: identifier];
[wc _setSegueMap: segueMap]; NSWindowController *wc = nil;
[wc _setTopLevelObjects: topLevelObjects]; NSViewController *vc = nil;
[wc _setStoryboard: self]; NSWindow *w = nil;
[wc _setOwner: NSApp];
result = o;
}
else if ([o isKindOfClass: [NSViewController class]])
{
vc = (NSViewController *)o;
[vc _setSegueMap: segueMap];
[vc _setTopLevelObjects: topLevelObjects];
[vc _setStoryboard: self];
result = o;
}
else if ([o isKindOfClass: [NSWindow class]])
{
w = (NSWindow *)o;
}
else if ([o isKindOfClass: [NSControllerPlaceholder class]])
{
NSControllerPlaceholder *ph = (NSControllerPlaceholder *)o;
result = [ph instantiate];
}
END_FOR_IN(topLevelObjects);
// Process action proxies after so we know we have the windowController... FOR_IN(id, o, topLevelObjects)
FOR_IN(id, o, topLevelObjects) if ([o isKindOfClass: [NSWindowController class]])
if ([o isKindOfClass: [NSStoryboardSeguePerformAction class]]) {
{ wc = (NSWindowController *)o;
NSStoryboardSeguePerformAction *ssa = (NSStoryboardSeguePerformAction *)o; [wc _setSegueMap: segueMap];
NSMapTable *mapTable = [_transform segueMapForIdentifier: identifier]; [wc _setTopLevelObjects: topLevelObjects];
NSStoryboardSegue *ss = [mapTable objectForKey: [ssa identifier]]; [wc _setStoryboard: self];
[wc _setOwner: NSApp];
result = o;
}
else if ([o isKindOfClass: [NSViewController class]])
{
vc = (NSViewController *)o;
[vc _setSegueMap: segueMap];
[vc _setTopLevelObjects: topLevelObjects];
[vc _setStoryboard: self];
result = o;
}
else if ([o isKindOfClass: [NSWindow class]])
{
w = (NSWindow *)o;
}
else if ([o isKindOfClass: [NSControllerPlaceholder class]])
{
NSControllerPlaceholder *ph = (NSControllerPlaceholder *)o;
result = [ph instantiate];
}
END_FOR_IN(topLevelObjects);
[ssa setSender: result]; // resolve controller here... // Process action proxies after so we know we have the windowController...
[ssa setStoryboardSegue: ss]; FOR_IN(id, o, topLevelObjects)
[ssa setStoryboard: self]; if ([o isKindOfClass: [NSStoryboardSeguePerformAction class]])
if ([[ssa kind] isEqualToString: @"relationship"]) // if it is a relationship, perform immediately {
{ NSStoryboardSeguePerformAction *ssa = (NSStoryboardSeguePerformAction *)o;
[seguesToPerform addObject: ssa]; NSMapTable *mapTable = [_transform segueMapForIdentifier: identifier];
} NSStoryboardSegue *ss = [mapTable objectForKey: [ssa identifier]];
}
END_FOR_IN(topLevelObjects);
// Depending on which kind of controller we have, do the correct thing.... [ssa setSender: result]; // resolve controller here...
if (w != nil && wc != nil) [ssa setStoryboardSegue: ss];
{ [ssa setStoryboard: self];
[wc setWindow: w]; if ([[ssa kind] isEqualToString: @"relationship"]) // if it is a relationship, perform immediately
} {
[seguesToPerform addObject: ssa];
}
}
END_FOR_IN(topLevelObjects);
// perform segues after all is initialized. // Depending on which kind of controller we have, do the correct thing....
FOR_IN(NSStoryboardSeguePerformAction*, ssa, seguesToPerform) if (w != nil && wc != nil)
[ssa doAction: result]; // this will, as far as I know, only happen with window controllers, to set content. {
END_FOR_IN(seguesToPerform); [wc setWindow: w];
} }
else
{ // perform segues after all is initialized.
[NSException raise: NSInternalInconsistencyException FOR_IN(NSStoryboardSeguePerformAction*, ssa, seguesToPerform)
format: @"Couldn't load controller scene identifier = %@", identifier]; [ssa doAction: result]; // this will, as far as I know, only happen with window controllers, to set content.
END_FOR_IN(seguesToPerform);
}
else
{
[NSException raise: NSInternalInconsistencyException
format: @"Couldn't load controller scene identifier = %@", identifier];
}
// Execute the block if it's set...
if (block != nil)
{
CALL_BLOCK(block, self);
}
} }
// Execute the block if it's set...
if (block != nil)
{
CALL_BLOCK(block, self);
}
return result; return result;
} }
@end @end