Skip to content

Commit

Permalink
WIP - adding serial blink
Browse files Browse the repository at this point in the history
  • Loading branch information
ladislas committed Feb 6, 2024
1 parent 7cf489a commit ce1f913
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct RobotKitExperimentView: View {
.motion(.stop, duration: .seconds(3), parallel: [
// .lights(.full(.belt, in: .red), duration: .seconds(3)),
]),
.blink(.seconds(0.2), duration: .seconds(5), parallel: []),
// .motion(.spin(.counterclockwise, speed: 0.8), duration: .seconds(4), parallel: [
// .blink(.seconds(0.2), duration: .seconds(2), parallel: []),
// ]),
Expand All @@ -29,7 +30,7 @@ struct RobotKitExperimentView: View {
.tint(.green)

Button("STOP", systemImage: "stop.circle.fill") {
self.robotkit.stop()
self.robotkit.cancel()
}
.buttonStyle(.bordered)
.tint(.red)
Expand Down
102 changes: 16 additions & 86 deletions Modules/RobotKit/Sources/RobotKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,120 +13,50 @@ public class RobotKit {

public static var shared: RobotKit = .init()

// public func append(actions: RobotAction...) {
// for action in actions {
// self.actions.append(action.object)
// }
// }

public func append(actions: [RobotAction]) {
self.actions = actions
}

// public func execute() {
// for action in self.actions {
// action.execute()
// }
// }

public func executeSync() {
guard self.task == nil else {
log.trace("Task already running, ignoring new execution")
return
}

// for action in self.actions {
// log.debug("execute action \(action)")
// await action.object.execute()
// log.debug("execute action \(action) ✅")
// }
self.task = Task {
for action in self.actions {
guard self.task?.isCancelled == false else {
log.debug("Task cancelled, stopping robot kit")
// action.object.stop()
return
}

self.currentAction = action
log.debug("execute action \(action)")
async let _ = action.object.execute()
// async let currentTask: () = action.object.execute()
// await currentTask
try await action.object.execute()
// async let _ = action.object.execute()
log.debug("execute action \(action)")
}
self.stop()
self.terminate()
}

// self.task = Task {
// for action in self.actions {
// guard self.task?.isCancelled == false else {
// log.debug("Task cancelled, stopping robot kit")
//// action.object.stop()
// return
// }
// self.currentAction = action
// log.debug("execute action \(action)")
// await action.object.execute()
//// async let currentTask: () = action.object.execute()
//// await currentTask
// log.debug("execute action \(action) ✅")
// }
// self.stop()
// }
}

// public func executeSync() {
// guard self.task == nil else {
// log.trace("Task already running, ignoring new execution")
// return
// }
//
// self.task = Task {
// for action in self.actions {
// guard self.task?.isCancelled == false else { return }
// guard let action = action.object else {
// self.stop()
// return
// }
//
// action.execute()
//
// action.parallelActions.forEach {
// guard let action = $0.object else { return }
// action.execute()
// }
//
// try? await Task.sleep(for: action.duration)
//
// action.stop()
// action.parallelActions.forEach {
// guard let action = $0.object else { return }
// action.stop()
// }
// }
// }
// }

public func stop() {
log.debug("stop robot kit")
// self.actions[self.currentActionIndex].object.stop()
public func cancel() {
log.debug("cancel sequence")

self.currentAction?.object.cancel()
self.task?.cancel()
// self.currentAction?.object.cancel()
self.task = nil

self.currentAction = nil
self.task = nil

// for action in self.actions {
// action.object.stop()
// if let parallelActions = action.object.parallelActions {
// for parallelAction in parallelActions {
// parallelAction.object.stop()
// }
// }
// }
self.actions = []
self.terminate()
}

public func terminate() {
log.debug("terminate sequence")
self.task?.cancel()
self.task = nil
self.actions = []
self.robot.stop()
}

Expand All @@ -136,5 +66,5 @@ public class RobotKit {

private var actions: [RobotAction] = []
private var currentAction: RobotAction?
private var task: Task<Void, Never>?
private var task: Task<Void, Error>?
}
97 changes: 59 additions & 38 deletions Modules/RobotKit/Sources/RobotKit/ActionBlink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,69 @@

import Foundation

//
// final class ActionBlink: RobotActionProtocol {
// // MARK: Lifecycle
//
// init(delay: Duration, duration: Duration, and parallelActions: [RobotAction] = []) {
// self.delay = delay
// self.duration = duration
// self.parallelActions = parallelActions
// }
//
// // MARK: Internal
//
// var delay: Duration
// var duration: Duration
// var parallelActions: [RobotAction]
//
// var isRunning: Bool = false
//
// func execute() {
// self.isRunning = true
final class ActionBlink: RobotActionProtocol {
// MARK: Lifecycle

init(delay: Duration, duration: Duration, and parallelActions: [RobotAction] = []) {
self.delay = delay
self.duration = duration
self.parallelActions = parallelActions

self.task = Task {
repeat {
guard self.task?.isCancelled == false else { return }
self.robot.shine(.all(in: .white))
try await Task.sleep(for: self.delay)
self.robot.shine(.all(in: .black))
try await Task.sleep(for: self.delay)
try Task.checkCancellation()
} while !Task.isCancelled && self.isRunning
}
}

// MARK: Internal

var delay: Duration
var duration: Duration
var parallelActions: [RobotAction]

var isRunning: Bool = false

func execute() async throws {
self.isRunning = true
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(Int(self.duration.components.seconds))) {
log.debug("toggle is running to false")
self.isRunning = false
}
// Task {
// // TODO: (@ladislas) NOT WORKING - count number of steps first
// repeat {
// guard self.task?.isCancelled == false else { return }
// self.robot.shine(.all(in: .white))
// try? await Task.sleep(for: self.delay)
// try await Task.sleep(for: self.delay)
// self.robot.shine(.all(in: .black))
// try? await Task.sleep(for: self.delay)
// try await Task.sleep(for: self.delay)
// try Task.checkCancellation()
// } while !Task.isCancelled && self.isRunning
// }
// }
//
// func stop() {
// log.debug("stop action blink")
// self.isRunning = false
// self.task?.cancel()
// self.task = nil
// }
//
// // MARK: Private
//
// private var task: Task<Void, Never>?
//
// private var robot = Robot.shared
// }

async let _ = self.task?.result
}

func end() {
log.debug("blink - END")
self.robot.stopLights()
}

func cancel() {
self.isRunning = false
self.task?.cancel()
self.task = nil
self.end()
}

// MARK: Private

private var task: Task<Void, Error>?

private var robot = Robot.shared
}
14 changes: 3 additions & 11 deletions Modules/RobotKit/Sources/RobotKit/ActionMotion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,7 @@ final class ActionMotion: RobotActionProtocol {
}
log.debug("motion - start task - move")
self.robot.move(self.motion)
do {
log.debug("motion - run task - sleep")
try await Task.sleep(for: self.duration)
log.debug("motion - run task - sleep done")
} catch {
log.debug("error \(error)")
self.cancel()
return
}
try await Task.sleep(for: self.duration)
log.debug("motion - end task")
}
}
Expand All @@ -42,7 +34,7 @@ final class ActionMotion: RobotActionProtocol {
self.task?.isCancelled == false
}

func execute() async {
func execute() async throws {
// log.debug("motion - before task")

// self.task = Task {
Expand Down Expand Up @@ -82,5 +74,5 @@ final class ActionMotion: RobotActionProtocol {
// MARK: Private

private let robot = Robot.shared
private var task: Task<Void, Never>?
private var task: Task<Void, any Error>?
}
6 changes: 3 additions & 3 deletions Modules/RobotKit/Sources/RobotKit/RobotAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Foundation
public enum RobotAction {
case motion(Robot.Motion, duration: Duration, parallel: [RobotAction] = [])
// case lights(Robot.Lights, duration: Duration, parallel: [RobotAction] = [])
// case blink(Duration, duration: Duration, parallel: [RobotAction] = [])
case blink(Duration, duration: Duration, parallel: [RobotAction] = [])
// case pause(duration: Duration)

// MARK: Public
Expand All @@ -18,8 +18,8 @@ public enum RobotAction {
ActionMotion(motion, duration: duration, and: parallel)
// case let .lights(lights, duration, parallel):
// ActionLights(lights, duration: duration, and: parallel)
// case let .blink(delay, duration, parallel):
// ActionBlink(delay: delay, duration: duration, and: parallel)
case let .blink(delay, duration, parallel):
ActionBlink(delay: delay, duration: duration, and: parallel)
// case let .pause(duration):
// ActionStop(duration: duration)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public protocol RobotActionProtocol {
var duration: Duration { get }
var parallelActions: [RobotAction] { get }

func execute() async
func execute() async throws
func end()
func cancel()
}

0 comments on commit ce1f913

Please sign in to comment.