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 edu.wpi.first.util.datalog;
006
007import edu.wpi.first.util.protobuf.Protobuf;
008import edu.wpi.first.util.protobuf.ProtobufBuffer;
009import java.io.IOException;
010import java.nio.ByteBuffer;
011import us.hebi.quickbuf.ProtoMessage;
012
013/**
014 * Log protobuf-encoded values.
015 *
016 * @param <T> value class
017 */
018public final class ProtobufLogEntry<T> extends DataLogEntry {
019  private ProtobufLogEntry(
020      DataLog log, String name, Protobuf<T, ?> proto, String metadata, long timestamp) {
021    super(log, name, proto.getTypeString(), metadata, timestamp);
022    m_buf = ProtobufBuffer.create(proto);
023    log.addSchema(proto, timestamp);
024  }
025
026  /**
027   * Creates a protobuf-encoded log entry.
028   *
029   * @param <T> value class (inferred from proto)
030   * @param <MessageType> protobuf message type (inferred from proto)
031   * @param log datalog
032   * @param name name of the entry
033   * @param proto protobuf serialization implementation
034   * @param metadata metadata
035   * @param timestamp entry creation timestamp (0=now)
036   * @return ProtobufLogEntry
037   */
038  public static <T, MessageType extends ProtoMessage<?>> ProtobufLogEntry<T> create(
039      DataLog log, String name, Protobuf<T, MessageType> proto, String metadata, long timestamp) {
040    return new ProtobufLogEntry<>(log, name, proto, metadata, timestamp);
041  }
042
043  /**
044   * Creates a protobuf-encoded log entry.
045   *
046   * @param <T> value class (inferred from proto)
047   * @param <MessageType> protobuf message type (inferred from proto)
048   * @param log datalog
049   * @param name name of the entry
050   * @param proto protobuf serialization implementation
051   * @param metadata metadata
052   * @return ProtobufLogEntry
053   */
054  public static <T, MessageType extends ProtoMessage<?>> ProtobufLogEntry<T> create(
055      DataLog log, String name, Protobuf<T, MessageType> proto, String metadata) {
056    return create(log, name, proto, metadata, 0);
057  }
058
059  /**
060   * Creates a protobuf-encoded log entry.
061   *
062   * @param <T> value class (inferred from proto)
063   * @param <MessageType> protobuf message type (inferred from proto)
064   * @param log datalog
065   * @param name name of the entry
066   * @param proto protobuf serialization implementation
067   * @param timestamp entry creation timestamp (0=now)
068   * @return ProtobufLogEntry
069   */
070  public static <T, MessageType extends ProtoMessage<?>> ProtobufLogEntry<T> create(
071      DataLog log, String name, Protobuf<T, MessageType> proto, long timestamp) {
072    return create(log, name, proto, "", timestamp);
073  }
074
075  /**
076   * Creates a protobuf-encoded log entry.
077   *
078   * @param <T> value class (inferred from proto)
079   * @param <MessageType> protobuf message type (inferred from proto)
080   * @param log datalog
081   * @param name name of the entry
082   * @param proto protobuf serialization implementation
083   * @return ProtobufLogEntry
084   */
085  public static <T, MessageType extends ProtoMessage<?>> ProtobufLogEntry<T> create(
086      DataLog log, String name, Protobuf<T, MessageType> proto) {
087    return create(log, name, proto, 0);
088  }
089
090  /**
091   * Appends a record to the log.
092   *
093   * @param value Value to record
094   * @param timestamp Time stamp (0 to indicate now)
095   */
096  public void append(T value, long timestamp) {
097    try {
098      synchronized (m_buf) {
099        ByteBuffer bb = m_buf.write(value);
100        m_log.appendRaw(m_entry, bb, 0, bb.position(), timestamp);
101      }
102    } catch (IOException e) {
103      // ignore
104    }
105  }
106
107  /**
108   * Appends a record to the log.
109   *
110   * @param value Value to record
111   */
112  public void append(T value) {
113    append(value, 0);
114  }
115
116  private final ProtobufBuffer<T, ?> m_buf;
117}