Play-/Source/ui_ios/CoverViewController.mm
Jean-Philip Desjardins 1fef15cb24 Move AltServer JIT logic in a separate module.
Also added a toggle to enable/disable it.
2021-11-20 15:35:57 -05:00

202 lines
6 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#import <SDWebImage/UIImageView+WebCache.h>
#import "CoverViewController.h"
#import "EmulatorViewController.h"
#import "SettingsViewController.h"
#import "../ui_shared/BootablesProcesses.h"
#import "../ui_shared/BootablesDbClient.h"
#import "PathUtils.h"
#import "BackgroundLayer.h"
#import "CoverViewCell.h"
#import "AltServerJitService.h"
@interface CoverViewController ()
@end
@implementation CoverViewController
static NSString* const reuseIdentifier = @"coverCell";
- (void)buildCollectionWithForcedFullScan:(BOOL)forceFullDeviceScan
{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Building collection" message:@"Please wait..." preferredStyle:UIAlertControllerStyleAlert];
CGRect aivRect = CGRectMake(0, 0, 40, 40);
UIActivityIndicatorView* aiv = [[UIActivityIndicatorView alloc] initWithFrame:aivRect];
[aiv startAnimating];
UIViewController* vc = [[UIViewController alloc] init];
vc.preferredContentSize = aivRect.size;
[vc.view addSubview:aiv];
[alert setValue:vc forKey:@"contentViewController"];
[self presentViewController:alert animated:YES completion:nil];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
auto activeDirs = GetActiveBootableDirectories();
if(forceFullDeviceScan || activeDirs.empty())
{
dispatch_async(dispatch_get_main_queue(), ^{
alert.message = @"Scanning games on filesystem...";
});
ScanBootables("/private/var/mobile");
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
alert.message = @"Scanning games in active directories...";
});
for(const auto& activeDir : activeDirs)
{
ScanBootables(activeDir, false);
}
}
//Always scan games in app storage. The app's path change when it's reinstalled,
//thus, games from the previous installation won't be found (will be deleted in PurgeInexistingFiles).
dispatch_async(dispatch_get_main_queue(), ^{
alert.message = @"Scanning games in app storage...";
});
ScanBootables(Framework::PathUtils::GetPersonalDataPath());
dispatch_async(dispatch_get_main_queue(), ^{
alert.message = @"Purging inexisting files...";
});
PurgeInexistingFiles();
dispatch_async(dispatch_get_main_queue(), ^{
alert.message = @"Fetching game titles...";
});
FetchGameTitles();
if(_bootables)
{
delete _bootables;
_bootables = nullptr;
}
_bootables = new BootableArray(BootablesDb::CClient::GetInstance().GetBootables());
//Done
dispatch_async(dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
[self.collectionView reloadData];
});
});
}
- (void)viewDidLoad
{
[super viewDidLoad];
CAGradientLayer* bgLayer = [BackgroundLayer blueGradient];
bgLayer.frame = self.view.bounds;
[self.view.layer insertSublayer:bgLayer atIndex:0];
self.collectionView.allowsMultipleSelection = NO;
if(@available(iOS 11.0, *))
{
self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
}
[[AltServerJitService sharedAltServerJitService] startProcess];
[self buildCollectionWithForcedFullScan:NO];
}
- (void)viewDidUnload
{
assert(_bootables != nullptr);
delete _bootables;
[super viewDidUnload];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// resize your layers based on the views new bounds
[[[self.view.layer sublayers] objectAtIndex:0] setFrame:self.view.bounds];
}
- (BOOL)shouldAutorotate
{
if([self isViewLoaded] && self.view.window)
{
return YES;
}
else
{
return NO;
}
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView
{
return 1;
}
- (NSString*)collectionView:(UICollectionView*)collectionView titleForHeaderInSection:(NSInteger)section
{
return @"";
}
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section
{
return _bootables ? _bootables->size() : 0;
}
- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath
{
CoverViewCell* cell = (CoverViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
auto bootable = (*_bootables)[indexPath.row];
UIImage* placeholder = [UIImage imageNamed:@"boxart.png"];
cell.nameLabel.text = [NSString stringWithUTF8String:bootable.title.c_str()];
cell.backgroundView = [[UIImageView alloc] initWithImage:placeholder];
if(!bootable.coverUrl.empty())
{
NSString* coverUrl = [NSString stringWithUTF8String:bootable.coverUrl.c_str()];
[(UIImageView*)cell.backgroundView sd_setImageWithURL:[NSURL URLWithString:coverUrl] placeholderImage:placeholder];
}
return cell;
}
#pragma mark <UICollectionViewDelegate>
- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"showEmulator"])
{
NSIndexPath* indexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
auto bootable = (*_bootables)[indexPath.row];
BootablesDb::CClient::GetInstance().SetLastBootedTime(bootable.path, time(nullptr));
EmulatorViewController* emulatorViewController = segue.destinationViewController;
emulatorViewController.bootablePath = [NSString stringWithUTF8String:bootable.path.native().c_str()];
[self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
else if([segue.identifier isEqualToString:@"showSettings"])
{
UINavigationController* navViewController = segue.destinationViewController;
SettingsViewController* settingsViewController = (SettingsViewController*)navViewController.visibleViewController;
settingsViewController.allowFullDeviceScan = true;
settingsViewController.allowGsHandlerSelection = true;
settingsViewController.completionHandler = ^(bool fullScanRequested) {
[[AltServerJitService sharedAltServerJitService] startProcess];
if(fullScanRequested)
{
[self buildCollectionWithForcedFullScan:YES];
}
};
}
}
- (IBAction)onExit:(id)sender
{
exit(0);
}
@end