312 lines
11 KiB
Swift
312 lines
11 KiB
Swift
//
|
|
// CheatsViewController.swift
|
|
// Delta
|
|
//
|
|
// Created by Riley Testut on 5/20/16.
|
|
// Copyright © 2016 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import CoreData
|
|
|
|
import DeltaCore
|
|
|
|
import Roxas
|
|
|
|
protocol CheatsViewControllerDelegate: class
|
|
{
|
|
func cheatsViewControllerActiveEmulatorCore(saveStatesViewController: CheatsViewController) -> EmulatorCore
|
|
func cheatsViewController(cheatsViewController: CheatsViewController, didActivateCheat cheat: Cheat) throws
|
|
func cheatsViewController(cheatsViewController: CheatsViewController, didDeactivateCheat cheat: Cheat) throws
|
|
}
|
|
|
|
class CheatsViewController: UITableViewController
|
|
{
|
|
weak var delegate: CheatsViewControllerDelegate! {
|
|
didSet {
|
|
self.updateFetchedResultsController()
|
|
}
|
|
}
|
|
|
|
private var backgroundView: RSTBackgroundView!
|
|
|
|
private var fetchedResultsController: NSFetchedResultsController!
|
|
}
|
|
|
|
extension CheatsViewController
|
|
{
|
|
override func viewDidLoad()
|
|
{
|
|
super.viewDidLoad()
|
|
|
|
self.title = NSLocalizedString("Cheats", comment: "")
|
|
|
|
self.backgroundView = RSTBackgroundView(frame: self.view.bounds)
|
|
self.backgroundView.hidden = false
|
|
self.backgroundView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
|
|
self.backgroundView.textLabel.text = NSLocalizedString("No Cheats", comment: "")
|
|
self.backgroundView.textLabel.textColor = UIColor.whiteColor()
|
|
self.backgroundView.detailTextLabel.text = NSLocalizedString("You can add a new cheat by pressing the + button in the top right.", comment: "")
|
|
self.backgroundView.detailTextLabel.textColor = UIColor.whiteColor()
|
|
self.tableView.backgroundView = self.backgroundView
|
|
|
|
self.registerForPreviewingWithDelegate(self, sourceView: self.tableView)
|
|
}
|
|
|
|
override func viewWillAppear(animated: Bool)
|
|
{
|
|
self.fetchedResultsController.performFetchIfNeeded()
|
|
|
|
self.updateBackgroundView()
|
|
|
|
super.viewWillAppear(animated)
|
|
}
|
|
|
|
override func didReceiveMemoryWarning()
|
|
{
|
|
super.didReceiveMemoryWarning()
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
}
|
|
|
|
//MARK: - Navigation -
|
|
private extension CheatsViewController
|
|
{
|
|
@IBAction func unwindFromEditCheatViewController(segue: UIStoryboardSegue)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
//MARK: - Update -
|
|
private extension CheatsViewController
|
|
{
|
|
func updateFetchedResultsController()
|
|
{
|
|
let game = self.delegate.cheatsViewControllerActiveEmulatorCore(self).game as! Game
|
|
|
|
let fetchRequest = Cheat.fetchRequest()
|
|
fetchRequest.returnsObjectsAsFaults = false
|
|
fetchRequest.predicate = NSPredicate(format: "%K == %@", Cheat.Attributes.game.rawValue, game)
|
|
fetchRequest.sortDescriptors = [NSSortDescriptor(key: Cheat.Attributes.name.rawValue, ascending: true)]
|
|
|
|
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
|
|
self.fetchedResultsController.delegate = self
|
|
}
|
|
|
|
func updateBackgroundView()
|
|
{
|
|
if let fetchedObjects = self.fetchedResultsController.fetchedObjects where fetchedObjects.count > 0
|
|
{
|
|
self.tableView.separatorStyle = .SingleLine
|
|
self.backgroundView.hidden = true
|
|
}
|
|
else
|
|
{
|
|
self.tableView.separatorStyle = .None
|
|
self.backgroundView.hidden = false
|
|
}
|
|
}
|
|
}
|
|
|
|
//MARK: - Managing Cheats -
|
|
/// Managing Cheats
|
|
private extension CheatsViewController
|
|
{
|
|
@IBAction func addCheat()
|
|
{
|
|
let editCheatViewController = self.makeEditCheatViewController(cheat: nil)
|
|
editCheatViewController.presentWithPresentingViewController(self)
|
|
}
|
|
|
|
func deleteCheat(cheat: Cheat)
|
|
{
|
|
let _ = try? self.delegate.cheatsViewController(self, didDeactivateCheat: cheat)
|
|
|
|
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
|
|
backgroundContext.performBlock {
|
|
let temporaryCheat = backgroundContext.objectWithID(cheat.objectID)
|
|
backgroundContext.deleteObject(temporaryCheat)
|
|
backgroundContext.saveWithErrorLogging()
|
|
}
|
|
}
|
|
}
|
|
|
|
//MARK: - Convenience -
|
|
/// Convenience
|
|
private extension CheatsViewController
|
|
{
|
|
func configure(cell cell: UITableViewCell, forIndexPath indexPath: NSIndexPath)
|
|
{
|
|
let cheat = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Cheat
|
|
cell.textLabel?.text = cheat.name
|
|
cell.textLabel?.font = UIFont.boldSystemFontOfSize(cell.textLabel!.font.pointSize)
|
|
cell.accessoryType = cheat.enabled ? .Checkmark : .None
|
|
}
|
|
|
|
func makeEditCheatViewController(cheat cheat: Cheat?) -> EditCheatViewController
|
|
{
|
|
let editCheatViewController = self.storyboard!.instantiateViewControllerWithIdentifier("editCheatViewController") as! EditCheatViewController
|
|
editCheatViewController.delegate = self
|
|
editCheatViewController.supportedCheatFormats = self.delegate.cheatsViewControllerActiveEmulatorCore(self).supportedCheatFormats
|
|
editCheatViewController.cheat = cheat
|
|
editCheatViewController.game = self.delegate.cheatsViewControllerActiveEmulatorCore(self).game as! Game
|
|
|
|
return editCheatViewController
|
|
}
|
|
}
|
|
|
|
extension CheatsViewController
|
|
{
|
|
// MARK: - Table view data source
|
|
|
|
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
|
|
{
|
|
let numberOfSections = self.fetchedResultsController.sections!.count
|
|
return numberOfSections
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
|
|
{
|
|
let section = self.fetchedResultsController.sections![section]
|
|
return section.numberOfObjects
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
|
|
{
|
|
let cell = tableView.dequeueReusableCellWithIdentifier(RSTGenericCellIdentifier, forIndexPath: indexPath)
|
|
self.configure(cell: cell, forIndexPath: indexPath)
|
|
return cell
|
|
}
|
|
}
|
|
|
|
extension CheatsViewController
|
|
{
|
|
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
|
|
{
|
|
let cheat = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Cheat
|
|
|
|
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
|
|
backgroundContext.performBlockAndWait {
|
|
let temporaryCheat = backgroundContext.objectWithID(cheat.objectID) as! Cheat
|
|
temporaryCheat.enabled = !temporaryCheat.enabled
|
|
|
|
do
|
|
{
|
|
if temporaryCheat.enabled
|
|
{
|
|
try self.delegate.cheatsViewController(self, didActivateCheat: temporaryCheat)
|
|
}
|
|
else
|
|
{
|
|
try self.delegate.cheatsViewController(self, didDeactivateCheat: temporaryCheat)
|
|
}
|
|
}
|
|
catch EmulatorCore.CheatError.invalid
|
|
{
|
|
print("Invalid cheat:", cheat.name, cheat.code)
|
|
}
|
|
catch EmulatorCore.CheatError.doesNotExist
|
|
{
|
|
print("Cheat does not exist:", cheat.name, cheat.code)
|
|
}
|
|
catch let error as NSError
|
|
{
|
|
print("Unknown Cheat Error:", error, cheat.name, cheat.code)
|
|
}
|
|
|
|
backgroundContext.saveWithErrorLogging()
|
|
}
|
|
|
|
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]?
|
|
{
|
|
let cheat = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Cheat
|
|
|
|
let deleteAction = UITableViewRowAction(style: .Destructive, title: NSLocalizedString("Delete", comment: "")) { (action, indexPath) in
|
|
self.deleteCheat(cheat)
|
|
}
|
|
|
|
let editAction = UITableViewRowAction(style: .Normal, title: NSLocalizedString("Edit", comment: "")) { (action, indexPath) in
|
|
let editCheatViewController = self.makeEditCheatViewController(cheat: cheat)
|
|
editCheatViewController.presentWithPresentingViewController(self)
|
|
}
|
|
|
|
return [deleteAction, editAction]
|
|
}
|
|
|
|
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
|
|
{
|
|
// This method intentionally left blank because someone decided it was a Good Idea™ to require this method be implemented to use UITableViewRowActions
|
|
}
|
|
}
|
|
|
|
//MARK: - <UIViewControllerPreviewingDelegate> -
|
|
extension CheatsViewController: UIViewControllerPreviewingDelegate
|
|
{
|
|
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
|
|
{
|
|
guard let indexPath = self.tableView.indexPathForRowAtPoint(location) else { return nil }
|
|
|
|
let frame = self.tableView.rectForRowAtIndexPath(indexPath)
|
|
previewingContext.sourceRect = frame
|
|
|
|
let cheat = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Cheat
|
|
|
|
let editCheatViewController = self.makeEditCheatViewController(cheat: cheat)
|
|
return editCheatViewController
|
|
}
|
|
|
|
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController)
|
|
{
|
|
let editCheatViewController = viewControllerToCommit as! EditCheatViewController
|
|
editCheatViewController.presentWithPresentingViewController(self)
|
|
}
|
|
}
|
|
|
|
//MARK: - <EditCheatViewControllerDelegate> -
|
|
extension CheatsViewController: EditCheatViewControllerDelegate
|
|
{
|
|
func editCheatViewController(editCheatViewController: EditCheatViewController, activateCheat cheat: Cheat, previousCheat: Cheat?) throws
|
|
{
|
|
try self.delegate.cheatsViewController(self, didActivateCheat: cheat)
|
|
|
|
if let previousCheat = previousCheat
|
|
{
|
|
let code = cheat.code
|
|
|
|
previousCheat.managedObjectContext?.performBlockAndWait({
|
|
|
|
guard previousCheat.code != code else { return }
|
|
|
|
do
|
|
{
|
|
try self.delegate.cheatsViewController(self, didDeactivateCheat: previousCheat)
|
|
}
|
|
catch let error as NSError
|
|
{
|
|
print(error)
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func editCheatViewController(editCheatViewController: EditCheatViewController, deactivateCheat cheat: Cheat)
|
|
{
|
|
let _ = try? self.delegate.cheatsViewController(self, didDeactivateCheat: cheat)
|
|
}
|
|
}
|
|
|
|
//MARK: - <NSFetchedResultsControllerDelegate> -
|
|
extension CheatsViewController: NSFetchedResultsControllerDelegate
|
|
{
|
|
func controllerDidChangeContent(controller: NSFetchedResultsController)
|
|
{
|
|
self.tableView.reloadData()
|
|
self.updateBackgroundView()
|
|
}
|
|
}
|