001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package org.wpilib.opmode; 006 007import java.util.Set; 008import org.wpilib.framework.OpModeRobot; 009import org.wpilib.internal.PeriodicPriorityQueue; 010 011/** 012 * Top-level interface for opmode classes. Users should generally extend one of the abstract 013 * implementations of this interface (e.g. {@link PeriodicOpMode}) rather than directly implementing 014 * this interface. 015 * 016 * <p><b>Lifecycle</b>: 017 * 018 * <ul> 019 * <li>constructed when opmode selected on driver station 020 * <li>disabledPeriodic() called periodically as long as DS is disabled. Note this is not called 021 * on a set time interval (it does not use the same time interval as periodic()) 022 * <li>when DS transitions from disabled to enabled, start() is called once 023 * <li>while DS is enabled, periodic() is called periodically at {@link OpModeRobot#getPeriod}, 024 * and additional periodic callbacks added via addPeriodic() are called periodically on their 025 * set time intervals 026 * <li>when DS transitions from enabled to disabled, or a different opmode is selected on the 027 * driver station when the DS is enabled, end() is called, followed by close(); the object is 028 * not reused 029 * <li>if a different opmode is selected on the driver station when the DS is disabled, only 030 * close() is called; the object is not reused 031 * </ul> 032 * 033 * <p>All lifecycle callbacks and periodic callbacks run synchronously on the same thread that 034 * invokes them. Interactions between opmodes and the robot framework do not require additional 035 * synchronization. 036 * 037 * <p>Additional callbacks can be registered by implementing {@link #getCallbacks()} to return a set 038 * of {@link PeriodicPriorityQueue.Callback} objects with custom timing. {@link PeriodicOpMode} 039 * provides a convenient implementation of this method and utility methods for adding periodic 040 * callbacks. 041 */ 042public interface OpMode extends AutoCloseable { 043 /** 044 * This function is called periodically while the opmode is selected and the robot is disabled. 045 * Code that should only run once when the opmode is selected should go in the opmode constructor. 046 */ 047 default void disabledPeriodic() {} 048 049 /** Called once when this opmode transitions to enabled. */ 050 default void start() {} 051 052 /** 053 * This function is called periodically while the opmode is enabled at the rate returned by {@link 054 * OpModeRobot#getPeriod()}. 055 */ 056 default void periodic() {} 057 058 /** 059 * This function is called asynchronously when the robot disables or switches opmodes while this 060 * opmode is enabled. Implementations should stop blocking work promptly. 061 */ 062 default void end() {} 063 064 /** 065 * This function is called when the opmode is no longer selected on the DS or after an enabled run 066 * ends. The object will not be reused after this is called. 067 */ 068 @Override 069 default void close() {} 070 071 /** 072 * Returns a set of custom periodic callbacks to be executed while the opmode is enabled. 073 * 074 * <p>This method allows opmodes to register arbitrary periodic callbacks with custom execution 075 * intervals. The callbacks are executed by the robot framework at their scheduled times, in 076 * addition to the primary {@link #periodic()} callback. 077 * 078 * @return A set of custom callbacks to execute, or an empty set if no custom callbacks are 079 * needed. The default implementation returns an empty set. 080 */ 081 default Set<PeriodicPriorityQueue.Callback> getCallbacks() { 082 return Set.of(); 083 } 084}