diff --git a/core/build.gradle b/core/build.gradle index 98752e2..fdbc823 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -3,7 +3,7 @@ check.dependsOn 'ktlint' dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile 'com.android.support:support-annotations:27.0.2' + implementation 'com.android.support:support-annotations:27.0.2' compile 'edu.wpi.first.wpilibj:wpilibj-java:2018.1.1' compileOnly 'openrio.mirror.third.ctre:CTRE-phoenix-java:5.1.2.1' compileOnly 'jaci.pathfinder:Pathfinder-Java:1.8' diff --git a/core/src/main/kotlin/org/sertain/Robot.kt b/core/src/main/kotlin/org/sertain/Robot.kt index 565cf37..aacddc5 100644 --- a/core/src/main/kotlin/org/sertain/Robot.kt +++ b/core/src/main/kotlin/org/sertain/Robot.kt @@ -28,18 +28,18 @@ public interface RobotLifecycle { */ public fun onStart() = Unit - /** - * Indicates that the robot is being enabled in the teleoperated mode. This method will be - * called before the robot becomes enabled in teleoperated mode. - */ - public fun onTeleopStart() = Unit - /** * Indicates that the robot is being enabled in the autonomous mode. This method will be called * before the robot becomes enabled in autonomous mode. */ public fun onAutoStart() = Unit + /** + * Indicates that the robot is being enabled in the teleoperated mode. This method will be + * called before the robot becomes enabled in teleoperated mode. + */ + public fun onTeleopStart() = Unit + /** * Runs periodically (default = every 20ms) while the robot is turned on. It need not be enabled * for this method to be called. @@ -73,12 +73,6 @@ public interface RobotLifecycle { */ public fun onAutoStop() = Unit - /** - * Indicates that the disabled state has just terminated. This method will be called after the - * disabled state has terminated. This method should be equivalent to [onStart]. - */ - public fun onDisabledStop() = Unit - /** * Indicates that the robot has become disabled. This method will be called upon entering the * disabled state. @@ -86,6 +80,7 @@ public interface RobotLifecycle { public fun onStop() = Unit companion object { + internal var state = Robot.State.DISABLED @VisibleForTesting internal val listeners = mutableSetOf() @@ -95,6 +90,13 @@ public interface RobotLifecycle { * @param lifecycle the lifecycle object to receive callbacks */ public fun addListener(lifecycle: RobotLifecycle) { + lifecycle.onCreate() + when (state) { + Robot.State.TELEOP -> lifecycle.onTeleopStart() + Robot.State.AUTO -> lifecycle.onAutoStart() + Robot.State.DISABLED -> Unit + } + synchronized(listeners) { listeners += lifecycle } } @@ -112,9 +114,9 @@ public interface RobotLifecycle { override fun onStart() = notify { onStart() } - override fun onTeleopStart() = notify { onTeleopStart() } + override fun onTeleopStart() = notify(Robot.State.TELEOP) { onTeleopStart() } - override fun onAutoStart() = notify { onAutoStart() } + override fun onAutoStart() = notify(Robot.State.AUTO) { onAutoStart() } override fun execute() = notify { execute() } @@ -128,11 +130,13 @@ public interface RobotLifecycle { override fun onAutoStop() = notify { onAutoStop() } - override fun onDisabledStop() = notify { onDisabledStop() } - - override fun onStop() = notify { onStop() } + override fun onStop() = notify(Robot.State.DISABLED) { onStop() } - private inline fun notify(block: RobotLifecycle.() -> Unit) { + private inline fun notify( + state: Robot.State? = null, + block: RobotLifecycle.() -> Unit + ) { + state?.let { RobotLifecycle.state = it } synchronized(listeners) { for (listener in listeners) listener.block() } } } @@ -143,13 +147,13 @@ public interface RobotLifecycle { * Base robot class which must be used for [RobotLifecycle] callbacks to work. */ public abstract class Robot : IterativeRobot(), RobotLifecycle { - private var mode = Mode.DISABLED + private var mode = State.DISABLED set(value) { if (value != field) { when (field) { - Mode.TELEOP -> LifecycleDistributor.onTeleopStop() - Mode.AUTO -> LifecycleDistributor.onAutoStop() - Mode.DISABLED -> LifecycleDistributor.onDisabledStop() + State.TELEOP -> LifecycleDistributor.onTeleopStop() + State.AUTO -> LifecycleDistributor.onAutoStop() + State.DISABLED -> Unit } field = value } @@ -168,14 +172,14 @@ public abstract class Robot : IterativeRobot(), RobotLifecycle { } override fun disabledInit() { - mode = Mode.DISABLED + mode = State.DISABLED LifecycleDistributor.onStop() } override fun disabledPeriodic() = LifecycleDistributor.executeDisabled() override fun autonomousInit() { - mode = Mode.AUTO + mode = State.AUTO LifecycleDistributor.onStart() LifecycleDistributor.onAutoStart() } @@ -183,14 +187,14 @@ public abstract class Robot : IterativeRobot(), RobotLifecycle { override fun autonomousPeriodic() = LifecycleDistributor.executeAuto() override fun teleopInit() { - mode = Mode.TELEOP + mode = State.TELEOP LifecycleDistributor.onStart() LifecycleDistributor.onTeleopStart() } override fun teleopPeriodic() = LifecycleDistributor.executeTeleop() - private enum class Mode { - AUTO, TELEOP, DISABLED + internal enum class State { + DISABLED, AUTO, TELEOP } } diff --git a/core/src/main/kotlin/org/sertain/command/Subsystem.kt b/core/src/main/kotlin/org/sertain/command/Subsystem.kt index a6fc290..b45669c 100644 --- a/core/src/main/kotlin/org/sertain/command/Subsystem.kt +++ b/core/src/main/kotlin/org/sertain/command/Subsystem.kt @@ -10,8 +10,12 @@ private typealias WpiLibSubsystem = edu.wpi.first.wpilibj.command.Subsystem * @see edu.wpi.first.wpilibj.command.Subsystem */ public abstract class Subsystem : WpiLibSubsystem(), RobotLifecycle { + abstract val defaultCommand: Command + override fun initSendable(builder: SendableBuilder?) { super.initSendable(builder) RobotLifecycle.addListener(this) } + + override fun initDefaultCommand() = setDefaultCommand(defaultCommand.mirror) }