Skip to content

Commit 158fdde

Browse files
committed
Add PeriodicRegistry
1 parent 0da91d7 commit 158fdde

4 files changed

Lines changed: 198 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.team2813.lib2813.subsystems;
2+
3+
import com.team2813.lib2813.util.PeriodicRegistry;
4+
import com.team2813.lib2813.util.SimplePeriodicRegistry;
5+
import edu.wpi.first.wpilibj2.command.CommandScheduler;
6+
import edu.wpi.first.wpilibj2.command.SubsystemBase;
7+
8+
/**
9+
* A base for subsystems that has APIs to support modular code.
10+
*
11+
* <p>Provides access to {@link PeriodicRegistry}, which can be passed to reusable components.
12+
*/
13+
public abstract class ModularSubsystem extends SubsystemBase {
14+
private final SimplePeriodicRegistry periodicRegistry = new SimplePeriodicRegistry();
15+
16+
/** Constructor. Telemetry/log name defaults to the classname. */
17+
public ModularSubsystem() {
18+
super();
19+
}
20+
21+
/**
22+
* Constructor.
23+
*
24+
* @param name Name of the subsystem for telemetry and logging.
25+
*/
26+
protected ModularSubsystem(String name) {
27+
super(name);
28+
}
29+
30+
/**
31+
* Gets a periodic registry for registering functions to periodically be called by this subsystem.
32+
*/
33+
protected final PeriodicRegistry getPeriodicRegistry() {
34+
return periodicRegistry;
35+
}
36+
37+
/**
38+
* Called periodically by the {@link CommandScheduler}.
39+
*
40+
* <p>This is intentionally marked as final; subclasses should use {@link #getPeriodicRegistry()}.
41+
*/
42+
@Override
43+
public final void periodic() {
44+
periodicRegistry.callPeriodicFunctions();
45+
}
46+
47+
/**
48+
* Called periodically by the {@link CommandScheduler} when in simulation mode.
49+
*
50+
* <p>This is intentionally marked as final; subclasses should use {@link #getPeriodicRegistry()}.
51+
*/
52+
@Override
53+
public final void simulationPeriodic() {
54+
periodicRegistry.callSimulationPeriodicFunctions();
55+
}
56+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.team2813.lib2813.util;
2+
3+
import java.util.function.Consumer;
4+
5+
/**
6+
* Service for registering callbacks that need to run periodically.
7+
*
8+
* <p>>Subsystems can extend {@link com.team2813.lib2813.subsystems.ModularSubsystem} to get access
9+
* to an instance of {@link PeriodicRegistry}. This will ensure that time spent in the periodic
10+
* methods are associated with the subsystem.
11+
*/
12+
public interface PeriodicRegistry {
13+
14+
/**
15+
* Add a callback to run for each iteration of the event loop.
16+
*
17+
* @param callback The callback to run.
18+
*/
19+
void addPeriodic(Consumer<RobotState> callback);
20+
21+
/**
22+
* Add a callback to run in simulation mode for each iteration of the event loop.
23+
*
24+
* @param callback The callback to run.
25+
*/
26+
void addSimulationPeriodic(Consumer<RobotState> callback);
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.team2813.lib2813.util;
2+
3+
/** Provides APIs for getting the current state of the robot. */
4+
public interface RobotState {
5+
6+
/**
7+
* Determines if the Robot is currently enabled.
8+
*
9+
* @return {@code True} if the Robot is currently enabled by the Driver Station.
10+
*/
11+
boolean isEnabled();
12+
13+
/**
14+
* Determines if the Robot is currently disabled.
15+
*
16+
* @return {@code True} if the Robot is currently disabled by the Driver Station.
17+
*/
18+
default boolean isDisabled() {
19+
return !isEnabled();
20+
}
21+
22+
/**
23+
* Determines if the robot is currently in Autonomous mode as determined by the Driver Station.
24+
*
25+
* @return {@code True} if the robot is currently operating autonomously.
26+
*/
27+
boolean isAutonomous();
28+
29+
/**
30+
* Determine sif the robot is currently in Test mode as determined by the Driver Station.
31+
*
32+
* @return {@code True} if the robot is currently operating in Test mode.
33+
*/
34+
boolean isTest();
35+
36+
/**
37+
* Determine if the robot is currently in Operator Control mode as determined by the Driver
38+
* Station.
39+
*
40+
* @return {@code True} if the robot is currently operating in Operator Control mode.
41+
*/
42+
boolean isTeleop();
43+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.team2813.lib2813.util;
2+
3+
import edu.wpi.first.wpilibj.DriverStation;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.function.Consumer;
7+
8+
/**
9+
* {@link PeriodicRegistry} implementation that gets the state from {@link DriverStation}.
10+
*
11+
* <p>Most code should not directly use this class. Subsystems can extend {@link
12+
* com.team2813.lib2813.subsystems.ModularSubsystem} to get access to an instance of {@link
13+
* PeriodicRegistry}.
14+
*
15+
* <p>Alternatively, the main robot code can construct this class, as long as it calls {@link
16+
* #callPeriodicFunctions()} in {@code robotPeriodic()} and {@link
17+
* #callSimulationPeriodicFunctions()} in {@code simulationPeriodic()}.
18+
*/
19+
public final class SimplePeriodicRegistry implements PeriodicRegistry {
20+
private final List<Consumer<RobotState>> periodicFunctions = new ArrayList<>();
21+
private final List<Consumer<RobotState>> simulationPeriodicFunctions = new ArrayList<>();
22+
23+
@Override
24+
public void addPeriodic(Consumer<RobotState> callback) {
25+
periodicFunctions.add(callback);
26+
}
27+
28+
@Override
29+
public void addSimulationPeriodic(Consumer<RobotState> callback) {
30+
simulationPeriodicFunctions.add(callback);
31+
}
32+
33+
/** Calls all the callbacks added via {@link #addPeriodic(Consumer)}. */
34+
public void callPeriodicFunctions() {
35+
RobotState robotState = SimpleRobotState.getInstance();
36+
periodicFunctions.forEach(fun -> fun.accept(robotState));
37+
}
38+
39+
/** Calls all the callbacks added via {@link #addSimulationPeriodic(Consumer)}. */
40+
public void callSimulationPeriodicFunctions() {
41+
RobotState robotState = SimpleRobotState.getInstance();
42+
simulationPeriodicFunctions.forEach(fun -> fun.accept(robotState));
43+
}
44+
45+
private static class SimpleRobotState implements RobotState {
46+
private static final SimpleRobotState INSTANCE = new SimpleRobotState();
47+
48+
static RobotState getInstance() {
49+
return INSTANCE;
50+
}
51+
52+
@Override
53+
public boolean isEnabled() {
54+
return DriverStation.isEnabled();
55+
}
56+
57+
@Override
58+
public boolean isAutonomous() {
59+
return DriverStation.isAutonomous();
60+
}
61+
62+
@Override
63+
public boolean isTest() {
64+
return DriverStation.isTest();
65+
}
66+
67+
@Override
68+
public boolean isTeleop() {
69+
return DriverStation.isTeleop();
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)