mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-28 02:11:43 +00:00
[glass] Split DataSource into type-specific variants (#7588)
This commit is contained in:
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/ContextInternal.h"
|
||||
|
||||
@@ -12,17 +16,13 @@ using namespace glass;
|
||||
|
||||
wpi::sig::Signal<const char*, DataSource*> DataSource::sourceCreated;
|
||||
|
||||
DataSource::DataSource(std::string_view id)
|
||||
: m_id{id}, m_name{gContext->sourceNameStorage.GetString(m_id)} {
|
||||
gContext->sources.try_emplace(m_id, this);
|
||||
sourceCreated(m_id.c_str(), this);
|
||||
std::string glass::MakeSourceId(std::string_view id, int index) {
|
||||
return fmt::format("{}[{}]", id, index);
|
||||
}
|
||||
|
||||
DataSource::DataSource(std::string_view id, int index)
|
||||
: DataSource{fmt::format("{}[{}]", id, index)} {}
|
||||
|
||||
DataSource::DataSource(std::string_view id, int index, int index2)
|
||||
: DataSource{fmt::format("{}[{},{}]", id, index, index2)} {}
|
||||
std::string glass::MakeSourceId(std::string_view id, int index, int index2) {
|
||||
return fmt::format("{}[{},{}]", id, index, index2);
|
||||
}
|
||||
|
||||
DataSource::~DataSource() {
|
||||
if (!gContext) {
|
||||
@@ -99,10 +99,11 @@ bool DataSource::InputInt(const char* label, int* v, int step, int step_fast,
|
||||
|
||||
void DataSource::EmitDrag(ImGuiDragDropFlags flags) const {
|
||||
if (ImGui::BeginDragDropSource(flags)) {
|
||||
char buf[32];
|
||||
std::snprintf(buf, sizeof(buf), "DataSource:%s", GetType());
|
||||
auto self = this;
|
||||
ImGui::SetDragDropPayload("DataSource", &self, sizeof(self)); // NOLINT
|
||||
const char* name = GetName().c_str();
|
||||
ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name);
|
||||
ImGui::SetDragDropPayload(buf, &self, sizeof(self)); // NOLINT
|
||||
DragDropTooltip();
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
@@ -114,3 +115,38 @@ DataSource* DataSource::Find(std::string_view id) {
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string& DataSource::GetNameStorage(std::string_view id) {
|
||||
return gContext->sourceNameStorage.GetString(id);
|
||||
}
|
||||
|
||||
void DataSource::Register() {
|
||||
gContext->sources.insert_or_assign(m_id, this);
|
||||
sourceCreated(m_id.c_str(), this);
|
||||
}
|
||||
|
||||
void DataSource::DragDropTooltip() const {
|
||||
const char* name = GetName().c_str();
|
||||
ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name);
|
||||
ImGui::Text("(%s)", GetType());
|
||||
}
|
||||
|
||||
const char* BooleanSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* DoubleSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* FloatSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* IntegerSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* StringSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
@@ -75,14 +75,14 @@ void DisplayDIOImpl(DIOModel* model, int index, bool outputsEnabled) {
|
||||
dioData->LabelText(label, "unknown");
|
||||
ImGui::PopStyleColor();
|
||||
} else if (model->IsReadOnly()) {
|
||||
dioData->LabelText(
|
||||
label, "%s",
|
||||
outputsEnabled ? (dioData->GetValue() != 0 ? "1 (high)" : "0 (low)")
|
||||
: "1 (disabled)");
|
||||
dioData->LabelText(label, "%s",
|
||||
outputsEnabled
|
||||
? (dioData->GetValue() ? "1 (high)" : "0 (low)")
|
||||
: "1 (disabled)");
|
||||
|
||||
} else {
|
||||
static const char* options[] = {"0 (low)", "1 (high)"};
|
||||
int val = dioData->GetValue() != 0 ? 1 : 0;
|
||||
int val = dioData->GetValue() ? 1 : 0;
|
||||
if (dioData->Combo(label, &val, options, 2)) {
|
||||
model->SetValue(val);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -58,7 +58,7 @@ void glass::DisplayRelay(RelayModel* model, int index, bool outputsEnabled) {
|
||||
IM_COL32(128, 128, 128, 255)};
|
||||
int values[2] = {reverseData ? (reverse ? 2 : -2) : -3,
|
||||
forwardData ? (forward ? 1 : -1) : -3};
|
||||
DataSource* sources[2] = {reverseData, forwardData};
|
||||
BooleanSource* sources[2] = {reverseData, forwardData};
|
||||
DrawLEDSources(values, sources, 2, 2, colors);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <imgui_internal.h>
|
||||
#include <numbers>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -80,12 +80,12 @@ void glass::DisplayFMS(FMSModel* model, bool editableDsAttached) {
|
||||
}
|
||||
|
||||
// Game Specific Message
|
||||
wpi::SmallString<64> gameSpecificMessageBuf;
|
||||
std::string gameSpecificMessage{
|
||||
model->GetGameSpecificMessage(gameSpecificMessageBuf)};
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
if (ImGui::InputText("Game Specific", &gameSpecificMessage)) {
|
||||
model->SetGameSpecificMessage(gameSpecificMessage);
|
||||
if (auto data = model->GetGameSpecificMessageData()) {
|
||||
std::string gameSpecificMessage = data->GetValue();
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
if (ImGui::InputText("Game Specific", &gameSpecificMessage)) {
|
||||
model->SetGameSpecificMessage(gameSpecificMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +148,11 @@ void glass::DisplayFMSReadOnly(FMSModel* model) {
|
||||
ImGui::TextUnformatted("?");
|
||||
}
|
||||
}
|
||||
|
||||
wpi::SmallString<64> gameSpecificMessageBuf;
|
||||
std::string_view gameSpecificMessage =
|
||||
model->GetGameSpecificMessage(gameSpecificMessageBuf);
|
||||
ImGui::Text("Game Specific: %s", exists ? gameSpecificMessage.data() : "?");
|
||||
if (auto data = model->GetGameSpecificMessageData()) {
|
||||
wpi::SmallString<64> gsmBuf;
|
||||
ImGui::Text("Game Specific: %s",
|
||||
exists ? data->GetValue(gsmBuf).data() : "?");
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
|
||||
#include "glass/other/PIDController.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -82,12 +82,13 @@ class PlotSeries {
|
||||
private:
|
||||
bool IsDigital() const {
|
||||
return m_digital.GetValue() == kDigital ||
|
||||
(m_digital.GetValue() == kAuto && m_source && m_source->IsDigital());
|
||||
(m_digital.GetValue() == kAuto && m_source && m_digitalSource);
|
||||
}
|
||||
void AppendValue(double value, int64_t time);
|
||||
|
||||
// source linkage
|
||||
DataSource* m_source = nullptr;
|
||||
bool m_digitalSource = false;
|
||||
wpi::sig::ScopedConnection m_sourceCreatedConn;
|
||||
wpi::sig::ScopedConnection m_newValueConn;
|
||||
std::string& m_id;
|
||||
@@ -255,11 +256,39 @@ void PlotSeries::CheckSource() {
|
||||
void PlotSeries::SetSource(DataSource* source) {
|
||||
m_source = source;
|
||||
|
||||
// add initial value
|
||||
AppendValue(source->GetValue(), 0);
|
||||
if (auto s = dynamic_cast<BooleanSource*>(source)) {
|
||||
m_digitalSource = true;
|
||||
|
||||
m_newValueConn = source->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](bool value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<DoubleSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<FloatSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<IntegerSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](int64_t value, int64_t time) { AppendValue(value, time); });
|
||||
}
|
||||
}
|
||||
|
||||
void PlotSeries::AppendValue(double value, int64_t timeUs) {
|
||||
@@ -522,9 +551,18 @@ Plot::Plot(Storage& storage)
|
||||
}
|
||||
|
||||
void Plot::DragDropAccept(PlotView& view, size_t i, int yAxis) {
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("DataSource")) {
|
||||
auto source = *static_cast<DataSource**>(payload->Data);
|
||||
// accept any of double/float/boolean/integer sources
|
||||
DataSource* source = AcceptDragDropPayload<DoubleSource>();
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<FloatSource>();
|
||||
}
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<BooleanSource>();
|
||||
}
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<IntegerSource>();
|
||||
}
|
||||
if (source) {
|
||||
// don't add duplicates unless it's onto a different Y axis
|
||||
auto it =
|
||||
std::find_if(m_series.begin(), m_series.end(), [=](const auto& elem) {
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
|
||||
#include "glass/other/ProfiledPIDController.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace glass {
|
||||
|
||||
void DrawLEDSources(const int* values, DataSource** sources, int numValues,
|
||||
void DrawLEDSources(const int* values, BooleanSource** sources, int numValues,
|
||||
int cols, const ImU32* colors, float size, float spacing,
|
||||
const LEDConfig& config) {
|
||||
if (numValues == 0 || cols < 1) {
|
||||
|
||||
Reference in New Issue
Block a user