1+ package dev.nextftc.extensions.fateweaver
2+
3+ import dev.nextftc.core.commands.CommandManager
4+ import dev.nextftc.core.components.Component
5+ import gay.zharel.fateweaver.flight.FlightLogChannel
6+ import gay.zharel.fateweaver.flight.FlightRecorder
7+ import gay.zharel.fateweaver.log.LogChannel
8+ import gay.zharel.fateweaver.schemas.FateSchema
9+ import java.util.function.Supplier
10+ import kotlin.reflect.KClass
11+
12+ /* *
13+ * FateWeaver integration component for NextFTC.
14+ *
15+ * This component provides a high-level interface for logging telemetry data using FateWeaver's
16+ * flight recorder system.
17+ * It manages log channels, handles periodic data publishing, and
18+ * automatically captures command snapshots during robot operation.
19+ *
20+ * Most FateComponent calls forward to [FlightRecorder].
21+ *
22+ * @see FlightRecorder
23+ */
24+ object FateComponent : Component {
25+ /* *
26+ * Internal channel used to log command manager snapshots.
27+ */
28+ private lateinit var snapshotChannel: FlightLogChannel <Array <String >>
29+
30+ /* *
31+ * Map of registered publishers that will be automatically invoked during periodic updates.
32+ * Each publisher supplies data to its associated log channel.
33+ */
34+ private val registeredPublishers: MutableMap <LogChannel <Any >, Supplier <Any >> = mutableMapOf ()
35+
36+ /* *
37+ * Creates a new log channel with a custom schema.
38+ *
39+ * Forwards to [FlightRecorder.createChannel].
40+ *
41+ * @param T The type of data that will be logged to this channel
42+ * @param name The name of the channel
43+ * @param schema The schema defining how to serialize/deserialize the data
44+ * @return A new [FlightLogChannel] for logging data
45+ */
46+ @JvmStatic
47+ fun <T > createChannel (name : String , schema : FateSchema <T >) =
48+ FlightRecorder .createChannel(name, schema)
49+
50+ /* *
51+ * Creates a new log channel for a specific class type.
52+ *
53+ * Forwards to [FlightRecorder.createChannel].
54+ *
55+ * @param T The type of data that will be logged to this channel
56+ * @param name The name of the channel
57+ * @param cls The Java class representing the data type
58+ * @return A new [FlightLogChannel] for logging data
59+ */
60+ @JvmStatic
61+ fun <T : Any > createChannel (name : String , cls : Class <T >) =
62+ FlightRecorder .createChannel(name, cls)
63+
64+ /* *
65+ * Creates a new log channel for a specific class type.
66+ *
67+ * Forwards to [FlightRecorder.createChannel].
68+ *
69+ * @param T The type of data that will be logged to this channel
70+ * @param name The name of the channel
71+ * @param cls The Kotlin class representing the data type
72+ * @return A new [FlightLogChannel] for logging data
73+ */
74+ @JvmStatic
75+ fun <T : Any > createChannel (name : String , cls : KClass <T >) =
76+ FlightRecorder .createChannel(name, cls.java)
77+
78+ /* *
79+ * Writes data to a specific log channel.
80+ *
81+ * Forwards to [FlightRecorder.write].
82+ *
83+ * @param T The type of data being logged
84+ * @param channel The channel to write to
85+ * @param obj The data object to log
86+ */
87+ @JvmStatic
88+ fun <T > write (channel : LogChannel <T >, obj : T ) =
89+ FlightRecorder .write(channel, obj)
90+
91+ /* *
92+ * Writes data to a channel by name.
93+ *
94+ * Forwards to [FlightRecorder.write].
95+ *
96+ * @param name The name of the channel to write to
97+ * @param obj The data object to log
98+ */
99+ @JvmStatic
100+ fun write (name : String , obj : Any ) =
101+ FlightRecorder .write(name, obj)
102+
103+ /* *
104+ * Registers a publisher that will automatically supply data to a channel during periodic updates.
105+ *
106+ * The supplier will be invoked during [postWaitForStart] and [postUpdate] to retrieve
107+ * the latest data and write it to the channel.
108+ *
109+ * @param T The type of data being published
110+ * @param channel The channel to publish to
111+ * @param supplier A supplier that provides the data to log
112+ */
113+ @JvmStatic
114+ @Suppress(" UNCHECKED_CAST" )
115+ fun <T > registerPublisher (channel : LogChannel <T >, supplier : Supplier <T >) {
116+ registeredPublishers[channel as LogChannel <Any >] = supplier as Supplier <Any >
117+ }
118+
119+ /* *
120+ * Registers a publisher for a new channel with a custom schema.
121+ *
122+ * This convenience method creates a channel and registers a publisher in one call.
123+ *
124+ * @param T The type of data being published
125+ * @param name The name of the channel to create
126+ * @param schema The schema defining how to serialize/deserialize the data
127+ * @param supplier A supplier that provides the data to log
128+ */
129+ @JvmStatic
130+ fun <T > registerPublisher (name : String , schema : FateSchema <T >, supplier : Supplier <T >) {
131+ registerPublisher(createChannel(name, schema), supplier)
132+ }
133+
134+ /* *
135+ * Registers a publisher for a new channel with a Java class type.
136+ *
137+ * This convenience method creates a channel and registers a publisher in one call.
138+ *
139+ * @param T The type of data being published
140+ * @param name The name of the channel to create
141+ * @param cls The Java class representing the data type
142+ * @param supplier A supplier that provides the data to log
143+ */
144+ @JvmStatic
145+ fun <T : Any > registerPublisher (name : String , cls : Class <T >, supplier : Supplier <T >) {
146+ registerPublisher(createChannel(name, cls), supplier)
147+ }
148+
149+ /* *
150+ * Registers a publisher for a new channel with a Kotlin class type.
151+ *
152+ * This convenience method creates a channel and registers a publisher in one call.
153+ *
154+ * @param T The type of data being published
155+ * @param name The name of the channel to create
156+ * @param cls The Kotlin class representing the data type
157+ * @param supplier A supplier that provides the data to log
158+ */
159+ @JvmStatic
160+ fun <T : Any > registerPublisher (name : String , cls : KClass <T >, supplier : Supplier <T >) {
161+ registerPublisher(createChannel(name, cls), supplier)
162+ }
163+
164+ override fun preInit () {
165+ snapshotChannel = createChannel(" CommandSnapshot" , Array <String >::class )
166+ }
167+
168+ override fun postWaitForStart () {
169+ snapshotChannel.put(CommandManager .snapshot.toTypedArray())
170+ registeredPublishers.forEach { (channel, supplier) ->
171+ write(channel, supplier.get())
172+ }
173+ FlightRecorder .timestamp()
174+ }
175+
176+ override fun postUpdate () {
177+ snapshotChannel.put(CommandManager .snapshot.toTypedArray())
178+ registeredPublishers.forEach { (channel, supplier) ->
179+ write(channel, supplier.get())
180+ }
181+ FlightRecorder .timestamp()
182+ }
183+
184+ override fun postStop () {
185+ registeredPublishers.clear()
186+ }
187+ }
0 commit comments