log window for mame stderr/stdout messages.

This commit is contained in:
Kelvin Sherlock 2020-08-29 18:45:25 -04:00
parent 03797486cc
commit 6a2b95b7f8
6 changed files with 251 additions and 29 deletions

View File

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B6004DEE24FB05D600D38596 /* LogWindowController.m */; };
B6004DF124FB05D600D38596 /* LogWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B6004DEF24FB05D600D38596 /* LogWindow.xib */; };
B60A6E1424EE0AE2004B7EEF /* FlippedView.m in Sources */ = {isa = PBXBuildFile; fileRef = B60A6E1324EE0AE2004B7EEF /* FlippedView.m */; };
B61099E724F5F231005CB652 /* SlotView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B61099E324F5F230005CB652 /* SlotView.xib */; };
B61099E824F5F231005CB652 /* MediaView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B61099E524F5F230005CB652 /* MediaView.xib */; };
@ -66,10 +68,12 @@
B6D6DE3B24FACF4F00661A5F /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = B6D6DE3A24FACF4F00661A5F /* Defaults.plist */; };
B6D6DE3E24FADF8B00661A5F /* LaunchWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B6D6DE3C24FADF8B00661A5F /* LaunchWindow.xib */; };
B6D6DE4124FADFAC00661A5F /* LaunchWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B6D6DE4024FADFAC00661A5F /* LaunchWindowController.m */; };
B6D6DE4524FAF00300661A5F /* ModelsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B6D6DE4324FAF00300661A5F /* ModelsView.xib */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
B6004DED24FB05D600D38596 /* LogWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogWindowController.h; sourceTree = "<group>"; };
B6004DEE24FB05D600D38596 /* LogWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LogWindowController.m; sourceTree = "<group>"; };
B6004DEF24FB05D600D38596 /* LogWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LogWindow.xib; sourceTree = "<group>"; };
B60A6E0B24ECE23F004B7EEF /* apple2gs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = apple2gs.plist; sourceTree = "<group>"; };
B60A6E1224EE0AE2004B7EEF /* FlippedView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FlippedView.h; sourceTree = "<group>"; };
B60A6E1324EE0AE2004B7EEF /* FlippedView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlippedView.m; sourceTree = "<group>"; };
@ -140,7 +144,6 @@
B6D6DE3D24FADF8B00661A5F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchWindow.xib; sourceTree = "<group>"; };
B6D6DE3F24FADFAC00661A5F /* LaunchWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LaunchWindowController.h; sourceTree = "<group>"; };
B6D6DE4024FADFAC00661A5F /* LaunchWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LaunchWindowController.m; sourceTree = "<group>"; };
B6D6DE4424FAF00300661A5F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ModelsView.xib; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -237,7 +240,6 @@
children = (
B6BA257E24E99BE9005FB8FF /* AppDelegate.h */,
B6BA257F24E99BE9005FB8FF /* AppDelegate.m */,
B6D6DE4324FAF00300661A5F /* ModelsView.xib */,
B6D6DE3F24FADFAC00661A5F /* LaunchWindowController.h */,
B6D6DE4024FADFAC00661A5F /* LaunchWindowController.m */,
B65593B024ECB61800722E0C /* SlotViewController.m */,
@ -248,6 +250,8 @@
B64E15A824EA1D5300E8AD3D /* MachineViewController.m */,
B60A6E1324EE0AE2004B7EEF /* FlippedView.m */,
B60A6E1224EE0AE2004B7EEF /* FlippedView.h */,
B6004DED24FB05D600D38596 /* LogWindowController.h */,
B6004DEE24FB05D600D38596 /* LogWindowController.m */,
B6BA258124E99BEB005FB8FF /* Assets.xcassets */,
B64E15AF24EA365E00E8AD3D /* Resources */,
B6BA258624E99BEB005FB8FF /* Info.plist */,
@ -264,6 +268,7 @@
children = (
B6BA258324E99BEB005FB8FF /* MainMenu.xib */,
B6D6DE3C24FADF8B00661A5F /* LaunchWindow.xib */,
B6004DEF24FB05D600D38596 /* LogWindow.xib */,
B6D6DE3724FAC8B500661A5F /* Preferences.xib */,
B61099E524F5F230005CB652 /* MediaView.xib */,
B61099E324F5F230005CB652 /* SlotView.xib */,
@ -336,6 +341,7 @@
B6109A3124F5F377005CB652 /* apple1.plist in Resources */,
B6109A3524F5F377005CB652 /* ace100.plist in Resources */,
B6109A3424F5F377005CB652 /* am64.plist in Resources */,
B6004DF124FB05D600D38596 /* LogWindow.xib in Resources */,
B6BA258224E99BEB005FB8FF /* Assets.xcassets in Resources */,
B6109A1724F5F377005CB652 /* apple2e.plist in Resources */,
B6109A3C24F5F377005CB652 /* am100.plist in Resources */,
@ -366,7 +372,6 @@
B6109A3B24F5F377005CB652 /* apple2gsr1.plist in Resources */,
B6D6DE3B24FACF4F00661A5F /* Defaults.plist in Resources */,
B6109A2224F5F377005CB652 /* models.plist in Resources */,
B6D6DE4524FAF00300661A5F /* ModelsView.xib in Resources */,
B6109A4024F5F377005CB652 /* craft2p.plist in Resources */,
B6109A1B24F5F377005CB652 /* uniap2pt.plist in Resources */,
B6109A3724F5F377005CB652 /* las128e2.plist in Resources */,
@ -397,6 +402,7 @@
B64979C224EF6703008ABD20 /* MediaViewController.m in Sources */,
B60A6E1424EE0AE2004B7EEF /* FlippedView.m in Sources */,
B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */,
B6004DF024FB05D600D38596 /* LogWindowController.m in Sources */,
B65593B124ECB61800722E0C /* SlotViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -444,14 +450,6 @@
name = LaunchWindow.xib;
sourceTree = "<group>";
};
B6D6DE4324FAF00300661A5F /* ModelsView.xib */ = {
isa = PBXVariantGroup;
children = (
B6D6DE4424FAF00300661A5F /* Base */,
);
name = ModelsView.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11134" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11134"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
</objects>
</document>

View File

@ -10,6 +10,7 @@
#import "MediaViewController.h"
#import "SlotViewController.h"
#import "MachineViewController.h"
#import "LogWindowController.h"
static NSString *kMyContext = @"kMyContext";
static NSString *kContextMachine = @"kContextMachine";
@ -228,6 +229,7 @@ static NSString * JoinArguments(NSArray *argv) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *path = [defaults stringForKey: @"MamePath"];
if (![path length]) path = @"/usr/local/bin/mame";
@ -237,15 +239,12 @@ static NSString * JoinArguments(NSArray *argv) {
NSTask *task = [NSTask new];
[task setExecutableURL: url];
[task setArguments: _args];
#if 0
[task setTerminationHandler: ^(NSTask *t){
}];
// set stderr/stdout...
[task launchAndReturnError: &error];
if (error) NSLog(@"launchAction: %@", error);
#endif
[LogWindowController controllerForTask: task];
}

61
MA2ME/LogWindow.xib Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="LogWindowController">
<connections>
<outlet property="textView" destination="562-nZ-1US" id="taS-vF-49s"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="800" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="800" height="270"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hj3-ou-djb">
<rect key="frame" x="0.0" y="0.0" width="800" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="Zvz-As-VIA">
<rect key="frame" x="0.0" y="0.0" width="785" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView ambiguous="YES" editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" smartInsertDelete="YES" id="562-nZ-1US">
<rect key="frame" x="0.0" y="0.0" width="785" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="785" height="270"/>
<size key="maxSize" width="788" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
</textView>
</subviews>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="V8m-bI-zzD">
<rect key="frame" x="-100" y="-100" width="225" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" horizontal="NO" id="clD-em-HSv">
<rect key="frame" x="785" y="0.0" width="15" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="-285" y="-234"/>
</window>
</objects>
</document>

View File

@ -0,0 +1,19 @@
//
// LogWindowController.h
// MA2ME
//
// Created by Kelvin Sherlock on 8/29/2020.
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
//
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface LogWindowController : NSWindowController <NSWindowDelegate>
+(id)controllerForTask: (NSTask *)task;
@end
NS_ASSUME_NONNULL_END

156
MA2ME/LogWindowController.m Normal file
View File

@ -0,0 +1,156 @@
//
// LogWindowController.m
// MA2ME
//
// Created by Kelvin Sherlock on 8/29/2020.
// Copyright © 2020 Kelvin Sherlock. All rights reserved.
//
#import "LogWindowController.h"
static NSMutableSet *LogWindows;
@interface LogWindowController ()
@property (unsafe_unretained) IBOutlet NSTextView *textView;
@end
@implementation LogWindowController {
NSTask *_task;
NSFileHandle *_handle;
}
+(void)initialize {
LogWindows = [NSMutableSet set];
}
-(NSString *)windowNibName {
return @"LogWindow";
}
+(id)controllerForTask: (NSTask *)task {
LogWindowController *controller = [[LogWindowController alloc] initWithWindowNibName: @"LogWindow"];
[controller runTask: task];
return controller;
}
- (void)windowDidLoad {
[super windowDidLoad];
[LogWindows addObject: self];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
-(void)appendString: (NSString *)string
{
if ([string length])
{
[[[_textView textStorage] mutableString] appendString: string];
}
}
-(NSError *)runTask: (NSTask *)task {
if (_task) return nil;
NSError *error = nil;
NSPipe *pipe = [NSPipe pipe];
[task setStandardError: pipe];
[task setStandardOutput: pipe];
[task launchAndReturnError: &error];
if (error) {
NSLog(@"launchAction: %@", error);
[self appendString: [error description]];
return error;
}
_task = task;
NSString *title = [NSString stringWithFormat: @"Log Window - %u", [task processIdentifier]];
[[self window] setTitle: title];
_handle = [pipe fileHandleForReading];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver: self
selector: @selector(taskComplete:)
name: NSTaskDidTerminateNotification
object: _task];
[nc addObserver: self
selector: @selector(readComplete:)
name: NSFileHandleReadCompletionNotification
object: _handle];
[_handle readInBackgroundAndNotify];
[[self window] setDocumentEdited: YES];
return nil;
}
#pragma mark -
#pragma mark Notifications
-(void)readComplete:(NSNotification *)notification
{
// read complete, queue up another.
NSDictionary *dict = [notification userInfo];
NSData *data = [dict objectForKey: NSFileHandleNotificationDataItem];
if ([data length])
{
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
[self appendString: string];
[_handle readInBackgroundAndNotify];
}
}
-(void)taskComplete: (NSNotification *)notification
{
BOOL ok = NO;
NSTaskTerminationReason reason;
int status;
NSString *string = nil;
reason = [_task terminationReason];
status = [_task terminationStatus];
if (reason == NSTaskTerminationReasonExit)
{
if (status == 0)
{
string = @"\n\n[Success]\n\n";
ok = YES;
}
else string = @"\n\n[An error occurred]\n\n";
}
else
{
string = @"\n\n[Caught signal]\n\n";
}
[self appendString: string];
_handle = nil;
_task = nil;
[[self window] setDocumentEdited: NO];
}
#pragma mark - NSWindowDelegate
-(void)windowWillClose:(NSNotification *)notification {
[LogWindows removeObject: self];
}
@end