2019-11-17 16:35:45 -08:00
|
|
|
/*----------------------------------------------------------------------------*/
|
2020-01-20 21:49:03 -08:00
|
|
|
/* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
|
2019-11-17 16:35:45 -08:00
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#include "AddressableLEDGui.h"
|
|
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
#include <glass/hardware/LEDDisplay.h>
|
|
|
|
|
|
2019-11-17 16:35:45 -08:00
|
|
|
#include <hal/Ports.h>
|
2020-06-27 22:11:24 -07:00
|
|
|
#include <hal/simulation/AddressableLEDData.h>
|
2019-11-17 16:35:45 -08:00
|
|
|
#include <imgui.h>
|
|
|
|
|
#include <wpi/StringRef.h>
|
|
|
|
|
|
|
|
|
|
#include "HALSimGui.h"
|
|
|
|
|
|
|
|
|
|
using namespace halsimgui;
|
|
|
|
|
|
2019-12-01 21:28:02 -08:00
|
|
|
namespace {
|
2020-09-12 10:55:46 -07:00
|
|
|
class AddressableLEDModel : public glass::LEDDisplayModel {
|
|
|
|
|
public:
|
|
|
|
|
explicit AddressableLEDModel(int32_t index) : m_index{index} {}
|
2020-01-20 21:49:03 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
void Update() override {}
|
|
|
|
|
bool Exists() override {
|
|
|
|
|
return HALSIM_GetAddressableLEDInitialized(m_index);
|
|
|
|
|
}
|
2019-12-01 21:28:02 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
bool IsRunning() override { return HALSIM_GetAddressableLEDRunning(m_index); }
|
|
|
|
|
|
|
|
|
|
wpi::ArrayRef<Data> GetData(wpi::SmallVectorImpl<Data>&) override {
|
|
|
|
|
size_t length = HALSIM_GetAddressableLEDData(m_index, m_data);
|
|
|
|
|
return {reinterpret_cast<Data*>(m_data), length};
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|
|
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
private:
|
|
|
|
|
int32_t m_index;
|
2019-11-17 16:35:45 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
HAL_AddressableLEDData m_data[HAL_kAddressableLEDMaxLength];
|
|
|
|
|
};
|
2019-11-17 16:35:45 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
class AddressableLEDsModel : public glass::LEDDisplaysModel {
|
|
|
|
|
public:
|
|
|
|
|
AddressableLEDsModel() : m_models(HAL_GetNumAddressableLEDs()) {}
|
2019-11-17 16:35:45 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
void Update() override;
|
|
|
|
|
bool Exists() override;
|
2019-11-17 16:35:45 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
size_t GetNumLEDDisplays() override { return m_models.size(); }
|
|
|
|
|
|
|
|
|
|
void ForEachLEDDisplay(
|
|
|
|
|
wpi::function_ref<void(glass::LEDDisplayModel& model, int index)> func)
|
|
|
|
|
override;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<std::unique_ptr<AddressableLEDModel>> m_models;
|
|
|
|
|
};
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
void AddressableLEDsModel::Update() {
|
|
|
|
|
for (int i = 0; i < static_cast<int>(m_models.size()); ++i) {
|
|
|
|
|
auto& model = m_models[i];
|
|
|
|
|
if (HALSIM_GetAddressableLEDInitialized(i)) {
|
|
|
|
|
if (!model) {
|
|
|
|
|
model = std::make_unique<AddressableLEDModel>(i);
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|
2020-09-12 10:55:46 -07:00
|
|
|
if (model) model->Update();
|
|
|
|
|
} else {
|
|
|
|
|
model.reset();
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|
2020-09-12 10:55:46 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AddressableLEDsModel::Exists() {
|
|
|
|
|
for (auto&& model : m_models) {
|
|
|
|
|
if (model && model->Exists()) return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-11-17 16:35:45 -08:00
|
|
|
|
2020-09-12 10:55:46 -07:00
|
|
|
void AddressableLEDsModel::ForEachLEDDisplay(
|
|
|
|
|
wpi::function_ref<void(glass::LEDDisplayModel& model, int index)> func) {
|
|
|
|
|
for (int i = 0; i < static_cast<int>(m_models.size()); ++i) {
|
|
|
|
|
if (m_models[i]) func(*m_models[i], i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool AddressableLEDsExists() {
|
|
|
|
|
static const int numLED = HAL_GetNumAddressableLEDs();
|
|
|
|
|
for (int i = 0; i < numLED; ++i) {
|
|
|
|
|
if (HALSIM_GetAddressableLEDInitialized(i)) return true;
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|
2020-09-12 10:55:46 -07:00
|
|
|
return false;
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AddressableLEDGui::Initialize() {
|
2020-09-12 10:55:46 -07:00
|
|
|
HALSimGui::halProvider.Register(
|
|
|
|
|
"Addressable LEDs", [] { return AddressableLEDsExists(); },
|
|
|
|
|
[] { return std::make_unique<AddressableLEDsModel>(); },
|
|
|
|
|
[](glass::Window* win, glass::Model* model) {
|
|
|
|
|
win->SetFlags(ImGuiWindowFlags_AlwaysAutoResize);
|
|
|
|
|
win->SetDefaultPos(290, 100);
|
|
|
|
|
return glass::MakeFunctionView([=] {
|
|
|
|
|
glass::DisplayLEDDisplays(static_cast<AddressableLEDsModel*>(model));
|
|
|
|
|
});
|
|
|
|
|
});
|
2019-11-17 16:35:45 -08:00
|
|
|
}
|