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.commands3.proto;
006
007import edu.wpi.first.util.protobuf.Protobuf;
008import org.wpilib.commands3.Command;
009import org.wpilib.commands3.Mechanism;
010import org.wpilib.commands3.Scheduler;
011import org.wpilib.commands3.proto.ProtobufCommands.ProtobufCommand;
012import us.hebi.quickbuf.Descriptors;
013
014/** Protobuf serde for running commands. */
015public class CommandProto implements Protobuf<Command, ProtobufCommand> {
016  private final Scheduler m_scheduler;
017
018  public CommandProto(Scheduler scheduler) {
019    m_scheduler = scheduler;
020  }
021
022  @Override
023  public Class<Command> getTypeClass() {
024    return Command.class;
025  }
026
027  @Override
028  public Descriptors.Descriptor getDescriptor() {
029    return ProtobufCommand.getDescriptor();
030  }
031
032  @Override
033  public ProtobufCommand createMessage() {
034    return ProtobufCommand.newInstance();
035  }
036
037  @Override
038  public Command unpack(ProtobufCommand msg) {
039    // Not possible. The command behavior is what really matters, and it cannot be serialized
040    throw new UnsupportedOperationException("Deserialization not supported");
041  }
042
043  @Override
044  public void pack(ProtobufCommand msg, Command command) {
045    msg.clear();
046
047    msg.setId(m_scheduler.runId(command));
048    Command parent = m_scheduler.getParentOf(command);
049    if (parent != null) {
050      msg.setParentId(m_scheduler.runId(parent));
051    }
052    msg.setName(command.name());
053    msg.setPriority(command.priority());
054
055    Protobuf.packArray(
056        msg.getMutableRequirements(),
057        command.requirements().toArray(new Mechanism[0]),
058        new MechanismProto());
059
060    if (m_scheduler.isRunning(command)) {
061      msg.setLastTimeMs(m_scheduler.lastCommandRuntimeMs(command));
062      msg.setTotalTimeMs(m_scheduler.totalRuntimeMs(command));
063    }
064  }
065}