[glass] Split DataSource into type-specific variants (#7588)

This commit is contained in:
Peter Johnson
2025-01-03 13:36:40 -08:00
committed by GitHub
parent 148fcdca85
commit 0f6693594c
62 changed files with 667 additions and 390 deletions

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -7,7 +7,6 @@
#include <imgui.h>
#include <imgui_internal.h>
#include "glass/Context.h"
#include "glass/DataSource.h"
using namespace glass;

View File

@@ -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);
}

View File

@@ -6,7 +6,6 @@
#include <imgui.h>
#include "glass/Context.h"
#include "glass/DataSource.h"
using namespace glass;

View File

@@ -13,7 +13,6 @@
#include <imgui_internal.h>
#include <numbers>
#include "glass/Context.h"
#include "glass/DataSource.h"
using namespace glass;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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) {