Adds back support for presenting CheatsViewController from Pause Menu
This commit is contained in:
parent
8c3d072a5f
commit
a5c50b41bc
@ -7,7 +7,7 @@
|
||||
<attribute name="identifier" attributeType="String" syncable="YES"/>
|
||||
<attribute name="modifiedDate" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||
<attribute name="type" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="type" attributeType="String" syncable="YES"/>
|
||||
<relationship name="game" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Game" inverseName="cheats" inverseEntity="Game" syncable="YES"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit d819614e5fe422aa4975f70e3d4f1d2dc97b9c24
|
||||
Subproject commit 7149d73128c0f5c95b3e58990f9d185cf33277df
|
||||
@ -19,6 +19,7 @@
|
||||
BF27CC8E1BC9FEA200A20D89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BF6BB2451BB73FE800CCF94A /* Assets.xcassets */; };
|
||||
BF27CC971BCC890700A20D89 /* GamesCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */; };
|
||||
BF2B98E61C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF2B98E51C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift */; };
|
||||
BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF31878A1D489AAA00BD020D /* CheatValidator.swift */; };
|
||||
BF34FA071CF0F510006624C7 /* EditCheatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF34FA061CF0F510006624C7 /* EditCheatViewController.swift */; };
|
||||
BF34FA111CF1899D006624C7 /* CheatTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF34FA101CF1899D006624C7 /* CheatTextView.swift */; };
|
||||
BF353FF21C5D7FB000C1184C /* PauseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF353FF11C5D7FB000C1184C /* PauseViewController.swift */; };
|
||||
@ -102,6 +103,7 @@
|
||||
BF27CC941BCB7B7A00A20D89 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
||||
BF27CC961BCC890700A20D89 /* GamesCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesCollectionViewController.swift; sourceTree = "<group>"; };
|
||||
BF2B98E51C97E32F00F6D57D /* SaveStatesCollectionHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SaveStatesCollectionHeaderView.swift; path = "Pause Menu/Save States/SaveStatesCollectionHeaderView.swift"; sourceTree = "<group>"; };
|
||||
BF31878A1D489AAA00BD020D /* CheatValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatValidator.swift; path = "Pause Menu/Cheats/CheatValidator.swift"; sourceTree = "<group>"; };
|
||||
BF34FA061CF0F510006624C7 /* EditCheatViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EditCheatViewController.swift; path = "Pause Menu/Cheats/EditCheatViewController.swift"; sourceTree = "<group>"; };
|
||||
BF34FA101CF1899D006624C7 /* CheatTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CheatTextView.swift; path = "Pause Menu/Cheats/CheatTextView.swift"; sourceTree = "<group>"; };
|
||||
BF353FF11C5D7FB000C1184C /* PauseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PauseViewController.swift; path = "Pause Menu/PauseViewController.swift"; sourceTree = "<group>"; };
|
||||
@ -320,6 +322,7 @@
|
||||
BFC9B7381CEFCD34008629BB /* CheatsViewController.swift */,
|
||||
BF34FA061CF0F510006624C7 /* EditCheatViewController.swift */,
|
||||
BF34FA101CF1899D006624C7 /* CheatTextView.swift */,
|
||||
BF31878A1D489AAA00BD020D /* CheatValidator.swift */,
|
||||
);
|
||||
name = Cheats;
|
||||
sourceTree = "<group>";
|
||||
@ -542,6 +545,7 @@
|
||||
BF7AE8241C2E984300B1B5BC /* GridCollectionViewLayout.swift in Sources */,
|
||||
BF1FB1861C5EE643007E2494 /* SaveState.swift in Sources */,
|
||||
BFA0D1271D3AE1F600565894 /* GameViewController.swift in Sources */,
|
||||
BF31878B1D489AAA00BD020D /* CheatValidator.swift in Sources */,
|
||||
BFB141181BE46934004FBF46 /* GameCollectionViewDataSource.swift in Sources */,
|
||||
BFA2315C1CED10BE0011E35A /* Action.swift in Sources */,
|
||||
BFAA1FF41B8AD7F900495943 /* ControllersSettingsViewController.swift in Sources */,
|
||||
|
||||
@ -10,13 +10,20 @@ import UIKit
|
||||
|
||||
import DeltaCore
|
||||
|
||||
private var kvoContext = 0
|
||||
|
||||
class GameViewController: DeltaCore.GameViewController
|
||||
{
|
||||
/// Assumed to be Delta.Game instance
|
||||
override var game: GameProtocol? {
|
||||
willSet {
|
||||
self.emulatorCore?.removeObserver(self, forKeyPath: #keyPath(EmulatorCore.state), context: &kvoContext)
|
||||
}
|
||||
didSet {
|
||||
guard let emulatorCore = self.emulatorCore else { return }
|
||||
self.preferredContentSize = emulatorCore.preferredRenderingSize
|
||||
|
||||
emulatorCore.addObserver(self, forKeyPath: #keyPath(EmulatorCore.state), options: [.old], context: &kvoContext)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +58,11 @@ class GameViewController: DeltaCore.GameViewController
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.updateControllers), name: .externalControllerDidDisconnect, object: nil)
|
||||
}
|
||||
|
||||
deinit
|
||||
{
|
||||
self.emulatorCore?.removeObserver(self, forKeyPath: #keyPath(EmulatorCore.state), context: &kvoContext)
|
||||
}
|
||||
|
||||
// MARK: GameControllerReceiver -
|
||||
override func gameController(_ gameController: GameController, didActivate input: Input)
|
||||
{
|
||||
@ -116,6 +128,7 @@ extension GameViewController
|
||||
pauseViewController.pauseText = (self.game as? Game)?.name ?? NSLocalizedString("Delta", comment: "")
|
||||
pauseViewController.emulatorCore = self.emulatorCore
|
||||
pauseViewController.saveStatesViewControllerDelegate = self
|
||||
pauseViewController.cheatsViewControllerDelegate = self
|
||||
self.pauseViewController = pauseViewController
|
||||
}
|
||||
|
||||
@ -135,6 +148,20 @@ extension GameViewController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - KVO -
|
||||
/// KVO
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?)
|
||||
{
|
||||
guard context == &kvoContext else { return super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) }
|
||||
|
||||
guard let rawValue = change?[.oldKey] as? Int, let previousState = EmulatorCore.State(rawValue: rawValue) else { return }
|
||||
|
||||
if previousState == .stopped
|
||||
{
|
||||
self.updateCheats()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: Controllers -
|
||||
@ -244,10 +271,81 @@ extension GameViewController: SaveStatesViewControllerDelegate
|
||||
print(error)
|
||||
}
|
||||
|
||||
self.updateCheats()
|
||||
|
||||
self.pauseViewController?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Cheats
|
||||
/// Cheats
|
||||
extension GameViewController: CheatsViewControllerDelegate
|
||||
{
|
||||
func cheatsViewController(_ cheatsViewController: CheatsViewController, activateCheat cheat: Cheat)
|
||||
{
|
||||
self.activate(cheat)
|
||||
}
|
||||
|
||||
func cheatsViewController(_ cheatsViewController: CheatsViewController, deactivateCheat cheat: Cheat)
|
||||
{
|
||||
self.emulatorCore?.deactivate(cheat)
|
||||
}
|
||||
|
||||
private func activate(_ cheat: Cheat)
|
||||
{
|
||||
do
|
||||
{
|
||||
try self.emulatorCore?.activate(cheat)
|
||||
}
|
||||
catch EmulatorCore.CheatError.invalid
|
||||
{
|
||||
print("Invalid cheat:", cheat.name, cheat.code)
|
||||
}
|
||||
catch let error as NSError
|
||||
{
|
||||
print("Unknown Cheat Error:", error, cheat.name, cheat.code)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateCheats()
|
||||
{
|
||||
guard let game = self.game as? Game else { return }
|
||||
|
||||
let running = (self.emulatorCore?.state == .running)
|
||||
|
||||
if running
|
||||
{
|
||||
// Core MUST be paused when activating cheats, or else race conditions could crash the core
|
||||
self.pauseEmulation()
|
||||
}
|
||||
|
||||
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
|
||||
backgroundContext.performAndWait {
|
||||
|
||||
let predicate = Predicate(format: "%K == %@", Cheat.Attributes.game.rawValue, game)
|
||||
|
||||
let cheats = Cheat.instancesWithPredicate(predicate, inManagedObjectContext: backgroundContext, type: Cheat.self)
|
||||
for cheat in cheats
|
||||
{
|
||||
if cheat.enabled
|
||||
{
|
||||
self.activate(cheat)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.emulatorCore?.deactivate(cheat)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if running
|
||||
{
|
||||
self.resumeEmulation()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: GameViewControllerDelegate -
|
||||
/// GameViewControllerDelegate
|
||||
extension GameViewController: GameViewControllerDelegate
|
||||
|
||||
59
Delta/Pause Menu/Cheats/CheatValidator.swift
Normal file
59
Delta/Pause Menu/Cheats/CheatValidator.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// CheatValidator.swift
|
||||
// Delta
|
||||
//
|
||||
// Created by Riley Testut on 7/27/16.
|
||||
// Copyright © 2016 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import DeltaCore
|
||||
|
||||
extension CheatValidator
|
||||
{
|
||||
enum Error: ErrorProtocol
|
||||
{
|
||||
case invalidCode
|
||||
case invalidName
|
||||
case duplicateName
|
||||
case duplicateCode
|
||||
}
|
||||
}
|
||||
|
||||
struct CheatValidator
|
||||
{
|
||||
let format: CheatFormat
|
||||
let managedObjectContext: NSManagedObjectContext
|
||||
|
||||
func validate(_ cheat: Cheat) throws
|
||||
{
|
||||
guard let name = cheat.name else { throw Error.invalidName }
|
||||
|
||||
let code = cheat.code
|
||||
|
||||
// Find all cheats that are for the same game, don't have the same identifier as the current cheat, but have either the same name or code
|
||||
let predicate = Predicate(format: "%K == %@ AND %K != %@ AND (%K == %@ OR %K == %@)", Cheat.Attributes.game.rawValue, cheat.game, Cheat.Attributes.identifier.rawValue, cheat.identifier, Cheat.Attributes.code.rawValue, code, Cheat.Attributes.name.rawValue, name)
|
||||
|
||||
let cheats = Cheat.instancesWithPredicate(predicate, inManagedObjectContext: self.managedObjectContext, type: Cheat.self)
|
||||
for cheat in cheats
|
||||
{
|
||||
if cheat.name == name
|
||||
{
|
||||
throw Error.duplicateName
|
||||
}
|
||||
else if cheat.code == code
|
||||
{
|
||||
throw Error.duplicateCode
|
||||
}
|
||||
}
|
||||
|
||||
// Remove newline characters (code should already be formatted)
|
||||
let sanitizedCode = (cheat.code as NSString).replacingOccurrences(of: "\n", with: "")
|
||||
|
||||
if sanitizedCode.characters.count % self.format.format.characters.count != 0
|
||||
{
|
||||
throw Error.invalidCode
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,19 +15,20 @@ 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)
|
||||
func cheatsViewController(_ cheatsViewController: CheatsViewController, activateCheat cheat: Cheat)
|
||||
func cheatsViewController(_ cheatsViewController: CheatsViewController, deactivateCheat cheat: Cheat)
|
||||
}
|
||||
|
||||
class CheatsViewController: UITableViewController
|
||||
{
|
||||
weak var delegate: CheatsViewControllerDelegate! {
|
||||
var game: Game! {
|
||||
didSet {
|
||||
self.updateFetchedResultsController()
|
||||
}
|
||||
}
|
||||
|
||||
weak var delegate: CheatsViewControllerDelegate?
|
||||
|
||||
private var backgroundView: RSTBackgroundView!
|
||||
|
||||
private var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
|
||||
@ -83,11 +84,9 @@ private extension CheatsViewController
|
||||
{
|
||||
func updateFetchedResultsController()
|
||||
{
|
||||
let game = self.delegate.cheatsViewControllerActiveEmulatorCore(self).game as! Game
|
||||
|
||||
let fetchRequest = Cheat.rst_fetchRequest()
|
||||
fetchRequest.returnsObjectsAsFaults = false
|
||||
fetchRequest.predicate = Predicate(format: "%K == %@", Cheat.Attributes.game.rawValue, game)
|
||||
fetchRequest.predicate = Predicate(format: "%K == %@", Cheat.Attributes.game.rawValue, self.game)
|
||||
fetchRequest.sortDescriptors = [SortDescriptor(key: Cheat.Attributes.name.rawValue, ascending: true)]
|
||||
|
||||
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.sharedManager.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
|
||||
@ -121,7 +120,7 @@ private extension CheatsViewController
|
||||
|
||||
func deleteCheat(_ cheat: Cheat)
|
||||
{
|
||||
self.delegate.cheatsViewController(self, didDeactivateCheat: cheat)
|
||||
self.delegate?.cheatsViewController(self, deactivateCheat: cheat)
|
||||
|
||||
let backgroundContext = DatabaseManager.sharedManager.backgroundManagedObjectContext()
|
||||
backgroundContext.perform {
|
||||
@ -145,12 +144,11 @@ private extension CheatsViewController
|
||||
}
|
||||
|
||||
func makeEditCheatViewController(cheat: Cheat?) -> EditCheatViewController
|
||||
{
|
||||
{
|
||||
let editCheatViewController = self.storyboard!.instantiateViewController(withIdentifier: "editCheatViewController") as! EditCheatViewController
|
||||
editCheatViewController.delegate = self
|
||||
editCheatViewController.supportedCheatFormats = self.delegate.cheatsViewControllerActiveEmulatorCore(self).configuration.supportedCheatFormats
|
||||
editCheatViewController.cheat = cheat
|
||||
editCheatViewController.game = self.delegate.cheatsViewControllerActiveEmulatorCore(self).game as! Game
|
||||
editCheatViewController.game = self.game
|
||||
|
||||
return editCheatViewController
|
||||
}
|
||||
@ -193,25 +191,13 @@ extension CheatsViewController
|
||||
|
||||
if temporaryCheat.enabled
|
||||
{
|
||||
do
|
||||
{
|
||||
try self.delegate.cheatsViewController(self, didActivateCheat: temporaryCheat)
|
||||
}
|
||||
catch EmulatorCore.CheatError.invalid
|
||||
{
|
||||
print("Invalid cheat:", cheat.name, cheat.code)
|
||||
}
|
||||
catch let error as NSError
|
||||
{
|
||||
print("Unknown Cheat Error:", error, cheat.name, cheat.code)
|
||||
}
|
||||
self.delegate?.cheatsViewController(self, activateCheat: temporaryCheat)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.delegate.cheatsViewController(self, didDeactivateCheat: temporaryCheat)
|
||||
self.delegate?.cheatsViewController(self, deactivateCheat: temporaryCheat)
|
||||
}
|
||||
|
||||
|
||||
backgroundContext.saveWithErrorLogging()
|
||||
}
|
||||
|
||||
@ -266,9 +252,9 @@ extension CheatsViewController: UIViewControllerPreviewingDelegate
|
||||
//MARK: - <EditCheatViewControllerDelegate> -
|
||||
extension CheatsViewController: EditCheatViewControllerDelegate
|
||||
{
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, activateCheat cheat: Cheat, previousCheat: Cheat?) throws
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, activateCheat cheat: Cheat, previousCheat: Cheat?)
|
||||
{
|
||||
try self.delegate.cheatsViewController(self, didActivateCheat: cheat)
|
||||
self.delegate?.cheatsViewController(self, activateCheat: cheat)
|
||||
|
||||
if let previousCheat = previousCheat
|
||||
{
|
||||
@ -278,14 +264,14 @@ extension CheatsViewController: EditCheatViewControllerDelegate
|
||||
|
||||
guard previousCheat.code != code else { return }
|
||||
|
||||
self.delegate.cheatsViewController(self, didDeactivateCheat: previousCheat)
|
||||
self.delegate?.cheatsViewController(self, deactivateCheat: previousCheat)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, deactivateCheat cheat: Cheat)
|
||||
{
|
||||
self.delegate.cheatsViewController(self, didDeactivateCheat: cheat)
|
||||
self.delegate?.cheatsViewController(self, deactivateCheat: cheat)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,19 +14,12 @@ import Roxas
|
||||
|
||||
protocol EditCheatViewControllerDelegate: class
|
||||
{
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, activateCheat cheat: Cheat, previousCheat: Cheat?) throws
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, activateCheat cheat: Cheat, previousCheat: Cheat?)
|
||||
func editCheatViewController(_ editCheatViewController: EditCheatViewController, deactivateCheat cheat: Cheat)
|
||||
}
|
||||
|
||||
private extension EditCheatViewController
|
||||
{
|
||||
enum ValidationError: ErrorProtocol
|
||||
{
|
||||
case invalidCode
|
||||
case duplicateName
|
||||
case duplicateCode
|
||||
}
|
||||
|
||||
enum Section: Int
|
||||
{
|
||||
case name
|
||||
@ -37,11 +30,18 @@ private extension EditCheatViewController
|
||||
|
||||
class EditCheatViewController: UITableViewController
|
||||
{
|
||||
weak var delegate: EditCheatViewControllerDelegate?
|
||||
var game: Game! {
|
||||
didSet {
|
||||
let deltaCore = Delta.core(for: self.game.type)!
|
||||
self.supportedCheatFormats = deltaCore.emulatorConfiguration.supportedCheatFormats
|
||||
}
|
||||
}
|
||||
|
||||
var cheat: Cheat?
|
||||
var game: Game!
|
||||
var supportedCheatFormats: [CheatFormat]!
|
||||
|
||||
weak var delegate: EditCheatViewControllerDelegate?
|
||||
|
||||
private var supportedCheatFormats: [CheatFormat]!
|
||||
|
||||
private var selectedCheatFormat: CheatFormat {
|
||||
let cheatFormat = self.supportedCheatFormats[self.typeSegmentedControl.selectedSegmentIndex]
|
||||
@ -271,63 +271,51 @@ private extension EditCheatViewController
|
||||
do
|
||||
{
|
||||
try self.validateCheat(self.mutableCheat)
|
||||
|
||||
self.delegate?.editCheatViewController(self, activateCheat: self.mutableCheat, previousCheat: self.cheat)
|
||||
|
||||
self.mutableCheat.managedObjectContext?.saveWithErrorLogging()
|
||||
self.performSegue(withIdentifier: "unwindEditCheatSegue", sender: sender)
|
||||
}
|
||||
catch ValidationError.invalidCode
|
||||
catch CheatValidator.Error.invalidCode
|
||||
{
|
||||
self.presentErrorAlert(title: NSLocalizedString("Invalid Code", comment: ""), message: NSLocalizedString("Please make sure you typed the cheat code in correctly and try again.", comment: "")) {
|
||||
self.codeTextView.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
catch ValidationError.duplicateCode
|
||||
catch CheatValidator.Error.invalidName
|
||||
{
|
||||
self.presentErrorAlert(title: NSLocalizedString("Invalid Name", comment: ""), message: NSLocalizedString("Please rename this cheat and try again.", comment: "")) {
|
||||
self.codeTextView.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
catch CheatValidator.Error.duplicateCode
|
||||
{
|
||||
self.presentErrorAlert(title: NSLocalizedString("Duplicate Code", comment: ""), message: NSLocalizedString("A cheat already exists with this code. Please type in a different code and try again.", comment: "")) {
|
||||
self.codeTextView.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
catch ValidationError.duplicateName
|
||||
catch CheatValidator.Error.duplicateName
|
||||
{
|
||||
self.presentErrorAlert(title: NSLocalizedString("Duplicate Name", comment: ""), message: NSLocalizedString("A cheat already exists with this name. Please rename this cheat and try again.", comment: "")) {
|
||||
self.nameTextField.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
catch let error as NSError
|
||||
catch
|
||||
{
|
||||
print(error)
|
||||
|
||||
self.presentErrorAlert(title: NSLocalizedString("Unknown Error", comment: ""), message: NSLocalizedString("An error occured. Please make sure you typed the cheat code in correctly and try again.", comment: "")) {
|
||||
self.codeTextView.becomeFirstResponder()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func validateCheat(_ cheat: Cheat) throws
|
||||
{
|
||||
let name = cheat.name!
|
||||
let code = cheat.code
|
||||
|
||||
// Find all cheats that are for the same game, don't have the same identifier as the current cheat, but have either the same name or code
|
||||
let predicate = Predicate(format: "%K == %@ AND %K != %@ AND (%K == %@ OR %K == %@)", Cheat.Attributes.game.rawValue, cheat.game, Cheat.Attributes.identifier.rawValue, cheat.identifier, Cheat.Attributes.code.rawValue, code, Cheat.Attributes.name.rawValue, name)
|
||||
|
||||
let cheats = Cheat.instancesWithPredicate(predicate, inManagedObjectContext: self.managedObjectContext, type: Cheat.self)
|
||||
for cheat in cheats
|
||||
{
|
||||
if cheat.name == name
|
||||
{
|
||||
throw ValidationError.duplicateName
|
||||
}
|
||||
else if cheat.code == code
|
||||
{
|
||||
throw ValidationError.duplicateCode
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
try self.delegate?.editCheatViewController(self, activateCheat: cheat, previousCheat: self.cheat)
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw ValidationError.invalidCode
|
||||
}
|
||||
let validator = CheatValidator(format: self.selectedCheatFormat, managedObjectContext: self.managedObjectContext)
|
||||
try validator.validate(cheat)
|
||||
}
|
||||
|
||||
@IBAction func textFieldDidEndEditing(_ sender: UITextField)
|
||||
|
||||
@ -32,10 +32,12 @@ class PauseViewController: UIViewController, PauseInfoProviding
|
||||
/// PauseInfoProviding
|
||||
var pauseText: String?
|
||||
|
||||
/// Cheats
|
||||
weak var cheatsViewControllerDelegate: CheatsViewControllerDelegate?
|
||||
|
||||
/// Save States
|
||||
weak var saveStatesViewControllerDelegate: SaveStatesViewControllerDelegate?
|
||||
|
||||
// Hopefully this can be removed once SE-0116 is implemented
|
||||
private var saveStatesViewControllerMode = SaveStatesViewController.Mode.loading
|
||||
|
||||
private var pauseNavigationController: UINavigationController!
|
||||
@ -104,7 +106,12 @@ extension PauseViewController
|
||||
saveStatesViewController.game = self.emulatorCore?.game as? Game
|
||||
saveStatesViewController.emulatorCore = self.emulatorCore
|
||||
saveStatesViewController.mode = self.saveStatesViewControllerMode
|
||||
|
||||
|
||||
case "cheats":
|
||||
let cheatsViewController = segue.destinationViewController as! CheatsViewController
|
||||
cheatsViewController.delegate = self.cheatsViewControllerDelegate
|
||||
cheatsViewController.game = self.emulatorCore?.game as? Game
|
||||
|
||||
default: break
|
||||
}
|
||||
}
|
||||
@ -150,7 +157,10 @@ private extension PauseViewController
|
||||
self.performSegue(withIdentifier: "saveStates", sender: self)
|
||||
})
|
||||
|
||||
self.cheatCodesItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Cheat Codes", comment: ""), action: { _ in })
|
||||
self.cheatCodesItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Cheat Codes", comment: ""), action: { [unowned self] _ in
|
||||
self.performSegue(withIdentifier: "cheats", sender: self)
|
||||
})
|
||||
|
||||
self.sustainButtonsItem = PauseItem(image: UIImage(named: "SmallPause")!, text: NSLocalizedString("Sustain Buttons", comment: ""), action: { _ in })
|
||||
self.fastForwardItem = PauseItem(image: UIImage(named: "FastForward")!, text: NSLocalizedString("Fast Forward", comment: ""), action: { _ in })
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user