Skip to content

Commit 8becf38

Browse files
committed
Add PeriodicRegistry
1 parent d4200c4 commit 8becf38

4 files changed

Lines changed: 258 additions & 0 deletions

File tree

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

0 commit comments

Comments
 (0)