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.internal;
006
007import java.util.concurrent.atomic.AtomicBoolean;
008import java.util.concurrent.atomic.AtomicLong;
009import org.wpilib.driverstation.DriverStation;
010import org.wpilib.hardware.hal.ControlWord;
011import org.wpilib.hardware.hal.DriverStationJNI;
012import org.wpilib.util.WPIUtilJNI;
013
014/** For internal use only. */
015public class DriverStationModeThread implements AutoCloseable {
016  private final AtomicBoolean m_keepAlive = new AtomicBoolean(true);
017  private final AtomicLong m_userControlWord;
018  private final int m_handle = WPIUtilJNI.createEvent(false, false);
019  private final Thread m_thread;
020
021  /**
022   * Internal use only.
023   *
024   * @param word control word
025   */
026  public DriverStationModeThread(ControlWord word) {
027    m_userControlWord = new AtomicLong(word.getNative());
028    DriverStationJNI.provideNewDataEventHandle(m_handle);
029    m_thread = new Thread(this::run, "DriverStationMode");
030    m_thread.start();
031  }
032
033  private void run() {
034    while (true) {
035      try {
036        WPIUtilJNI.waitForObjectTimeout(m_handle, 0.1);
037      } catch (InterruptedException e) {
038        Thread.currentThread().interrupt();
039        return;
040      }
041      if (!m_keepAlive.get()) {
042        return;
043      }
044      DriverStation.refreshData();
045      DriverStationJNI.observeUserProgram(m_userControlWord.get());
046    }
047  }
048
049  /**
050   * Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
051   * purposes only.
052   *
053   * @param word control word
054   */
055  public void inControl(ControlWord word) {
056    m_userControlWord.set(word.getNative());
057  }
058
059  @Override
060  public void close() {
061    DriverStationJNI.removeNewDataEventHandle(m_handle);
062    WPIUtilJNI.destroyEvent(m_handle);
063    m_keepAlive.set(false);
064    try {
065      m_thread.join();
066    } catch (InterruptedException e) {
067      Thread.currentThread().interrupt();
068    }
069  }
070}