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.epilogue.logging;
006
007import edu.wpi.first.util.protobuf.Protobuf;
008import edu.wpi.first.util.struct.Struct;
009import java.util.HashMap;
010import java.util.List;
011import java.util.Map;
012import us.hebi.quickbuf.ProtoMessage;
013
014/**
015 * A backend implementation that delegates to other backends. Helpful for simultaneous logging to
016 * multiple data stores at once.
017 */
018public class MultiBackend implements EpilogueBackend {
019  private final List<EpilogueBackend> m_backends;
020  private final Map<String, NestedBackend> m_nestedBackends = new HashMap<>();
021
022  // Use EpilogueBackend.multi(...) instead of instantiation directly
023  MultiBackend(EpilogueBackend... backends) {
024    this.m_backends = List.of(backends);
025  }
026
027  @Override
028  public EpilogueBackend getNested(String path) {
029    if (!m_nestedBackends.containsKey(path)) {
030      var nested = new NestedBackend(path, this);
031      m_nestedBackends.put(path, nested);
032      return nested;
033    }
034
035    return m_nestedBackends.get(path);
036  }
037
038  @Override
039  public void log(String identifier, int value) {
040    for (EpilogueBackend backend : m_backends) {
041      backend.log(identifier, value);
042    }
043  }
044
045  @Override
046  public void log(String identifier, long value) {
047    for (EpilogueBackend backend : m_backends) {
048      backend.log(identifier, value);
049    }
050  }
051
052  @Override
053  public void log(String identifier, float value) {
054    for (EpilogueBackend backend : m_backends) {
055      backend.log(identifier, value);
056    }
057  }
058
059  @Override
060  public void log(String identifier, double value) {
061    for (EpilogueBackend backend : m_backends) {
062      backend.log(identifier, value);
063    }
064  }
065
066  @Override
067  public void log(String identifier, boolean value) {
068    for (EpilogueBackend backend : m_backends) {
069      backend.log(identifier, value);
070    }
071  }
072
073  @Override
074  public void log(String identifier, byte[] value) {
075    for (EpilogueBackend backend : m_backends) {
076      backend.log(identifier, value);
077    }
078  }
079
080  @Override
081  public void log(String identifier, int[] value) {
082    for (EpilogueBackend backend : m_backends) {
083      backend.log(identifier, value);
084    }
085  }
086
087  @Override
088  public void log(String identifier, long[] value) {
089    for (EpilogueBackend backend : m_backends) {
090      backend.log(identifier, value);
091    }
092  }
093
094  @Override
095  public void log(String identifier, float[] value) {
096    for (EpilogueBackend backend : m_backends) {
097      backend.log(identifier, value);
098    }
099  }
100
101  @Override
102  public void log(String identifier, double[] value) {
103    for (EpilogueBackend backend : m_backends) {
104      backend.log(identifier, value);
105    }
106  }
107
108  @Override
109  public void log(String identifier, boolean[] value) {
110    for (EpilogueBackend backend : m_backends) {
111      backend.log(identifier, value);
112    }
113  }
114
115  @Override
116  public void log(String identifier, String value) {
117    for (EpilogueBackend backend : m_backends) {
118      backend.log(identifier, value);
119    }
120  }
121
122  @Override
123  public void log(String identifier, String[] value) {
124    for (EpilogueBackend backend : m_backends) {
125      backend.log(identifier, value);
126    }
127  }
128
129  @Override
130  public <S> void log(String identifier, S value, Struct<S> struct) {
131    for (EpilogueBackend backend : m_backends) {
132      backend.log(identifier, value, struct);
133    }
134  }
135
136  @Override
137  public <S> void log(String identifier, S[] value, Struct<S> struct) {
138    for (EpilogueBackend backend : m_backends) {
139      backend.log(identifier, value, struct);
140    }
141  }
142
143  @Override
144  public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
145    for (EpilogueBackend backend : m_backends) {
146      backend.log(identifier, value, proto);
147    }
148  }
149}