From 3ef88e1033fb20148e9b347837cc64bb60daa94c Mon Sep 17 00:00:00 2001 From: Ladislas de Toldi Date: Mon, 13 Nov 2023 14:37:20 +0100 Subject: [PATCH 1/2] :recycle: (ContentKit): Move Action to Exercise (instead of payload) --- .../activities/activity-colorBingo.yml | 60 +++++++++---------- ...y-listenThenTouchToSelect-mixed-images.yml | 60 +++++++++---------- .../activities/activity-medley.yml | 30 +++++----- ...-observeThenTouchToSelect-mixed-colors.yml | 60 +++++++++---------- .../Sources/Exercise/Exercise+Payload.swift | 7 ++- .../Exercise/Exercise+TouchSelection.swift | 1 - .../Sources/Exercise/Exercise.swift | 1 + .../ListenThenTouchToSelectView.swift | 9 ++- .../ObserveThenTouchToSelect.swift | 9 ++- .../RobotThenTouchToSelectView.swift | 7 ++- 10 files changed, 128 insertions(+), 116 deletions(-) diff --git a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-colorBingo.yml b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-colorBingo.yml index ab32edb374..5534cdb283 100644 --- a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-colorBingo.yml +++ b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-colorBingo.yml @@ -12,12 +12,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: blue payload: - action: - type: robot - value: - type: color - value: blue choices: - value: blue type: color @@ -27,12 +27,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: green payload: - action: - type: robot - value: - type: color - value: green choices: - value: green type: color @@ -44,12 +44,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: red payload: - action: - type: robot - value: - type: color - value: red choices: - value: red type: color @@ -63,12 +63,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: yellow payload: - action: - type: robot - value: - type: color - value: yellow choices: - value: yellow type: color @@ -84,12 +84,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: orange payload: - action: - type: robot - value: - type: color - value: orange choices: - value: orange type: color @@ -107,12 +107,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: yellow payload: - action: - type: robot - value: - type: color - value: yellow choices: - value: purple type: color diff --git a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-listenThenTouchToSelect-mixed-images.yml b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-listenThenTouchToSelect-mixed-images.yml index 49034bd2e2..65b90bd544 100644 --- a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-listenThenTouchToSelect-mixed-images.yml +++ b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-listenThenTouchToSelect-mixed-images.yml @@ -12,12 +12,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: guitar payload: - action: - type: ipad - value: - type: audio - value: guitar choices: - value: image-instrument-guitar-no_background type: image @@ -27,12 +27,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: violin payload: - action: - type: ipad - value: - type: audio - value: violin choices: - value: image-instrument-violin-no_background type: image @@ -44,12 +44,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: saxophone payload: - action: - type: ipad - value: - type: audio - value: saxophone choices: - value: image-instrument-saxophone-no_background type: image @@ -64,12 +64,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: piano payload: - action: - type: ipad - value: - type: audio - value: piano choices: - value: image-instrument-harmonica-no_background type: image @@ -85,12 +85,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: flute payload: - action: - type: ipad - value: - type: audio - value: flute choices: - value: image-instrument-violin-no_background type: image @@ -110,12 +110,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: drums payload: - action: - type: ipad - value: - type: audio - value: drums choices: - value: image-instrument-drums-no_background type: image diff --git a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-medley.yml b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-medley.yml index eb8f193ec6..6a07148de4 100644 --- a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-medley.yml +++ b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-medley.yml @@ -12,12 +12,12 @@ sequence: category: selection interface: listenThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: audio + value: violin payload: - action: - type: ipad - value: - type: audio - value: violin choices: - value: image-instrument-violin-no_background type: image @@ -60,12 +60,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-red payload: - action: - type: ipad - value: - type: image - value: image-landscape-red choices: - value: yellow type: color @@ -85,12 +85,12 @@ sequence: category: selection interface: robotThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: robot + value: + type: color + value: orange payload: - action: - type: robot - value: - type: color - value: orange choices: - value: orange type: color diff --git a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-observeThenTouchToSelect-mixed-colors.yml b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-observeThenTouchToSelect-mixed-colors.yml index 6180f1ea7e..bba94c2440 100644 --- a/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-observeThenTouchToSelect-mixed-colors.yml +++ b/Apps/LekaActivityUIExplorer/Resources/GEKNewSystem/activities/activity-observeThenTouchToSelect-mixed-colors.yml @@ -12,12 +12,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-blue payload: - action: - type: ipad - value: - type: image - value: image-landscape-blue choices: - value: blue type: color @@ -27,12 +27,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-red payload: - action: - type: ipad - value: - type: image - value: image-landscape-red choices: - value: blue type: color @@ -44,12 +44,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-purple payload: - action: - type: ipad - value: - type: image - value: image-landscape-purple choices: - value: purple type: color @@ -64,12 +64,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-yellow payload: - action: - type: ipad - value: - type: image - value: image-landscape-yellow choices: - value: blue type: color @@ -85,12 +85,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-green payload: - action: - type: ipad - value: - type: image - value: image-landscape-green choices: - value: yellow type: color @@ -110,12 +110,12 @@ sequence: category: selection interface: observeThenTouchToSelect gameplay: selectAllRightAnswers + action: + type: ipad + value: + type: image + value: image-landscape-red payload: - action: - type: ipad - value: - type: image - value: image-landscape-red choices: - value: yellow type: color diff --git a/Modules/ContentKit/Sources/Exercise/Exercise+Payload.swift b/Modules/ContentKit/Sources/Exercise/Exercise+Payload.swift index 7bb2788c20..28d92bed97 100644 --- a/Modules/ContentKit/Sources/Exercise/Exercise+Payload.swift +++ b/Modules/ContentKit/Sources/Exercise/Exercise+Payload.swift @@ -4,6 +4,8 @@ import Foundation +// swiftlint:disable nesting + extension Exercise { public enum Payload: Codable { @@ -28,11 +30,10 @@ extension Exercise { // ? Selection if container.allKeys.contains(.choices) { let choices = try container.decode([TouchSelection.Choice].self, forKey: .choices) - let action = try? container.decode(Exercise.Action.self, forKey: .action) let shuffleChoices = try container.decodeIfPresent(Bool.self, forKey: .shuffleChoices) ?? false self = .selection( - TouchSelection.Payload(choices: choices, action: action, shuffleChoices: shuffleChoices)) + TouchSelection.Payload(choices: choices, shuffleChoices: shuffleChoices)) return } @@ -59,3 +60,5 @@ extension Exercise { } } + +// swiftlint:enable nesting diff --git a/Modules/ContentKit/Sources/Exercise/Exercise+TouchSelection.swift b/Modules/ContentKit/Sources/Exercise/Exercise+TouchSelection.swift index 28a8a67632..3cf0560e61 100644 --- a/Modules/ContentKit/Sources/Exercise/Exercise+TouchSelection.swift +++ b/Modules/ContentKit/Sources/Exercise/Exercise+TouchSelection.swift @@ -31,7 +31,6 @@ public enum TouchSelection { public struct Payload: Codable { public let choices: [Choice] - public let action: Exercise.Action? // TODO(@ladislas): remove action from here public let shuffleChoices: Bool } diff --git a/Modules/ContentKit/Sources/Exercise/Exercise.swift b/Modules/ContentKit/Sources/Exercise/Exercise.swift index d580e66070..25a855814d 100644 --- a/Modules/ContentKit/Sources/Exercise/Exercise.swift +++ b/Modules/ContentKit/Sources/Exercise/Exercise.swift @@ -10,6 +10,7 @@ public struct Exercise: Codable { public let category: Category public let interface: Interface public let gameplay: Gameplay + public let action: Action? public let payload: Payload } diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift index 2748e0c492..379dbf2d75 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift @@ -27,10 +27,13 @@ public struct ListenThenTouchToSelectView: View { public init(exercise: Exercise, data: ExerciseSharedData? = nil) { guard case .selection(let payload) = exercise.payload else { - fatalError("Exercise payload is not .selection") + log.error("Exercise payload is not .selection") + fatalError("💥 Exercise payload is not .selection") } - guard case .ipad(type: .audio(name: let name)) = payload.action else { - fatalError("Exercise payload has no iPad audio action") + + guard case .ipad(type: .audio(name: let name)) = exercise.action else { + log.error("Exercise payload has no iPad audio action") + fatalError("💥 Exercise payload has no iPad audio action") } let audioRecording = AudioRecordingModel(name: name, file: name) diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift index 7225cdbd1d..d23ef65c47 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift @@ -30,10 +30,13 @@ public struct ObserveThenTouchToSelectView: View { public init(exercise: Exercise, data: ExerciseSharedData? = nil) { guard case .selection(let payload) = exercise.payload else { - fatalError("Exercise payload is not .selection") + log.error("Exercise payload is not .selection") + fatalError("💥 Exercise payload is not .selection") } - guard case .ipad(type: .image(name: let name)) = payload.action else { - fatalError("Exercise payload does not contain an iPad image action") + + guard case .ipad(type: .image(name: let name)) = exercise.action else { + log.error("Exercise payload does not contain an iPad image action") + fatalError("💥 Exercise payload does not contain an iPad image action") } self.image = name diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift index 0b739fbaae..7a579f0cf1 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift @@ -34,10 +34,13 @@ public struct RobotThenTouchToSelectView: View { public init(exercise: Exercise, data: ExerciseSharedData? = nil) { guard case .selection(let payload) = exercise.payload else { + log.error("Exercise payload is not .selection") fatalError("💥 Exercise payload is not .selection") } - guard case .robot(let robotMedia) = payload.action else { - fatalError("💥 Exercise payload does not contain an robot action") + + guard case .robot(let robotMedia) = exercise.action else { + log.error("Exercise does not contain an robot action") + fatalError("💥 Exercise does not contain an robot action") } self.robot.blacken(.all) From 8cf77e7c5d01e23d6886536e5ae74c45a85b7ba0 Mon Sep 17 00:00:00 2001 From: Ladislas de Toldi Date: Mon, 13 Nov 2023 17:38:24 +0100 Subject: [PATCH 2/2] :recycle: (GEK): Action - refactor init(...) for Listen, Observe, Robot --- .../ListenThenTouchToSelectView.swift | 19 +++++++---------- .../ObserveThenTouchToSelect.swift | 18 +++++++--------- .../RobotThenTouchToSelectView.swift | 21 +++++++++---------- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift index 379dbf2d75..e3f2e0c4d5 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/ListenThenTouchToSelect/ListenThenTouchToSelectView.swift @@ -26,22 +26,19 @@ public struct ListenThenTouchToSelectView: View { } public init(exercise: Exercise, data: ExerciseSharedData? = nil) { - guard case .selection(let payload) = exercise.payload else { - log.error("Exercise payload is not .selection") - fatalError("💥 Exercise payload is not .selection") + guard + case .selection(let payload) = exercise.payload, + case .ipad(type: .audio(let name)) = exercise.action + else { + log.error("Exercise payload is not .selection and/or Exercise does not contain iPad audio action") + fatalError("💥 Exercise payload is not .selection and/or Exercise does not contain iPad audio action") } - guard case .ipad(type: .audio(name: let name)) = exercise.action else { - log.error("Exercise payload has no iPad audio action") - fatalError("💥 Exercise payload has no iPad audio action") - } + self._viewModel = StateObject( + wrappedValue: SelectionViewViewModel(choices: payload.choices, shared: data)) let audioRecording = AudioRecordingModel(name: name, file: name) self._audioPlayer = StateObject(wrappedValue: AudioPlayer(audioRecording: audioRecording)) - - self._viewModel = StateObject(wrappedValue: SelectionViewViewModel(choices: payload.choices)) - self._viewModel = StateObject( - wrappedValue: SelectionViewViewModel(choices: payload.choices, shared: data)) } public var body: some View { diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift index d23ef65c47..3c18d98f1d 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/ObserveThenTouchToSelect/ObserveThenTouchToSelect.swift @@ -29,20 +29,18 @@ public struct ObserveThenTouchToSelectView: View { } public init(exercise: Exercise, data: ExerciseSharedData? = nil) { - guard case .selection(let payload) = exercise.payload else { - log.error("Exercise payload is not .selection") - fatalError("💥 Exercise payload is not .selection") + guard + case .selection(let payload) = exercise.payload, + case .ipad(type: .image(let name)) = exercise.action + else { + log.error("Exercise payload is not .selection and/or Exercise does not contain iPad image action") + fatalError("💥 Exercise payload is not .selection and/or Exercise does not contain iPad image action") } - guard case .ipad(type: .image(name: let name)) = exercise.action else { - log.error("Exercise payload does not contain an iPad image action") - fatalError("💥 Exercise payload does not contain an iPad image action") - } - - self.image = name - self._viewModel = StateObject( wrappedValue: SelectionViewViewModel(choices: payload.choices, shared: data)) + + self.image = name } public var body: some View { diff --git a/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift b/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift index 7a579f0cf1..0627cb95d3 100644 --- a/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift +++ b/Modules/GameEngineKit/Sources/_NewSystem/Views/RobotThenTouchToSelect/RobotThenTouchToSelectView.swift @@ -33,21 +33,20 @@ public struct RobotThenTouchToSelectView: View { } public init(exercise: Exercise, data: ExerciseSharedData? = nil) { - guard case .selection(let payload) = exercise.payload else { - log.error("Exercise payload is not .selection") - fatalError("💥 Exercise payload is not .selection") + guard + case .selection(let payload) = exercise.payload, + case .robot(let actionType) = exercise.action + else { + log.error("Exercise payload is not .selection and/or Exercise does not contain robot action") + fatalError("💥 Exercise payload is not .selection and/or Exercise does not contain robot action") } - guard case .robot(let robotMedia) = exercise.action else { - log.error("Exercise does not contain an robot action") - fatalError("💥 Exercise does not contain an robot action") - } - - self.robot.blacken(.all) - self.actionType = robotMedia - self._viewModel = StateObject( wrappedValue: SelectionViewViewModel(choices: payload.choices, shared: data)) + + self.actionType = actionType + + self.robot.blacken(.all) } public var body: some View {