diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java index 3b8f9f8fa8..be5c03a10e 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java @@ -186,8 +186,13 @@ public final class Commands { * * @param supplier the command supplier * @return the command + * @deprecated The ProxyCommand supplier constructor has been deprecated in favor of directly + * proxying a {@link DeferredCommand}, see ProxyCommand documentaion for more details. As a + * replacement, consider using `defer(supplier).asProxy()`. * @see ProxyCommand */ + @Deprecated(since = "2025", forRemoval = true) + @SuppressWarnings("removal") public static Command deferredProxy(Supplier supplier) { return new ProxyCommand(supplier); } diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ProxyCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ProxyCommand.java index f71c10b233..7225dee1a9 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ProxyCommand.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ProxyCommand.java @@ -31,8 +31,14 @@ public class ProxyCommand extends Command { * only initialization time command construction is needed, use {@link DeferredCommand} instead. * * @param supplier the command supplier + * @deprecated This constructor's similarity to {@link DeferredCommand} is confusing and opens + * potential footguns for users who do not fully understand the semantics and implications of + * proxying, but who simply want runtime construction. Users who do know what they are doing + * and need a supplier-constructed proxied command should instead proxy a DeferredCommand + * using the asProxy decorator. * @see DeferredCommand */ + @Deprecated(since = "2025", forRemoval = true) public ProxyCommand(Supplier supplier) { m_supplier = requireNonNullParam(supplier, "supplier", "ProxyCommand"); } @@ -45,8 +51,9 @@ public class ProxyCommand extends Command { */ @SuppressWarnings("this-escape") public ProxyCommand(Command command) { - this(() -> command); - setName("Proxy(" + command.getName() + ")"); + Command nullCheckedCommand = requireNonNullParam(command, "command", "ProxyCommand"); + m_supplier = () -> nullCheckedCommand; + setName("Proxy(" + nullCheckedCommand.getName() + ")"); } @Override diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp index 31a4b1fe1c..2e698425bb 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp @@ -4,6 +4,8 @@ #include "frc2/command/Commands.h" +#include + #include "frc2/command/ConditionalCommand.h" #include "frc2/command/DeferredCommand.h" #include "frc2/command/FunctionalCommand.h" @@ -60,6 +62,7 @@ CommandPtr cmd::Print(std::string_view msg) { return PrintCommand(msg).ToPtr(); } +WPI_IGNORE_DEPRECATED CommandPtr cmd::DeferredProxy(wpi::unique_function supplier) { return ProxyCommand(std::move(supplier)).ToPtr(); } @@ -67,6 +70,7 @@ CommandPtr cmd::DeferredProxy(wpi::unique_function supplier) { CommandPtr cmd::DeferredProxy(wpi::unique_function supplier) { return ProxyCommand(std::move(supplier)).ToPtr(); } +WPI_UNIGNORE_DEPRECATED CommandPtr cmd::Wait(units::second_t duration) { return WaitCommand(duration).ToPtr(); diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/ProxyCommand.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/ProxyCommand.cpp index 3851afa53c..9f903845ee 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/ProxyCommand.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/ProxyCommand.cpp @@ -5,10 +5,12 @@ #include "frc2/command/ProxyCommand.h" #include +#include #include using namespace frc2; +WPI_IGNORE_DEPRECATED ProxyCommand::ProxyCommand(wpi::unique_function supplier) : m_supplier(std::move(supplier)) {} @@ -18,9 +20,10 @@ ProxyCommand::ProxyCommand(wpi::unique_function supplier) holder = supplier(); return holder->get(); }) {} +WPI_UNIGNORE_DEPRECATED ProxyCommand::ProxyCommand(Command* command) - : ProxyCommand([command] { return command; }) { + : m_supplier([command] { return command; }) { SetName(fmt::format("Proxy({})", command->GetName())); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h index 5c1d49a257..0124d0ae3f 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h @@ -12,6 +12,8 @@ #include #include +#include + #include "frc2/command/CommandPtr.h" #include "frc2/command/Requirements.h" #include "frc2/command/SelectCommand.h" @@ -155,11 +157,15 @@ CommandPtr Defer(wpi::unique_function supplier, /** * Constructs a command that schedules the command returned from the supplier * when initialized, and ends when it is no longer scheduled. The supplier is - * called when the command is initialized. + * called when the command is initialized. As a replacement, consider using + * `Defer(supplier).AsProxy()`. * * @param supplier the command supplier */ -[[nodiscard]] +WPI_IGNORE_DEPRECATED +[[nodiscard]] [[deprecated( + "The ProxyCommand supplier constructor has been deprecated. Use " + "Defer(supplier).AsProxy() instead.")]] CommandPtr DeferredProxy(wpi::unique_function supplier); /** @@ -169,9 +175,11 @@ CommandPtr DeferredProxy(wpi::unique_function supplier); * * @param supplier the command supplier */ -[[nodiscard]] +[[nodiscard]] [[deprecated( + "The ProxyCommand supplier constructor has been deprecated. Use " + "Defer(supplier).AsProxy() instead.")]] CommandPtr DeferredProxy(wpi::unique_function supplier); - +WPI_UNIGNORE_DEPRECATED // Command Groups namespace impl { diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/ProxyCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/ProxyCommand.h index d4d4757cf4..714427d104 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/ProxyCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/ProxyCommand.h @@ -7,6 +7,7 @@ #include #include +#include #include "frc2/command/Command.h" #include "frc2/command/CommandHelper.h" @@ -36,8 +37,16 @@ class ProxyCommand : public CommandHelper { * DeferredCommand} instead. * * @param supplier the command supplier + * @deprecated This constructor's similarity to {@link DeferredCommand} is + * confusing and opens potential footguns for users who do not fully + * understand the semantics and implications of proxying, but who simply want + * runtime construction. Users who do know what they are doing and need a + * supplier-constructed proxied command should instead proxy a DeferredCommand + * using the AsProxy decorator. * @see DeferredCommand */ + WPI_IGNORE_DEPRECATED + [[deprecated("Proxy a DeferredCommand instead")]] explicit ProxyCommand(wpi::unique_function supplier); /** @@ -49,9 +58,17 @@ class ProxyCommand : public CommandHelper { * DeferredCommand} instead. * * @param supplier the command supplier + * @deprecated This constructor's similarity to {@link DeferredCommand} is + * confusing and opens potential footguns for users who do not fully + * understand the semantics and implications of proxying, but who simply want + * runtime construction. Users who do know what they are doing and need a + * supplier-constructed proxied command should instead proxy a DeferredCommand + * using the AsProxy decorator. * @see DeferredCommand */ + [[deprecated("Proxy a DeferredCommand instead")]] explicit ProxyCommand(wpi::unique_function supplier); + WPI_UNIGNORE_DEPRECATED /** * Creates a new ProxyCommand that schedules the given command when