Path: blob/main/Natives/PLLogOutputView.m
589 views
#import "PLLogOutputView.h"1#import "SurfaceViewController.h"2#import "utils.h"34@interface PLLogOutputView()<UITableViewDataSource, UITableViewDelegate>5@property(nonatomic) UITableView* logTableView;6@property(nonatomic) UINavigationBar* navigationBar;7@end89@implementation PLLogOutputView10static BOOL fatalErrorOccurred;11static NSMutableArray* logLines;12static PLLogOutputView* current;1314- (instancetype)initWithFrame:(CGRect)frame {15frame.origin.y = frame.size.height;16self = [super initWithFrame:frame];17frame.origin.y = 0;1819logLines = [NSMutableArray new];20self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];21self.hidden = YES;2223UINavigationItem *navigationItem = [[UINavigationItem alloc] init];24navigationItem.rightBarButtonItems = @[25[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop26target:self action:@selector(actionToggleLogOutput)],27[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash28target:self action:@selector(actionClearLogOutput)]29];30self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 44)];31self.navigationBar.items = @[navigationItem];32self.navigationBar.topItem.title = localize(@"game.menu.log_output", nil);33[self.navigationBar sizeToFit];34self.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;3536self.logTableView = [[UITableView alloc] initWithFrame:frame];37//self.logTableView.allowsSelection = NO;38self.logTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;39self.logTableView.backgroundColor = UIColor.clearColor;40self.logTableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);41self.logTableView.dataSource = self;42self.logTableView.delegate = self;43self.logTableView.layoutMargins = UIEdgeInsetsZero;44self.logTableView.rowHeight = 20;45self.logTableView.separatorInset = UIEdgeInsetsZero;46self.logTableView.separatorStyle = UITableViewCellSeparatorStyleNone;47[self addSubview:self.logTableView];48[self addSubview:self.navigationBar];4950canAppendToLog = YES;51[self actionStartStopLogOutput];5253current = self;54return self;55}5657- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {58return logLines.count;59}6061- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {62UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];6364if (cell == nil) {65cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];66cell.backgroundColor = UIColor.clearColor;67//cell.selectionStyle = UITableViewCellSelectionStyleNone;68cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:16];69cell.textLabel.textColor = UIColor.whiteColor;70}71cell.textLabel.text = logLines[indexPath.row];7273return cell;74}7576- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {77[tableView deselectRowAtIndexPath:indexPath animated:NO];7879UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];80NSString *line = cell.textLabel.text;81if (line.length == 0 || [line isEqualToString:@"\n"]) {82return;83}8485UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:line preferredStyle:UIAlertControllerStyleActionSheet];86alert.popoverPresentationController.sourceView = cell;87alert.popoverPresentationController.sourceRect = cell.bounds;88UIAlertAction *share = [UIAlertAction actionWithTitle:localize(localize(@"Share", nil), nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {89UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[line] applicationActivities:nil];90activityVC.popoverPresentationController.sourceView = _navigationBar;91activityVC.popoverPresentationController.sourceRect = _navigationBar.bounds;92[currentVC() presentViewController:activityVC animated:YES completion:nil];93}];94UIAlertAction *cancel = [UIAlertAction actionWithTitle:localize(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil];95[alert addAction:share];96[alert addAction:cancel];97[currentVC() presentViewController:alert animated:YES completion:nil];98}99100- (void)actionClearLogOutput {101[logLines removeAllObjects];102[self.logTableView reloadData];103}104105- (void)actionShareLatestlog {106NSString *latestlogPath = [NSString stringWithFormat:@"file://%s/latestlog.txt", getenv("POJAV_HOME")];107UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[@"latestlog.txt",108[NSURL URLWithString:latestlogPath]] applicationActivities:nil];109activityVC.popoverPresentationController.sourceView = self.navigationBar;110activityVC.popoverPresentationController.sourceRect = self.navigationBar.bounds;111[currentVC() presentViewController:activityVC animated:YES completion:nil];112}113114- (void)actionStartStopLogOutput {115canAppendToLog = !canAppendToLog;116UINavigationItem* item = self.navigationBar.items[0];117item.leftBarButtonItem =118[[UIBarButtonItem alloc] initWithBarButtonSystemItem:119canAppendToLog ? UIBarButtonSystemItemPause : UIBarButtonSystemItemPlay120target:self action:@selector(actionStartStopLogOutput)];121}122123- (void)actionToggleLogOutput {124if (fatalErrorOccurred) {125[UIApplication.sharedApplication performSelector:@selector(suspend)];126dispatch_group_leave(fatalExitGroup);127return;128}129130UIViewAnimationOptions opt = self.hidden ? UIViewAnimationOptionCurveEaseOut : UIViewAnimationOptionCurveEaseIn;131[UIView transitionWithView:self duration:0.4 options:UIViewAnimationOptionCurveEaseOut animations:^(void){132CGRect frame = self.frame;133frame.origin.y = self.hidden ? 0 : frame.size.height;134self.hidden = NO;135self.frame = frame;136} completion: ^(BOOL finished) {137self.hidden = self.frame.origin.y != 0;138}];139}140141+ (void)_appendToLog:(NSString *)line {142if (line.length == 0) {143return;144}145146NSIndexPath *indexPath = [NSIndexPath indexPathForRow:logLines.count inSection:0];147[logLines addObject:line];148UIView.animationsEnabled = NO;149[current.logTableView beginUpdates];150[current.logTableView151insertRowsAtIndexPaths:@[indexPath]152withRowAnimation:UITableViewRowAnimationNone];153[current.logTableView endUpdates];154UIView.animationsEnabled = YES;155156[current.logTableView157scrollToRowAtIndexPath:indexPath158atScrollPosition:UITableViewScrollPositionBottom animated:NO];159}160161+ (void)appendToLog:(NSString *)string {162dispatch_async(dispatch_get_main_queue(), ^(void){163NSArray *lines = [string componentsSeparatedByCharactersInSet:164NSCharacterSet.newlineCharacterSet];165for (NSString *line in lines) {166[self _appendToLog:line];167}168});169}170171+ (void)handleExitCode:(int)code {172if (!current) return;173dispatch_async(dispatch_get_main_queue(), ^(void){174if (current.hidden) {175[current actionToggleLogOutput];176}177// Cleanup navigation bar178UINavigationBar *navigationBar = current.navigationBar;179navigationBar.topItem.title = [NSString stringWithFormat:180localize(@"game.title.exit_code", nil), code];181navigationBar.items[0].leftBarButtonItem = [[UIBarButtonItem alloc]182initWithBarButtonSystemItem:UIBarButtonSystemItemAction183target:current action:@selector(actionShareLatestlog)];184UIBarButtonItem *exitItem = navigationBar.items[0].rightBarButtonItems[0];185navigationBar.items[0].rightBarButtonItems = nil;186navigationBar.items[0].rightBarButtonItem = exitItem;187188if (canAppendToLog) {189canAppendToLog = NO;190fatalErrorOccurred = YES;191return;192}193[current actionClearLogOutput];194[self _appendToLog:@"... (latestlog.txt)"];195NSString *latestlogPath = [NSString stringWithFormat:@"%s/latestlog.txt", getenv("POJAV_HOME")];196NSString *linesStr = [NSString stringWithContentsOfFile:latestlogPath197encoding:NSUTF8StringEncoding error:nil];198NSArray *lines = [linesStr componentsSeparatedByCharactersInSet:199NSCharacterSet.newlineCharacterSet];200201// Print last 100 lines from latestlog.txt202for (int i = MAX(lines.count-100, 0); i < lines.count; i++) {203[self _appendToLog:lines[i]];204}205206fatalErrorOccurred = YES;207});208}209210@end211212213