diff --git a/glass/src/lib/native/cpp/DataSource.cpp b/glass/src/lib/native/cpp/DataSource.cpp index 372d5f2ee5d..e9237965b6f 100644 --- a/glass/src/lib/native/cpp/DataSource.cpp +++ b/glass/src/lib/native/cpp/DataSource.cpp @@ -7,22 +7,24 @@ #include #include "glass/ContextInternal.h" +#include "imgui.h" using namespace glass; wpi::sig::Signal 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)} {} +std::string glass::MakeSourceId(std::string_view id, int index, int index2) { + return fmt::format("{}[{},{}]", id, index, index2); +} -DataSource::DataSource(std::string_view id, int index, int index2) - : DataSource{fmt::format("{}[{},{}]", id, index, index2)} {} +DataSource::DataSource(Kind kind, std::string_view id) + : m_id{id}, + m_name{gContext->sourceNameStorage.GetString(m_id)}, + m_kind{kind} {} DataSource::~DataSource() { if (!gContext) { @@ -99,8 +101,7 @@ bool DataSource::InputInt(const char* label, int* v, int step, int step_fast, void DataSource::EmitDrag(ImGuiDragDropFlags flags) const { if (ImGui::BeginDragDropSource(flags)) { - auto self = this; - ImGui::SetDragDropPayload("DataSource", &self, sizeof(self)); // NOLINT + SetDragDropPayload(); const char* name = GetName().c_str(); ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name); ImGui::EndDragDropSource(); @@ -114,3 +115,68 @@ DataSource* DataSource::Find(std::string_view id) { } return it->second; } + +void DataSource::Register() { + gContext->sources.insert_or_assign(m_id, this); + sourceCreated(m_id.c_str(), this); +} + +BooleanSource* BooleanSource::AcceptDragDropPayload(ImGuiDragDropFlags flags) { + if (auto payload = ImGui::AcceptDragDropPayload("BooleanSource", flags)) { + return *static_cast(payload->Data); + } + return nullptr; +} + +void BooleanSource::SetDragDropPayload() const { + auto self = this; + ImGui::SetDragDropPayload("BooleanSource", &self, sizeof(self)); // NOLINT +} + +DoubleSource* DoubleSource::AcceptDragDropPayload(ImGuiDragDropFlags flags) { + if (auto payload = ImGui::AcceptDragDropPayload("DoubleSource", flags)) { + return *static_cast(payload->Data); + } + return nullptr; +} + +void DoubleSource::SetDragDropPayload() const { + auto self = this; + ImGui::SetDragDropPayload("DoubleSource", &self, sizeof(self)); // NOLINT +} + +FloatSource* FloatSource::AcceptDragDropPayload(ImGuiDragDropFlags flags) { + if (auto payload = ImGui::AcceptDragDropPayload("FloatSource", flags)) { + return *static_cast(payload->Data); + } + return nullptr; +} + +void FloatSource::SetDragDropPayload() const { + auto self = this; + ImGui::SetDragDropPayload("FloatSource", &self, sizeof(self)); // NOLINT +} + +IntegerSource* IntegerSource::AcceptDragDropPayload(ImGuiDragDropFlags flags) { + if (auto payload = ImGui::AcceptDragDropPayload("IntegerSource", flags)) { + return *static_cast(payload->Data); + } + return nullptr; +} + +void IntegerSource::SetDragDropPayload() const { + auto self = this; + ImGui::SetDragDropPayload("IntegerSource", &self, sizeof(self)); // NOLINT +} + +StringSource* StringSource::AcceptDragDropPayload(ImGuiDragDropFlags flags) { + if (auto payload = ImGui::AcceptDragDropPayload("StringSource", flags)) { + return *static_cast(payload->Data); + } + return nullptr; +} + +void StringSource::SetDragDropPayload() const { + auto self = this; + ImGui::SetDragDropPayload("StringSource", &self, sizeof(self)); // NOLINT +} diff --git a/glass/src/lib/native/cpp/hardware/DIO.cpp b/glass/src/lib/native/cpp/hardware/DIO.cpp index f52974a5a30..26fd21923b5 100644 --- a/glass/src/lib/native/cpp/hardware/DIO.cpp +++ b/glass/src/lib/native/cpp/hardware/DIO.cpp @@ -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); } diff --git a/glass/src/lib/native/cpp/hardware/MotorController.cpp b/glass/src/lib/native/cpp/hardware/MotorController.cpp index 96181b29c45..49a4803e0b4 100644 --- a/glass/src/lib/native/cpp/hardware/MotorController.cpp +++ b/glass/src/lib/native/cpp/hardware/MotorController.cpp @@ -7,7 +7,6 @@ #include #include -#include "glass/Context.h" #include "glass/DataSource.h" using namespace glass; diff --git a/glass/src/lib/native/cpp/hardware/Relay.cpp b/glass/src/lib/native/cpp/hardware/Relay.cpp index ff383d0fa5f..a29832e8c7c 100644 --- a/glass/src/lib/native/cpp/hardware/Relay.cpp +++ b/glass/src/lib/native/cpp/hardware/Relay.cpp @@ -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); } diff --git a/glass/src/lib/native/cpp/other/CommandSelector.cpp b/glass/src/lib/native/cpp/other/CommandSelector.cpp index d2124c39fa5..a7eb073dd28 100644 --- a/glass/src/lib/native/cpp/other/CommandSelector.cpp +++ b/glass/src/lib/native/cpp/other/CommandSelector.cpp @@ -6,7 +6,6 @@ #include -#include "glass/Context.h" #include "glass/DataSource.h" using namespace glass; diff --git a/glass/src/lib/native/cpp/other/Drive.cpp b/glass/src/lib/native/cpp/other/Drive.cpp index d54b2da825b..60b6130d90e 100644 --- a/glass/src/lib/native/cpp/other/Drive.cpp +++ b/glass/src/lib/native/cpp/other/Drive.cpp @@ -13,7 +13,6 @@ #include #include -#include "glass/Context.h" #include "glass/DataSource.h" using namespace glass; diff --git a/glass/src/lib/native/cpp/other/FMS.cpp b/glass/src/lib/native/cpp/other/FMS.cpp index 86ed0205a7a..ed56a669db5 100644 --- a/glass/src/lib/native/cpp/other/FMS.cpp +++ b/glass/src/lib/native/cpp/other/FMS.cpp @@ -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(); diff --git a/glass/src/lib/native/cpp/other/PIDController.cpp b/glass/src/lib/native/cpp/other/PIDController.cpp index 8aa5e1f99d1..ae42dee0ca4 100644 --- a/glass/src/lib/native/cpp/other/PIDController.cpp +++ b/glass/src/lib/native/cpp/other/PIDController.cpp @@ -4,11 +4,8 @@ #include "glass/other/PIDController.h" -#include - #include -#include "glass/Context.h" #include "glass/DataSource.h" using namespace glass; diff --git a/glass/src/lib/native/cpp/other/Plot.cpp b/glass/src/lib/native/cpp/other/Plot.cpp index 56fc04d099d..2a9c33283db 100644 --- a/glass/src/lib/native/cpp/other/Plot.cpp +++ b/glass/src/lib/native/cpp/other/Plot.cpp @@ -82,7 +82,8 @@ 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_source->GetKind() == DataSource::kBoolean); } void AppendValue(double value, int64_t time); @@ -255,11 +256,46 @@ void PlotSeries::CheckSource() { void PlotSeries::SetSource(DataSource* source) { m_source = source; - // add initial value - AppendValue(source->GetValue(), 0); + switch (source->GetKind()) { + case DataSource::kBoolean: { + auto s = static_cast(source); + // add initial value + AppendValue(s->GetValue(), 0); - m_newValueConn = source->valueChanged.connect_connection( - [this](double value, int64_t time) { AppendValue(value, time); }); + m_newValueConn = s->valueChanged.connect_connection( + [this](bool value, int64_t time) { AppendValue(value, time); }); + break; + } + case DataSource::kDouble: { + auto s = static_cast(source); + // add initial value + AppendValue(s->GetValue(), 0); + + m_newValueConn = s->valueChanged.connect_connection( + [this](double value, int64_t time) { AppendValue(value, time); }); + break; + } + case DataSource::kFloat: { + auto s = static_cast(source); + // add initial value + AppendValue(s->GetValue(), 0); + + m_newValueConn = s->valueChanged.connect_connection( + [this](double value, int64_t time) { AppendValue(value, time); }); + break; + } + case DataSource::kInteger: { + auto s = static_cast(source); + // add initial value + AppendValue(s->GetValue(), 0); + + m_newValueConn = s->valueChanged.connect_connection( + [this](int64_t value, int64_t time) { AppendValue(value, time); }); + break; + } + default: + break; + } } void PlotSeries::AppendValue(double value, int64_t timeUs) { @@ -522,9 +558,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(payload->Data); + // accept any of double/float/boolean/integer sources + DataSource* source = DoubleSource::AcceptDragDropPayload(); + if (!source) { + source = FloatSource::AcceptDragDropPayload(); + } + if (!source) { + source = BooleanSource::AcceptDragDropPayload(); + } + if (!source) { + source = IntegerSource::AcceptDragDropPayload(); + } + 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) { diff --git a/glass/src/lib/native/cpp/other/ProfiledPIDController.cpp b/glass/src/lib/native/cpp/other/ProfiledPIDController.cpp index f9d37b90019..3c9b75b16b4 100644 --- a/glass/src/lib/native/cpp/other/ProfiledPIDController.cpp +++ b/glass/src/lib/native/cpp/other/ProfiledPIDController.cpp @@ -4,11 +4,8 @@ #include "glass/other/ProfiledPIDController.h" -#include - #include -#include "glass/Context.h" #include "glass/DataSource.h" using namespace glass; diff --git a/glass/src/lib/native/cpp/support/ExtraGuiWidgets.cpp b/glass/src/lib/native/cpp/support/ExtraGuiWidgets.cpp index 0b0aae3eaaf..6d81ac682a2 100644 --- a/glass/src/lib/native/cpp/support/ExtraGuiWidgets.cpp +++ b/glass/src/lib/native/cpp/support/ExtraGuiWidgets.cpp @@ -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) { diff --git a/glass/src/lib/native/include/glass/DataSource.h b/glass/src/lib/native/include/glass/DataSource.h index 7e0c673054f..baa731d934a 100644 --- a/glass/src/lib/native/include/glass/DataSource.h +++ b/glass/src/lib/native/include/glass/DataSource.h @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -20,13 +21,19 @@ namespace glass { */ class DataSource { public: - explicit DataSource(std::string_view id); - DataSource(std::string_view id, int index); - DataSource(std::string_view id, int index, int index2); + enum Kind { + kBoolean, + kDouble, + kFloat, + kInteger, + kString, + }; virtual ~DataSource(); DataSource(const DataSource&) = delete; DataSource& operator=(const DataSource&) = delete; + DataSource(DataSource&&) = delete; + DataSource& operator=(DataSource&&) = delete; const char* GetId() const { return m_id.c_str(); } @@ -34,20 +41,7 @@ class DataSource { std::string& GetName() { return m_name; } const std::string& GetName() const { return m_name; } - void SetDigital(bool digital) { m_digital = digital; } - bool IsDigital() const { return m_digital; } - - void SetValue(double value, int64_t time = 0) { - std::scoped_lock lock{m_valueMutex}; - m_value = value; - m_valueTime = time; - valueChanged(value, time); - } - - double GetValue() const { - std::scoped_lock lock{m_valueMutex}; - return m_value; - } + Kind GetKind() const { return m_kind; } int64_t GetValueTime() const { std::scoped_lock lock{m_valueMutex}; @@ -69,8 +63,6 @@ class DataSource { ImGuiInputTextFlags flags = 0) const; void EmitDrag(ImGuiDragDropFlags flags = 0) const; - wpi::sig::SignalBase valueChanged; - static DataSource* Find(std::string_view id); static wpi::sig::Signal sourceCreated; @@ -78,10 +70,133 @@ class DataSource { private: std::string m_id; std::string& m_name; - bool m_digital = false; + Kind m_kind; + + protected: + DataSource(Kind kind, std::string_view id); + + void Register(); + + virtual void SetDragDropPayload() const = 0; + mutable wpi::spinlock m_valueMutex; - double m_value = 0; int64_t m_valueTime = 0; }; +std::string MakeSourceId(std::string_view id, int index); +std::string MakeSourceId(std::string_view id, int index, int index2); + +template +class ValueSource : public DataSource { + public: + void SetValue(T value, int64_t time = 0) { + std::scoped_lock lock{m_valueMutex}; + m_value = value; + m_valueTime = time; + valueChanged(value, time); + } + + T GetValue() const { + std::scoped_lock lock{m_valueMutex}; + return m_value; + } + + wpi::sig::SignalBase valueChanged; + + private: + T m_value = 0; + + protected: + explicit ValueSource(std::string_view id) : DataSource{kind, id} {} +}; + +class BooleanSource : public ValueSource { + public: + explicit BooleanSource(std::string_view id) : ValueSource{id} { Register(); } + + static BooleanSource* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0); + + protected: + void SetDragDropPayload() const override; +}; + +class DoubleSource : public ValueSource { + public: + explicit DoubleSource(std::string_view id) : ValueSource{id} { Register(); } + + static DoubleSource* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0); + + protected: + void SetDragDropPayload() const override; +}; + +class FloatSource : public ValueSource { + public: + explicit FloatSource(std::string_view id) : ValueSource{id} { Register(); } + + static FloatSource* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0); + + protected: + void SetDragDropPayload() const override; +}; + +class IntegerSource : public ValueSource { + public: + explicit IntegerSource(std::string_view id) : ValueSource{id} { Register(); } + + static IntegerSource* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0); + + protected: + void SetDragDropPayload() const override; +}; + +class StringSource : public DataSource { + public: + explicit StringSource(std::string_view id) : DataSource{kString, id} { + Register(); + } + + void SetValue(std::string_view value, int64_t time = 0) { + std::scoped_lock lock{m_valueMutex}; + m_value = value; + m_valueTime = time; + valueChanged(m_value, time); + } + + void SetValue(std::string&& value, int64_t time = 0) { + std::scoped_lock lock{m_valueMutex}; + m_value = std::move(value); + m_valueTime = time; + valueChanged(m_value, time); + } + + void SetValue(const char* value, int64_t time = 0) { + std::scoped_lock lock{m_valueMutex}; + m_value = value; + m_valueTime = time; + valueChanged(m_value, time); + } + + std::string GetValue() const { + std::scoped_lock lock{m_valueMutex}; + return m_value; + } + + std::string_view GetValue(wpi::SmallVectorImpl& buf) const { + std::scoped_lock lock{m_valueMutex}; + buf.assign(m_value.begin(), m_value.end()); + return {buf.begin(), buf.end()}; + } + + wpi::sig::SignalBase valueChanged; + + static StringSource* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0); + + private: + std::string m_value; + + protected: + void SetDragDropPayload() const override; +}; + } // namespace glass diff --git a/glass/src/lib/native/include/glass/hardware/Accelerometer.h b/glass/src/lib/native/include/glass/hardware/Accelerometer.h index e997963da89..a5d38d525c2 100644 --- a/glass/src/lib/native/include/glass/hardware/Accelerometer.h +++ b/glass/src/lib/native/include/glass/hardware/Accelerometer.h @@ -8,13 +8,13 @@ namespace glass { -class DataSource; +class DoubleSource; class AccelerometerModel : public Model { public: - virtual DataSource* GetXData() = 0; - virtual DataSource* GetYData() = 0; - virtual DataSource* GetZData() = 0; + virtual DoubleSource* GetXData() = 0; + virtual DoubleSource* GetYData() = 0; + virtual DoubleSource* GetZData() = 0; virtual int GetRange() = 0; diff --git a/glass/src/lib/native/include/glass/hardware/AnalogGyro.h b/glass/src/lib/native/include/glass/hardware/AnalogGyro.h index fdfcf4f7987..39db0e83ad7 100644 --- a/glass/src/lib/native/include/glass/hardware/AnalogGyro.h +++ b/glass/src/lib/native/include/glass/hardware/AnalogGyro.h @@ -10,12 +10,12 @@ namespace glass { -class DataSource; +class DoubleSource; class AnalogGyroModel : public Model { public: - virtual DataSource* GetAngleData() = 0; - virtual DataSource* GetRateData() = 0; + virtual DoubleSource* GetAngleData() = 0; + virtual DoubleSource* GetRateData() = 0; virtual void SetAngle(double val) = 0; virtual void SetRate(double val) = 0; diff --git a/glass/src/lib/native/include/glass/hardware/AnalogInput.h b/glass/src/lib/native/include/glass/hardware/AnalogInput.h index 2e49b9ccce1..f0079c7f7b1 100644 --- a/glass/src/lib/native/include/glass/hardware/AnalogInput.h +++ b/glass/src/lib/native/include/glass/hardware/AnalogInput.h @@ -12,14 +12,14 @@ namespace glass { -class DataSource; +class DoubleSource; class AnalogInputModel : public Model { public: virtual bool IsGyro() const = 0; virtual const char* GetSimDevice() const = 0; - virtual DataSource* GetVoltageData() = 0; + virtual DoubleSource* GetVoltageData() = 0; virtual void SetVoltage(double val) = 0; }; diff --git a/glass/src/lib/native/include/glass/hardware/AnalogOutput.h b/glass/src/lib/native/include/glass/hardware/AnalogOutput.h index 7ba8be6dd16..da24384ba31 100644 --- a/glass/src/lib/native/include/glass/hardware/AnalogOutput.h +++ b/glass/src/lib/native/include/glass/hardware/AnalogOutput.h @@ -10,11 +10,11 @@ namespace glass { -class DataSource; +class DoubleSource; class AnalogOutputModel : public Model { public: - virtual DataSource* GetVoltageData() = 0; + virtual DoubleSource* GetVoltageData() = 0; virtual void SetVoltage(double val) = 0; }; diff --git a/glass/src/lib/native/include/glass/hardware/DIO.h b/glass/src/lib/native/include/glass/hardware/DIO.h index 5593ba69daf..b2f742373e7 100644 --- a/glass/src/lib/native/include/glass/hardware/DIO.h +++ b/glass/src/lib/native/include/glass/hardware/DIO.h @@ -13,13 +13,14 @@ namespace glass { class EncoderModel; -class DataSource; +class BooleanSource; +class DoubleSource; class DPWMModel : public Model { public: virtual const char* GetSimDevice() const = 0; - virtual DataSource* GetValueData() = 0; + virtual DoubleSource* GetValueData() = 0; virtual void SetValue(double val) = 0; }; @@ -28,7 +29,7 @@ class DutyCycleModel : public Model { public: virtual const char* GetSimDevice() const = 0; - virtual DataSource* GetValueData() = 0; + virtual DoubleSource* GetValueData() = 0; virtual void SetValue(double val) = 0; }; @@ -45,7 +46,7 @@ class DIOModel : public Model { virtual bool IsInput() const = 0; - virtual DataSource* GetValueData() = 0; + virtual BooleanSource* GetValueData() = 0; virtual void SetValue(bool val) = 0; }; diff --git a/glass/src/lib/native/include/glass/hardware/Encoder.h b/glass/src/lib/native/include/glass/hardware/Encoder.h index 41d781aa9ac..7ade4c0b16a 100644 --- a/glass/src/lib/native/include/glass/hardware/Encoder.h +++ b/glass/src/lib/native/include/glass/hardware/Encoder.h @@ -12,7 +12,9 @@ namespace glass { -class DataSource; +class BooleanSource; +class DoubleSource; +class IntegerSource; class EncoderModel : public Model { public: @@ -23,12 +25,12 @@ class EncoderModel : public Model { virtual int GetChannelA() const = 0; virtual int GetChannelB() const = 0; - virtual DataSource* GetDistancePerPulseData() = 0; - virtual DataSource* GetCountData() = 0; - virtual DataSource* GetPeriodData() = 0; - virtual DataSource* GetDirectionData() = 0; - virtual DataSource* GetDistanceData() = 0; - virtual DataSource* GetRateData() = 0; + virtual DoubleSource* GetDistancePerPulseData() = 0; + virtual IntegerSource* GetCountData() = 0; + virtual DoubleSource* GetPeriodData() = 0; + virtual BooleanSource* GetDirectionData() = 0; + virtual DoubleSource* GetDistanceData() = 0; + virtual DoubleSource* GetRateData() = 0; virtual double GetMaxPeriod() = 0; virtual bool GetReverseDirection() = 0; diff --git a/glass/src/lib/native/include/glass/hardware/Gyro.h b/glass/src/lib/native/include/glass/hardware/Gyro.h index d2bb09d2ac0..53b8ce6f82f 100644 --- a/glass/src/lib/native/include/glass/hardware/Gyro.h +++ b/glass/src/lib/native/include/glass/hardware/Gyro.h @@ -7,13 +7,13 @@ #include "glass/Model.h" namespace glass { -class DataSource; +class DoubleSource; class GyroModel : public Model { public: virtual const char* GetName() const = 0; virtual const char* GetSimDevice() const = 0; - virtual DataSource* GetAngleData() = 0; + virtual DoubleSource* GetAngleData() = 0; virtual void SetAngle(double angle) = 0; }; void DisplayGyro(GyroModel* m); diff --git a/glass/src/lib/native/include/glass/hardware/MotorController.h b/glass/src/lib/native/include/glass/hardware/MotorController.h index 5fc831f23df..fdd1f5ec05b 100644 --- a/glass/src/lib/native/include/glass/hardware/MotorController.h +++ b/glass/src/lib/native/include/glass/hardware/MotorController.h @@ -7,12 +7,12 @@ #include "glass/Model.h" namespace glass { -class DataSource; +class DoubleSource; class MotorControllerModel : public Model { public: virtual const char* GetName() const = 0; virtual const char* GetSimDevice() const = 0; - virtual DataSource* GetPercentData() = 0; + virtual DoubleSource* GetPercentData() = 0; virtual void SetPercent(double value) = 0; }; void DisplayMotorController(MotorControllerModel* m); diff --git a/glass/src/lib/native/include/glass/hardware/PWM.h b/glass/src/lib/native/include/glass/hardware/PWM.h index 74c7461c8ab..184d45a1333 100644 --- a/glass/src/lib/native/include/glass/hardware/PWM.h +++ b/glass/src/lib/native/include/glass/hardware/PWM.h @@ -12,14 +12,14 @@ namespace glass { -class DataSource; +class DoubleSource; class PWMModel : public Model { public: // returns -1 if not an addressable LED virtual int GetAddressableLED() const = 0; - virtual DataSource* GetSpeedData() = 0; + virtual DoubleSource* GetSpeedData() = 0; virtual void SetSpeed(double val) = 0; }; diff --git a/glass/src/lib/native/include/glass/hardware/Pneumatic.h b/glass/src/lib/native/include/glass/hardware/Pneumatic.h index 0e9e525f261..9fcbff3a2b0 100644 --- a/glass/src/lib/native/include/glass/hardware/Pneumatic.h +++ b/glass/src/lib/native/include/glass/hardware/Pneumatic.h @@ -14,14 +14,15 @@ namespace glass { -class DataSource; +class BooleanSource; +class DoubleSource; class CompressorModel : public Model { public: - virtual DataSource* GetRunningData() = 0; - virtual DataSource* GetEnabledData() = 0; - virtual DataSource* GetPressureSwitchData() = 0; - virtual DataSource* GetCurrentData() = 0; + virtual BooleanSource* GetRunningData() = 0; + virtual BooleanSource* GetEnabledData() = 0; + virtual BooleanSource* GetPressureSwitchData() = 0; + virtual DoubleSource* GetCurrentData() = 0; virtual void SetRunning(bool val) = 0; virtual void SetEnabled(bool val) = 0; @@ -31,7 +32,7 @@ class CompressorModel : public Model { class SolenoidModel : public Model { public: - virtual DataSource* GetOutputData() = 0; + virtual BooleanSource* GetOutputData() = 0; virtual void SetOutput(bool val) = 0; }; diff --git a/glass/src/lib/native/include/glass/hardware/PowerDistribution.h b/glass/src/lib/native/include/glass/hardware/PowerDistribution.h index 0ef600637d0..0c6c7b0a62a 100644 --- a/glass/src/lib/native/include/glass/hardware/PowerDistribution.h +++ b/glass/src/lib/native/include/glass/hardware/PowerDistribution.h @@ -12,15 +12,15 @@ namespace glass { -class DataSource; +class DoubleSource; class PowerDistributionModel : public Model { public: virtual int GetNumChannels() const = 0; - virtual DataSource* GetTemperatureData() = 0; - virtual DataSource* GetVoltageData() = 0; - virtual DataSource* GetCurrentData(int channel) = 0; + virtual DoubleSource* GetTemperatureData() = 0; + virtual DoubleSource* GetVoltageData() = 0; + virtual DoubleSource* GetCurrentData(int channel) = 0; virtual void SetTemperature(double val) = 0; virtual void SetVoltage(double val) = 0; diff --git a/glass/src/lib/native/include/glass/hardware/Relay.h b/glass/src/lib/native/include/glass/hardware/Relay.h index b025119b6b0..f320e6d2e2a 100644 --- a/glass/src/lib/native/include/glass/hardware/Relay.h +++ b/glass/src/lib/native/include/glass/hardware/Relay.h @@ -12,12 +12,12 @@ namespace glass { -class DataSource; +class BooleanSource; class RelayModel : public Model { public: - virtual DataSource* GetForwardData() = 0; - virtual DataSource* GetReverseData() = 0; + virtual BooleanSource* GetForwardData() = 0; + virtual BooleanSource* GetReverseData() = 0; virtual void SetForward(bool val) = 0; virtual void SetReverse(bool val) = 0; diff --git a/glass/src/lib/native/include/glass/hardware/RoboRio.h b/glass/src/lib/native/include/glass/hardware/RoboRio.h index df9a2a5d346..063d0cf056d 100644 --- a/glass/src/lib/native/include/glass/hardware/RoboRio.h +++ b/glass/src/lib/native/include/glass/hardware/RoboRio.h @@ -8,14 +8,16 @@ namespace glass { -class DataSource; +class BooleanSource; +class DoubleSource; +class IntegerSource; class RoboRioRailModel : public Model { public: - virtual DataSource* GetVoltageData() = 0; - virtual DataSource* GetCurrentData() = 0; - virtual DataSource* GetActiveData() = 0; - virtual DataSource* GetFaultsData() = 0; + virtual DoubleSource* GetVoltageData() = 0; + virtual DoubleSource* GetCurrentData() = 0; + virtual BooleanSource* GetActiveData() = 0; + virtual IntegerSource* GetFaultsData() = 0; virtual void SetVoltage(double val) = 0; virtual void SetCurrent(double val) = 0; @@ -29,10 +31,10 @@ class RoboRioModel : public Model { virtual RoboRioRailModel* GetUser5VRail() = 0; virtual RoboRioRailModel* GetUser3V3Rail() = 0; - virtual DataSource* GetUserButton() = 0; - virtual DataSource* GetVInVoltageData() = 0; - virtual DataSource* GetVInCurrentData() = 0; - virtual DataSource* GetBrownoutVoltage() = 0; + virtual BooleanSource* GetUserButton() = 0; + virtual DoubleSource* GetVInVoltageData() = 0; + virtual DoubleSource* GetVInCurrentData() = 0; + virtual DoubleSource* GetBrownoutVoltage() = 0; virtual void SetUserButton(bool val) = 0; virtual void SetVInVoltage(double val) = 0; diff --git a/glass/src/lib/native/include/glass/other/CommandSelector.h b/glass/src/lib/native/include/glass/other/CommandSelector.h index e5126f2ad68..3042977743c 100644 --- a/glass/src/lib/native/include/glass/other/CommandSelector.h +++ b/glass/src/lib/native/include/glass/other/CommandSelector.h @@ -7,11 +7,11 @@ #include "glass/Model.h" namespace glass { -class DataSource; +class BooleanSource; class CommandSelectorModel : public Model { public: virtual const char* GetName() const = 0; - virtual DataSource* GetRunningData() = 0; + virtual BooleanSource* GetRunningData() = 0; virtual void SetRunning(bool run) = 0; }; void DisplayCommandSelector(CommandSelectorModel* m); diff --git a/glass/src/lib/native/include/glass/other/Drive.h b/glass/src/lib/native/include/glass/other/Drive.h index c9695829f2f..1fd7dae30c0 100644 --- a/glass/src/lib/native/include/glass/other/Drive.h +++ b/glass/src/lib/native/include/glass/other/Drive.h @@ -15,15 +15,15 @@ struct ImVec2; namespace glass { -class DataSource; +class DoubleSource; class DriveModel : public Model { public: struct WheelInfo { std::string name; - DataSource* percent; + DoubleSource* percent; std::function setter; - WheelInfo(std::string_view name, DataSource* percent, + WheelInfo(std::string_view name, DoubleSource* percent, std::function setter) : name(name), percent(percent), setter(std::move(setter)) {} }; diff --git a/glass/src/lib/native/include/glass/other/FMS.h b/glass/src/lib/native/include/glass/other/FMS.h index f039c15a702..85fda7176ca 100644 --- a/glass/src/lib/native/include/glass/other/FMS.h +++ b/glass/src/lib/native/include/glass/other/FMS.h @@ -15,20 +15,22 @@ class SmallVectorImpl; namespace glass { -class DataSource; +class BooleanSource; +class DoubleSource; +class IntegerSource; +class StringSource; class FMSModel : public Model { public: - virtual DataSource* GetFmsAttachedData() = 0; - virtual DataSource* GetDsAttachedData() = 0; - virtual DataSource* GetAllianceStationIdData() = 0; - virtual DataSource* GetMatchTimeData() = 0; - virtual DataSource* GetEStopData() = 0; - virtual DataSource* GetEnabledData() = 0; - virtual DataSource* GetTestData() = 0; - virtual DataSource* GetAutonomousData() = 0; - virtual std::string_view GetGameSpecificMessage( - wpi::SmallVectorImpl& buf) = 0; + virtual BooleanSource* GetFmsAttachedData() = 0; + virtual BooleanSource* GetDsAttachedData() = 0; + virtual IntegerSource* GetAllianceStationIdData() = 0; + virtual DoubleSource* GetMatchTimeData() = 0; + virtual BooleanSource* GetEStopData() = 0; + virtual BooleanSource* GetEnabledData() = 0; + virtual BooleanSource* GetTestData() = 0; + virtual BooleanSource* GetAutonomousData() = 0; + virtual StringSource* GetGameSpecificMessageData() = 0; virtual void SetFmsAttached(bool val) = 0; virtual void SetDsAttached(bool val) = 0; diff --git a/glass/src/lib/native/include/glass/other/PIDController.h b/glass/src/lib/native/include/glass/other/PIDController.h index 8c11c5914db..429bba9ffe3 100644 --- a/glass/src/lib/native/include/glass/other/PIDController.h +++ b/glass/src/lib/native/include/glass/other/PIDController.h @@ -7,16 +7,16 @@ #include "glass/Model.h" namespace glass { -class DataSource; +class DoubleSource; class PIDControllerModel : public Model { public: virtual const char* GetName() const = 0; - virtual DataSource* GetPData() = 0; - virtual DataSource* GetIData() = 0; - virtual DataSource* GetDData() = 0; - virtual DataSource* GetSetpointData() = 0; - virtual DataSource* GetIZoneData() = 0; + virtual DoubleSource* GetPData() = 0; + virtual DoubleSource* GetIData() = 0; + virtual DoubleSource* GetDData() = 0; + virtual DoubleSource* GetSetpointData() = 0; + virtual DoubleSource* GetIZoneData() = 0; virtual void SetP(double value) = 0; virtual void SetI(double value) = 0; diff --git a/glass/src/lib/native/include/glass/other/ProfiledPIDController.h b/glass/src/lib/native/include/glass/other/ProfiledPIDController.h index a087757da69..7a2e32c2c2d 100644 --- a/glass/src/lib/native/include/glass/other/ProfiledPIDController.h +++ b/glass/src/lib/native/include/glass/other/ProfiledPIDController.h @@ -7,18 +7,18 @@ #include "glass/Model.h" namespace glass { -class DataSource; +class DoubleSource; class ProfiledPIDControllerModel : public Model { public: virtual const char* GetName() const = 0; - virtual DataSource* GetPData() = 0; - virtual DataSource* GetIData() = 0; - virtual DataSource* GetDData() = 0; - virtual DataSource* GetIZoneData() = 0; - virtual DataSource* GetMaxVelocityData() = 0; - virtual DataSource* GetMaxAccelerationData() = 0; - virtual DataSource* GetGoalData() = 0; + virtual DoubleSource* GetPData() = 0; + virtual DoubleSource* GetIData() = 0; + virtual DoubleSource* GetDData() = 0; + virtual DoubleSource* GetIZoneData() = 0; + virtual DoubleSource* GetMaxVelocityData() = 0; + virtual DoubleSource* GetMaxAccelerationData() = 0; + virtual DoubleSource* GetGoalData() = 0; virtual void SetP(double value) = 0; virtual void SetI(double value) = 0; diff --git a/glass/src/lib/native/include/glass/support/ExtraGuiWidgets.h b/glass/src/lib/native/include/glass/support/ExtraGuiWidgets.h index ec4f20ab925..6e6d76408f7 100644 --- a/glass/src/lib/native/include/glass/support/ExtraGuiWidgets.h +++ b/glass/src/lib/native/include/glass/support/ExtraGuiWidgets.h @@ -11,7 +11,7 @@ namespace glass { -class DataSource; +class BooleanSource; /** * DrawLEDs() configuration for 2D arrays. @@ -81,7 +81,7 @@ void DrawLEDs(const int* values, int numValues, int cols, const ImU32* colors, * if 0, defaults to 1/3 of font size * @param config 2D array configuration */ -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 = 0.0f, float spacing = 0.0f, const LEDConfig& config = LEDConfig{}); diff --git a/glass/src/libnt/native/cpp/NTCommandSelector.cpp b/glass/src/libnt/native/cpp/NTCommandSelector.cpp index ce8f8a2e48f..e22a1a71220 100644 --- a/glass/src/libnt/native/cpp/NTCommandSelector.cpp +++ b/glass/src/libnt/native/cpp/NTCommandSelector.cpp @@ -21,9 +21,7 @@ NTCommandSelectorModel::NTCommandSelectorModel(nt::NetworkTableInstance inst, .GetEntry(false)}, m_name{inst.GetStringTopic(fmt::format("{}/.name", path)).Subscribe("")}, m_runningData{fmt::format("NTCmd:{}", path)}, - m_nameValue{wpi::rsplit(path, '/').second} { - m_runningData.SetDigital(true); -} + m_nameValue{wpi::rsplit(path, '/').second} {} void NTCommandSelectorModel::SetRunning(bool run) { m_running.Set(run); diff --git a/glass/src/libnt/native/cpp/NTDigitalInput.cpp b/glass/src/libnt/native/cpp/NTDigitalInput.cpp index e96a041e5fa..6284afd54f2 100644 --- a/glass/src/libnt/native/cpp/NTDigitalInput.cpp +++ b/glass/src/libnt/native/cpp/NTDigitalInput.cpp @@ -21,9 +21,7 @@ NTDigitalInputModel::NTDigitalInputModel(nt::NetworkTableInstance inst, inst.GetBooleanTopic(fmt::format("{}/Value", path)).Subscribe(false)}, m_name{inst.GetStringTopic(fmt::format("{}/.name", path)).Subscribe("")}, m_valueData{fmt::format("NT_DIn:{}", path)}, - m_nameValue{wpi::rsplit(path, '/').second} { - m_valueData.SetDigital(true); -} + m_nameValue{wpi::rsplit(path, '/').second} {} void NTDigitalInputModel::Update() { for (auto&& v : m_value.ReadQueue()) { diff --git a/glass/src/libnt/native/cpp/NTDigitalOutput.cpp b/glass/src/libnt/native/cpp/NTDigitalOutput.cpp index fe9021f97ef..c42516bbe07 100644 --- a/glass/src/libnt/native/cpp/NTDigitalOutput.cpp +++ b/glass/src/libnt/native/cpp/NTDigitalOutput.cpp @@ -21,9 +21,7 @@ NTDigitalOutputModel::NTDigitalOutputModel(nt::NetworkTableInstance inst, m_name{inst.GetStringTopic(fmt::format("{}/.name", path)).Subscribe("")}, m_controllable{inst.GetBooleanTopic(fmt::format("{}/.controllable", path)) .Subscribe(false)}, - m_valueData{fmt::format("NT_DOut:{}", path)} { - m_valueData.SetDigital(true); -} + m_valueData{fmt::format("NT_DOut:{}", path)} {} void NTDigitalOutputModel::SetValue(bool val) { m_value.Set(val); diff --git a/glass/src/libnt/native/cpp/NTFMS.cpp b/glass/src/libnt/native/cpp/NTFMS.cpp index 65ffa6a435f..c968b763a0e 100644 --- a/glass/src/libnt/native/cpp/NTFMS.cpp +++ b/glass/src/libnt/native/cpp/NTFMS.cpp @@ -32,19 +32,9 @@ NTFMSModel::NTFMSModel(nt::NetworkTableInstance inst, std::string_view path) m_estop{fmt::format("NT_FMS:EStop:{}", path)}, m_enabled{fmt::format("NT_FMS:RobotEnabled:{}", path)}, m_test{fmt::format("NT_FMS:TestMode:{}", path)}, - m_autonomous{fmt::format("NT_FMS:AutonomousMode:{}", path)} { - m_fmsAttached.SetDigital(true); - m_dsAttached.SetDigital(true); - m_estop.SetDigital(true); - m_enabled.SetDigital(true); - m_test.SetDigital(true); - m_autonomous.SetDigital(true); -} - -std::string_view NTFMSModel::GetGameSpecificMessage( - wpi::SmallVectorImpl& buf) { - return m_gameSpecificMessage.Get(buf, ""); -} + m_autonomous{fmt::format("NT_FMS:AutonomousMode:{}", path)}, + m_gameSpecificMessageData{ + fmt::format("NT_FMS:GameSpecificMessage:{}", path)} {} void NTFMSModel::Update() { for (auto&& v : m_alliance.ReadQueue()) { @@ -70,6 +60,9 @@ void NTFMSModel::Update() { m_fmsAttached.SetValue(((controlWord & 0x10) != 0) ? 1 : 0, v.time); m_dsAttached.SetValue(((controlWord & 0x20) != 0) ? 1 : 0, v.time); } + for (auto&& v : m_gameSpecificMessage.ReadQueue()) { + m_gameSpecificMessageData.SetValue(std::move(v.value), v.time); + } } bool NTFMSModel::Exists() { diff --git a/glass/src/libnt/native/cpp/NetworkTables.cpp b/glass/src/libnt/native/cpp/NetworkTables.cpp index d661ee5f05f..3a9ccfc9760 100644 --- a/glass/src/libnt/native/cpp/NetworkTables.cpp +++ b/glass/src/libnt/native/cpp/NetworkTables.cpp @@ -631,20 +631,39 @@ static void UpdateJsonValueSource(NetworkTablesModel& model, } } +template void NetworkTablesModel::ValueSource::UpdateDiscreteSource( - std::string_view name, double value, int64_t time, bool digital) { + std::string_view name, T value, int64_t time) { valueChildren.clear(); - if (!source) { - source = std::make_unique(fmt::format("NT:{}", name)); + if constexpr (std::same_as) { + if (!source || source->GetKind() != DataSource::kBoolean) { + source = std::make_unique(fmt::format("NT:{}", name)); + } + static_cast(source.get())->SetValue(value, time); + } else if constexpr (std::same_as) { + if (!source || source->GetKind() != DataSource::kDouble) { + source = std::make_unique(fmt::format("NT:{}", name)); + } + static_cast(source.get())->SetValue(value, time); + } else if constexpr (std::same_as) { + if (!source || source->GetKind() != DataSource::kFloat) { + source = std::make_unique(fmt::format("NT:{}", name)); + } + static_cast(source.get())->SetValue(value, time); + } else if constexpr (std::same_as) { + if (!source || source->GetKind() != DataSource::kInteger) { + source = std::make_unique(fmt::format("NT:{}", name)); + } + static_cast(source.get())->SetValue(value, time); + } else { + static_assert(false, "Unknown type"); } - source->SetValue(value, time); - source->SetDigital(digital); } -template +template void NetworkTablesModel::ValueSource::UpdateDiscreteArray( std::string_view name, std::span arr, int64_t time, - MakeValue makeValue, bool digital) { + MakeValue makeValue) { if (valueChildrenMap) { valueChildren.clear(); valueChildrenMap = false; @@ -657,7 +676,11 @@ void NetworkTablesModel::ValueSource::UpdateDiscreteArray( child.path = fmt::format("{}{}", name, child.name); } child.value = makeValue(arr[i], time); - child.UpdateDiscreteSource(child.path, arr[i], time, digital); + if constexpr (IsBoolean) { + child.UpdateDiscreteSource(child.path, static_cast(arr[i]), time); + } else { + child.UpdateDiscreteSource(child.path, arr[i], time); + } ++i; } } @@ -667,8 +690,7 @@ void NetworkTablesModel::ValueSource::UpdateFromValue( std::string_view typeStr) { switch (value.type()) { case NT_BOOLEAN: - UpdateDiscreteSource(name, value.GetBoolean() ? 1 : 0, value.time(), - true); + UpdateDiscreteSource(name, value.GetBoolean(), value.time()); break; case NT_INTEGER: UpdateDiscreteSource(name, value.GetInteger(), value.time()); @@ -680,20 +702,20 @@ void NetworkTablesModel::ValueSource::UpdateFromValue( UpdateDiscreteSource(name, value.GetDouble(), value.time()); break; case NT_BOOLEAN_ARRAY: - UpdateDiscreteArray(name, value.GetBooleanArray(), value.time(), - nt::Value::MakeBoolean, true); + UpdateDiscreteArray(name, value.GetBooleanArray(), value.time(), + nt::Value::MakeBoolean); break; case NT_INTEGER_ARRAY: - UpdateDiscreteArray(name, value.GetIntegerArray(), value.time(), - nt::Value::MakeInteger); + UpdateDiscreteArray(name, value.GetIntegerArray(), value.time(), + nt::Value::MakeInteger); break; case NT_FLOAT_ARRAY: - UpdateDiscreteArray(name, value.GetFloatArray(), value.time(), - nt::Value::MakeFloat); + UpdateDiscreteArray(name, value.GetFloatArray(), value.time(), + nt::Value::MakeFloat); break; case NT_DOUBLE_ARRAY: - UpdateDiscreteArray(name, value.GetDoubleArray(), value.time(), - nt::Value::MakeDouble); + UpdateDiscreteArray(name, value.GetDoubleArray(), value.time(), + nt::Value::MakeDouble); break; case NT_STRING_ARRAY: { auto arr = value.GetStringArray(); @@ -729,6 +751,11 @@ void NetworkTablesModel::ValueSource::UpdateFromValue( os << '"'; os.write_escaped(value.GetString()); os << '"'; + if (!source || source->GetKind() != DataSource::kString) { + source = std::make_unique(fmt::format("NT:{}", name)); + } + static_cast(source.get()) + ->SetValue(value.GetString(), value.time()); } break; case NT_RAW: diff --git a/glass/src/libnt/native/include/glass/networktables/NTCommandSelector.h b/glass/src/libnt/native/include/glass/networktables/NTCommandSelector.h index ab354845e7a..6223074b760 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTCommandSelector.h +++ b/glass/src/libnt/native/include/glass/networktables/NTCommandSelector.h @@ -23,7 +23,7 @@ class NTCommandSelectorModel : public CommandSelectorModel { NTCommandSelectorModel(nt::NetworkTableInstance inst, std::string_view path); const char* GetName() const override { return m_nameValue.c_str(); } - DataSource* GetRunningData() override { return &m_runningData; } + BooleanSource* GetRunningData() override { return &m_runningData; } void SetRunning(bool run) override; void Update() override; @@ -35,7 +35,7 @@ class NTCommandSelectorModel : public CommandSelectorModel { nt::BooleanEntry m_running; nt::StringSubscriber m_name; - DataSource m_runningData; + BooleanSource m_runningData; std::string m_nameValue; }; } // namespace glass diff --git a/glass/src/libnt/native/include/glass/networktables/NTDifferentialDrive.h b/glass/src/libnt/native/include/glass/networktables/NTDifferentialDrive.h index 5e346692047..8da76852eed 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTDifferentialDrive.h +++ b/glass/src/libnt/native/include/glass/networktables/NTDifferentialDrive.h @@ -46,8 +46,8 @@ class NTDifferentialDriveModel : public DriveModel { std::string m_nameValue; bool m_controllableValue = false; - DataSource m_lPercentData; - DataSource m_rPercentData; + DoubleSource m_lPercentData; + DoubleSource m_rPercentData; std::vector m_wheels; ImVec2 m_speedVector; diff --git a/glass/src/libnt/native/include/glass/networktables/NTDigitalInput.h b/glass/src/libnt/native/include/glass/networktables/NTDigitalInput.h index 7aa9234761a..49a8b53de80 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTDigitalInput.h +++ b/glass/src/libnt/native/include/glass/networktables/NTDigitalInput.h @@ -34,7 +34,7 @@ class NTDigitalInputModel : public DIOModel { bool IsInput() const override { return true; } - DataSource* GetValueData() override { return &m_valueData; } + BooleanSource* GetValueData() override { return &m_valueData; } void SetValue(bool val) override {} @@ -47,7 +47,7 @@ class NTDigitalInputModel : public DIOModel { nt::BooleanSubscriber m_value; nt::StringSubscriber m_name; - DataSource m_valueData; + BooleanSource m_valueData; std::string m_nameValue; }; diff --git a/glass/src/libnt/native/include/glass/networktables/NTDigitalOutput.h b/glass/src/libnt/native/include/glass/networktables/NTDigitalOutput.h index fb6a15153dc..6fd1ed17824 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTDigitalOutput.h +++ b/glass/src/libnt/native/include/glass/networktables/NTDigitalOutput.h @@ -34,7 +34,7 @@ class NTDigitalOutputModel : public DIOModel { bool IsInput() const override { return true; } - DataSource* GetValueData() override { return &m_valueData; } + BooleanSource* GetValueData() override { return &m_valueData; } void SetValue(bool val) override; @@ -48,7 +48,7 @@ class NTDigitalOutputModel : public DIOModel { nt::StringSubscriber m_name; nt::BooleanSubscriber m_controllable; - DataSource m_valueData; + BooleanSource m_valueData; std::string m_nameValue; bool m_controllableValue = false; }; diff --git a/glass/src/libnt/native/include/glass/networktables/NTFMS.h b/glass/src/libnt/native/include/glass/networktables/NTFMS.h index 5898080f128..5b6b6e01baa 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTFMS.h +++ b/glass/src/libnt/native/include/glass/networktables/NTFMS.h @@ -24,19 +24,20 @@ class NTFMSModel : public FMSModel { explicit NTFMSModel(std::string_view path); NTFMSModel(nt::NetworkTableInstance inst, std::string_view path); - DataSource* GetFmsAttachedData() override { return &m_fmsAttached; } - DataSource* GetDsAttachedData() override { return &m_dsAttached; } - DataSource* GetAllianceStationIdData() override { + BooleanSource* GetFmsAttachedData() override { return &m_fmsAttached; } + BooleanSource* GetDsAttachedData() override { return &m_dsAttached; } + IntegerSource* GetAllianceStationIdData() override { return &m_allianceStationId; } // NT does not provide match time - DataSource* GetMatchTimeData() override { return nullptr; } - DataSource* GetEStopData() override { return &m_estop; } - DataSource* GetEnabledData() override { return &m_enabled; } - DataSource* GetTestData() override { return &m_test; } - DataSource* GetAutonomousData() override { return &m_autonomous; } - std::string_view GetGameSpecificMessage( - wpi::SmallVectorImpl& buf) override; + DoubleSource* GetMatchTimeData() override { return nullptr; } + BooleanSource* GetEStopData() override { return &m_estop; } + BooleanSource* GetEnabledData() override { return &m_enabled; } + BooleanSource* GetTestData() override { return &m_test; } + BooleanSource* GetAutonomousData() override { return &m_autonomous; } + StringSource* GetGameSpecificMessageData() override { + return &m_gameSpecificMessageData; + } // NT is read-only (it's continually set by robot code) void SetFmsAttached(bool val) override {} @@ -60,13 +61,14 @@ class NTFMSModel : public FMSModel { nt::IntegerSubscriber m_station; nt::IntegerSubscriber m_controlWord; - DataSource m_fmsAttached; - DataSource m_dsAttached; - DataSource m_allianceStationId; - DataSource m_estop; - DataSource m_enabled; - DataSource m_test; - DataSource m_autonomous; + BooleanSource m_fmsAttached; + BooleanSource m_dsAttached; + IntegerSource m_allianceStationId; + BooleanSource m_estop; + BooleanSource m_enabled; + BooleanSource m_test; + BooleanSource m_autonomous; + StringSource m_gameSpecificMessageData; }; } // namespace glass diff --git a/glass/src/libnt/native/include/glass/networktables/NTGyro.h b/glass/src/libnt/native/include/glass/networktables/NTGyro.h index dc91acc4518..92b5303eaa4 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTGyro.h +++ b/glass/src/libnt/native/include/glass/networktables/NTGyro.h @@ -25,7 +25,7 @@ class NTGyroModel : public GyroModel { const char* GetName() const override { return m_nameValue.c_str(); } const char* GetSimDevice() const override { return nullptr; } - DataSource* GetAngleData() override { return &m_angleData; } + DoubleSource* GetAngleData() override { return &m_angleData; } void SetAngle(double value) override {} void Update() override; @@ -37,7 +37,7 @@ class NTGyroModel : public GyroModel { nt::DoubleSubscriber m_angle; nt::StringSubscriber m_name; - DataSource m_angleData; + DoubleSource m_angleData; std::string m_nameValue; }; } // namespace glass diff --git a/glass/src/libnt/native/include/glass/networktables/NTMecanumDrive.h b/glass/src/libnt/native/include/glass/networktables/NTMecanumDrive.h index 38895bc1b4e..1ec318698e0 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTMecanumDrive.h +++ b/glass/src/libnt/native/include/glass/networktables/NTMecanumDrive.h @@ -47,10 +47,10 @@ class NTMecanumDriveModel : public DriveModel { std::string m_nameValue; bool m_controllableValue = false; - DataSource m_flPercentData; - DataSource m_frPercentData; - DataSource m_rlPercentData; - DataSource m_rrPercentData; + DoubleSource m_flPercentData; + DoubleSource m_frPercentData; + DoubleSource m_rlPercentData; + DoubleSource m_rrPercentData; std::vector m_wheels; ImVec2 m_speedVector; diff --git a/glass/src/libnt/native/include/glass/networktables/NTMotorController.h b/glass/src/libnt/native/include/glass/networktables/NTMotorController.h index 574a55b2dcd..5a2af5d8a46 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTMotorController.h +++ b/glass/src/libnt/native/include/glass/networktables/NTMotorController.h @@ -26,7 +26,7 @@ class NTMotorControllerModel : public MotorControllerModel { const char* GetName() const override { return m_nameValue.c_str(); } const char* GetSimDevice() const override { return nullptr; } - DataSource* GetPercentData() override { return &m_valueData; } + DoubleSource* GetPercentData() override { return &m_valueData; } void SetPercent(double value) override; void Update() override; @@ -39,7 +39,7 @@ class NTMotorControllerModel : public MotorControllerModel { nt::StringSubscriber m_name; nt::BooleanSubscriber m_controllable; - DataSource m_valueData; + DoubleSource m_valueData; std::string m_nameValue; bool m_controllableValue = false; }; diff --git a/glass/src/libnt/native/include/glass/networktables/NTPIDController.h b/glass/src/libnt/native/include/glass/networktables/NTPIDController.h index d19dcea2de6..672483dbbd0 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTPIDController.h +++ b/glass/src/libnt/native/include/glass/networktables/NTPIDController.h @@ -25,11 +25,11 @@ class NTPIDControllerModel : public PIDControllerModel { const char* GetName() const override { return m_nameValue.c_str(); } - DataSource* GetPData() override { return &m_pData; } - DataSource* GetIData() override { return &m_iData; } - DataSource* GetDData() override { return &m_dData; } - DataSource* GetSetpointData() override { return &m_setpointData; } - DataSource* GetIZoneData() override { return &m_iZoneData; } + DoubleSource* GetPData() override { return &m_pData; } + DoubleSource* GetIData() override { return &m_iData; } + DoubleSource* GetDData() override { return &m_dData; } + DoubleSource* GetSetpointData() override { return &m_setpointData; } + DoubleSource* GetIZoneData() override { return &m_iZoneData; } void SetP(double value) override; void SetI(double value) override; @@ -51,11 +51,11 @@ class NTPIDControllerModel : public PIDControllerModel { nt::DoubleEntry m_setpoint; nt::DoubleEntry m_iZone; - DataSource m_pData; - DataSource m_iData; - DataSource m_dData; - DataSource m_setpointData; - DataSource m_iZoneData; + DoubleSource m_pData; + DoubleSource m_iData; + DoubleSource m_dData; + DoubleSource m_setpointData; + DoubleSource m_iZoneData; std::string m_nameValue; bool m_controllableValue = false; diff --git a/glass/src/libnt/native/include/glass/networktables/NTProfiledPIDController.h b/glass/src/libnt/native/include/glass/networktables/NTProfiledPIDController.h index 2197354157e..b7e2f991fd9 100644 --- a/glass/src/libnt/native/include/glass/networktables/NTProfiledPIDController.h +++ b/glass/src/libnt/native/include/glass/networktables/NTProfiledPIDController.h @@ -26,15 +26,15 @@ class NTProfiledPIDControllerModel : public ProfiledPIDControllerModel { const char* GetName() const override { return m_nameValue.c_str(); } - DataSource* GetPData() override { return &m_pData; } - DataSource* GetIData() override { return &m_iData; } - DataSource* GetDData() override { return &m_dData; } - DataSource* GetIZoneData() override { return &m_iZoneData; } - DataSource* GetMaxVelocityData() override { return &m_maxVelocityData; } - DataSource* GetMaxAccelerationData() override { + DoubleSource* GetPData() override { return &m_pData; } + DoubleSource* GetIData() override { return &m_iData; } + DoubleSource* GetDData() override { return &m_dData; } + DoubleSource* GetIZoneData() override { return &m_iZoneData; } + DoubleSource* GetMaxVelocityData() override { return &m_maxVelocityData; } + DoubleSource* GetMaxAccelerationData() override { return &m_maxAccelerationData; } - DataSource* GetGoalData() override { return &m_goalData; } + DoubleSource* GetGoalData() override { return &m_goalData; } void SetP(double value) override; void SetI(double value) override; @@ -60,13 +60,13 @@ class NTProfiledPIDControllerModel : public ProfiledPIDControllerModel { nt::DoubleEntry m_maxAcceleration; nt::DoubleEntry m_goal; - DataSource m_pData; - DataSource m_iData; - DataSource m_dData; - DataSource m_iZoneData; - DataSource m_maxVelocityData; - DataSource m_maxAccelerationData; - DataSource m_goalData; + DoubleSource m_pData; + DoubleSource m_iData; + DoubleSource m_dData; + DoubleSource m_iZoneData; + DoubleSource m_maxVelocityData; + DoubleSource m_maxAccelerationData; + DoubleSource m_goalData; std::string m_nameValue; bool m_controllableValue = false; diff --git a/glass/src/libnt/native/include/glass/networktables/NetworkTables.h b/glass/src/libnt/native/include/glass/networktables/NetworkTables.h index bca5a411925..b45c74682a7 100644 --- a/glass/src/libnt/native/include/glass/networktables/NetworkTables.h +++ b/glass/src/libnt/native/include/glass/networktables/NetworkTables.h @@ -58,13 +58,12 @@ class NetworkTablesModel : public Model { bool valueChildrenMap = false; private: - void UpdateDiscreteSource(std::string_view name, double value, int64_t time, - bool digital = false); + template + void UpdateDiscreteSource(std::string_view name, T value, int64_t time); - template + template void UpdateDiscreteArray(std::string_view name, std::span arr, - int64_t time, MakeValue makeValue, - bool digital = false); + int64_t time, MakeValue makeValue); }; struct EntryValueTreeNode : public ValueSource { diff --git a/simulation/halsim_gui/src/main/native/cpp/AccelerometerSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/AccelerometerSimGui.cpp index 115b4ecef50..b7f4e40cb52 100644 --- a/simulation/halsim_gui/src/main/native/cpp/AccelerometerSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/AccelerometerSimGui.cpp @@ -32,9 +32,9 @@ class AccelerometerSimModel : public glass::AccelerometerModel { bool Exists() override { return HALSIM_GetAccelerometerActive(m_index); } - glass::DataSource* GetXData() override { return &m_xData; } - glass::DataSource* GetYData() override { return &m_yData; } - glass::DataSource* GetZData() override { return &m_zData; } + glass::DoubleSource* GetXData() override { return &m_xData; } + glass::DoubleSource* GetYData() override { return &m_yData; } + glass::DoubleSource* GetZData() override { return &m_zData; } int GetRange() override { return HALSIM_GetAccelerometerRange(m_index); } diff --git a/simulation/halsim_gui/src/main/native/cpp/AnalogGyroSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/AnalogGyroSimGui.cpp index 4bd328f4e46..62c064661b2 100644 --- a/simulation/halsim_gui/src/main/native/cpp/AnalogGyroSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/AnalogGyroSimGui.cpp @@ -32,8 +32,8 @@ class AnalogGyroSimModel : public glass::AnalogGyroModel { bool Exists() override { return HALSIM_GetAnalogGyroInitialized(m_index); } - glass::DataSource* GetAngleData() override { return &m_angle; } - glass::DataSource* GetRateData() override { return &m_rate; } + glass::DoubleSource* GetAngleData() override { return &m_angle; } + glass::DoubleSource* GetRateData() override { return &m_rate; } void SetAngle(double val) override { HALSIM_SetAnalogGyroAngle(m_index, val); diff --git a/simulation/halsim_gui/src/main/native/cpp/AnalogInputSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/AnalogInputSimGui.cpp index 4a428b602ab..dfefe5051c4 100644 --- a/simulation/halsim_gui/src/main/native/cpp/AnalogInputSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/AnalogInputSimGui.cpp @@ -44,7 +44,7 @@ class AnalogInputSimModel : public glass::AnalogInputModel { } } - glass::DataSource* GetVoltageData() override { return &m_voltageData; } + glass::DoubleSource* GetVoltageData() override { return &m_voltageData; } void SetVoltage(double val) override { HALSIM_SetAnalogInVoltage(m_index, val); diff --git a/simulation/halsim_gui/src/main/native/cpp/AnalogOutputSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/AnalogOutputSimGui.cpp index 7a98bed575c..0f84cc1bd83 100644 --- a/simulation/halsim_gui/src/main/native/cpp/AnalogOutputSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/AnalogOutputSimGui.cpp @@ -30,7 +30,7 @@ class AnalogOutputSimModel : public glass::AnalogOutputModel { bool Exists() override { return HALSIM_GetAnalogOutInitialized(m_index); } - glass::DataSource* GetVoltageData() override { return &m_voltageData; } + glass::DoubleSource* GetVoltageData() override { return &m_voltageData; } void SetVoltage(double val) override { HALSIM_SetAnalogOutVoltage(m_index, val); diff --git a/simulation/halsim_gui/src/main/native/cpp/DIOSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/DIOSimGui.cpp index 13ec169406b..fb24d97b8f3 100644 --- a/simulation/halsim_gui/src/main/native/cpp/DIOSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/DIOSimGui.cpp @@ -44,7 +44,7 @@ class DPWMSimModel : public glass::DPWMModel { } } - glass::DataSource* GetValueData() override { return &m_valueData; } + glass::DoubleSource* GetValueData() override { return &m_valueData; } void SetValue(double val) override { HALSIM_SetDigitalPWMDutyCycle(m_index, val); @@ -73,7 +73,7 @@ class DutyCycleSimModel : public glass::DutyCycleModel { } } - glass::DataSource* GetValueData() override { return &m_valueData; } + glass::DoubleSource* GetValueData() override { return &m_valueData; } void SetValue(double val) override { HALSIM_SetDutyCycleOutput(m_index, val); @@ -115,7 +115,7 @@ class DIOSimModel : public glass::DIOModel { bool IsInput() const override { return HALSIM_GetDIOIsInput(m_channel); } - glass::DataSource* GetValueData() override { return &m_valueData; } + glass::BooleanSource* GetValueData() override { return &m_valueData; } void SetValue(bool val) override { HALSIM_SetDIOValue(m_channel, val); } diff --git a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp index 3ed8fa71127..cdc46f1a8aa 100644 --- a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp @@ -197,11 +197,11 @@ class JoystickModel { int axisCount; int buttonCount; int povCount; - std::unique_ptr axes[HAL_kMaxJoystickAxes]; + std::unique_ptr axes[HAL_kMaxJoystickAxes]; // use pointer instead of unique_ptr to allow it to be passed directly // to DrawLEDSources() - glass::DataSource* buttons[32]; - std::unique_ptr povs[HAL_kMaxJoystickPOVs]; + glass::BooleanSource* buttons[32]; + std::unique_ptr povs[HAL_kMaxJoystickPOVs]; private: static void CallbackFunc(const char*, void* param, const HAL_Value*); @@ -214,19 +214,18 @@ class FMSSimModel : public glass::FMSModel { public: FMSSimModel(); - glass::DataSource* GetFmsAttachedData() override { return &m_fmsAttached; } - glass::DataSource* GetDsAttachedData() override { return &m_dsAttached; } - glass::DataSource* GetAllianceStationIdData() override { + glass::BooleanSource* GetFmsAttachedData() override { return &m_fmsAttached; } + glass::BooleanSource* GetDsAttachedData() override { return &m_dsAttached; } + glass::IntegerSource* GetAllianceStationIdData() override { return &m_allianceStationId; } - glass::DataSource* GetMatchTimeData() override { return &m_matchTime; } - glass::DataSource* GetEStopData() override { return &m_estop; } - glass::DataSource* GetEnabledData() override { return &m_enabled; } - glass::DataSource* GetTestData() override { return &m_test; } - glass::DataSource* GetAutonomousData() override { return &m_autonomous; } - std::string_view GetGameSpecificMessage( - wpi::SmallVectorImpl& buf) override { - return m_gameMessage; + glass::DoubleSource* GetMatchTimeData() override { return &m_matchTime; } + glass::BooleanSource* GetEStopData() override { return &m_estop; } + glass::BooleanSource* GetEnabledData() override { return &m_enabled; } + glass::BooleanSource* GetTestData() override { return &m_test; } + glass::BooleanSource* GetAutonomousData() override { return &m_autonomous; } + glass::StringSource* GetGameSpecificMessageData() override { + return &m_gameMessage; } void SetFmsAttached(bool val) override { m_fmsAttached.SetValue(val); } @@ -240,7 +239,7 @@ class FMSSimModel : public glass::FMSModel { void SetTest(bool val) override { m_test.SetValue(val); } void SetAutonomous(bool val) override { m_autonomous.SetValue(val); } void SetGameSpecificMessage(std::string_view val) override { - m_gameMessage = val; + m_gameMessage.SetValue(val); } void UpdateHAL(); @@ -252,16 +251,16 @@ class FMSSimModel : public glass::FMSModel { bool IsReadOnly() override; private: - glass::DataSource m_fmsAttached{"FMS:FMSAttached"}; - glass::DataSource m_dsAttached{"FMS:DSAttached"}; - glass::DataSource m_allianceStationId{"FMS:AllianceStationID"}; - glass::DataSource m_matchTime{"FMS:MatchTime"}; - glass::DataSource m_estop{"FMS:EStop"}; - glass::DataSource m_enabled{"FMS:RobotEnabled"}; - glass::DataSource m_test{"FMS:TestMode"}; - glass::DataSource m_autonomous{"FMS:AutonomousMode"}; + glass::BooleanSource m_fmsAttached{"FMS:FMSAttached"}; + glass::BooleanSource m_dsAttached{"FMS:DSAttached"}; + glass::IntegerSource m_allianceStationId{"FMS:AllianceStationID"}; + glass::DoubleSource m_matchTime{"FMS:MatchTime"}; + glass::BooleanSource m_estop{"FMS:EStop"}; + glass::BooleanSource m_enabled{"FMS:RobotEnabled"}; + glass::BooleanSource m_test{"FMS:TestMode"}; + glass::BooleanSource m_autonomous{"FMS:AutonomousMode"}; double m_startMatchTime = -1.0; - std::string m_gameMessage; + glass::StringSource m_gameMessage{"FMS:GameSpecificMessage"}; }; } // namespace @@ -297,7 +296,7 @@ JoystickModel::JoystickModel(int index) : m_index{index} { HALSIM_GetJoystickAxes(index, &halAxes); axisCount = halAxes.count; for (int i = 0; i < axisCount; ++i) { - axes[i] = std::make_unique( + axes[i] = std::make_unique( fmt::format("Joystick[{}] Axis[{}]", index, i)); } @@ -305,9 +304,8 @@ JoystickModel::JoystickModel(int index) : m_index{index} { HALSIM_GetJoystickButtons(index, &halButtons); buttonCount = halButtons.count; for (int i = 0; i < buttonCount; ++i) { - buttons[i] = new glass::DataSource( + buttons[i] = new glass::BooleanSource( fmt::format("Joystick[{}] Button[{}]", index, i + 1)); - buttons[i]->SetDigital(true); } for (int i = buttonCount; i < 32; ++i) { buttons[i] = nullptr; @@ -317,7 +315,7 @@ JoystickModel::JoystickModel(int index) : m_index{index} { HALSIM_GetJoystickPOVs(index, &halPOVs); povCount = halPOVs.count; for (int i = 0; i < povCount; ++i) { - povs[i] = std::make_unique( + povs[i] = std::make_unique( fmt::format("Joystick[{}] POV [{}]", index, i)); } @@ -1149,12 +1147,6 @@ static void DriverStationExecute() { } FMSSimModel::FMSSimModel() { - m_fmsAttached.SetDigital(true); - m_dsAttached.SetDigital(true); - m_estop.SetDigital(true); - m_enabled.SetDigital(true); - m_test.SetDigital(true); - m_autonomous.SetDigital(true); m_matchTime.SetValue(-1.0); m_allianceStationId.SetValue(HAL_AllianceStationID_kRed1); } @@ -1168,7 +1160,7 @@ void FMSSimModel::UpdateHAL() { HALSIM_SetDriverStationTest(m_test.GetValue()); HALSIM_SetDriverStationAutonomous(m_autonomous.GetValue()); HALSIM_SetDriverStationMatchTime(m_matchTime.GetValue()); - auto str = wpi::make_string(m_gameMessage); + auto str = wpi::make_string(m_gameMessage.GetValue()); HALSIM_SetGameSpecificMessage(&str); HALSIM_SetDriverStationDsAttached(m_dsAttached.GetValue()); } @@ -1206,8 +1198,10 @@ void FMSSimModel::Update() { HAL_MatchInfo info; HALSIM_GetMatchInfo(&info); - m_gameMessage.assign(info.gameSpecificMessage, - info.gameSpecificMessage + info.gameSpecificMessageSize); + m_gameMessage.SetValue( + std::string_view{reinterpret_cast(info.gameSpecificMessage), + reinterpret_cast(info.gameSpecificMessage) + + info.gameSpecificMessageSize}); } bool FMSSimModel::IsReadOnly() { diff --git a/simulation/halsim_gui/src/main/native/cpp/EncoderSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/EncoderSimGui.cpp index 8e53c864d6f..9af9db17e7a 100644 --- a/simulation/halsim_gui/src/main/native/cpp/EncoderSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/EncoderSimGui.cpp @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include -#include "HALDataSource.h" #include "HALSimGui.h" using namespace halsimgui; @@ -45,9 +45,7 @@ class EncoderSimModel : public glass::EncoderModel { m_periodCallback{HALSIM_RegisterEncoderPeriodCallback( index, PeriodCallbackFunc, this, true)}, m_directionCallback{HALSIM_RegisterEncoderDirectionCallback( - index, DirectionCallbackFunc, this, true)} { - m_direction.SetDigital(true); - } + index, DirectionCallbackFunc, this, true)} {} EncoderSimModel(int32_t index, int channelA, int channelB) : EncoderSimModel(fmt::format("Encoder[{},{}]", channelA, channelB), @@ -90,14 +88,14 @@ class EncoderSimModel : public glass::EncoderModel { int GetChannelA() const override { return m_channelA; } int GetChannelB() const override { return m_channelB; } - glass::DataSource* GetDistancePerPulseData() override { + glass::DoubleSource* GetDistancePerPulseData() override { return &m_distancePerPulse; } - glass::DataSource* GetCountData() override { return &m_count; } - glass::DataSource* GetPeriodData() override { return &m_period; } - glass::DataSource* GetDirectionData() override { return &m_direction; } - glass::DataSource* GetDistanceData() override { return &m_distance; } - glass::DataSource* GetRateData() override { return &m_rate; } + glass::IntegerSource* GetCountData() override { return &m_count; } + glass::DoubleSource* GetPeriodData() override { return &m_period; } + glass::BooleanSource* GetDirectionData() override { return &m_direction; } + glass::DoubleSource* GetDistanceData() override { return &m_distance; } + glass::DoubleSource* GetRateData() override { return &m_rate; } double GetMaxPeriod() override { return HALSIM_GetEncoderMaxPeriod(m_index); } bool GetReverseDirection() override { @@ -178,12 +176,12 @@ class EncoderSimModel : public glass::EncoderModel { } } - glass::DataSource m_distancePerPulse; - glass::DataSource m_count; - glass::DataSource m_period; - glass::DataSource m_direction; - glass::DataSource m_distance; - glass::DataSource m_rate; + glass::DoubleSource m_distancePerPulse; + glass::IntegerSource m_count; + glass::DoubleSource m_period; + glass::BooleanSource m_direction; + glass::DoubleSource m_distance; + glass::DoubleSource m_rate; int32_t m_index; int m_channelA; diff --git a/simulation/halsim_gui/src/main/native/cpp/PCMSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/PCMSimGui.cpp index 019a86c76cf..fd8bd6d493e 100644 --- a/simulation/halsim_gui/src/main/native/cpp/PCMSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/PCMSimGui.cpp @@ -41,12 +41,12 @@ class CompressorSimModel : public glass::CompressorModel { bool Exists() override { return HALSIM_GetCTREPCMInitialized(m_index); } - glass::DataSource* GetRunningData() override { return &m_running; } - glass::DataSource* GetEnabledData() override { return &m_enabled; } - glass::DataSource* GetPressureSwitchData() override { + glass::BooleanSource* GetRunningData() override { return &m_running; } + glass::BooleanSource* GetEnabledData() override { return &m_enabled; } + glass::BooleanSource* GetPressureSwitchData() override { return &m_pressureSwitch; } - glass::DataSource* GetCurrentData() override { return &m_current; } + glass::DoubleSource* GetCurrentData() override { return &m_current; } void SetRunning(bool val) override { HALSIM_SetCTREPCMCompressorOn(m_index, val); @@ -78,7 +78,7 @@ class SolenoidSimModel : public glass::SolenoidModel { bool Exists() override { return HALSIM_GetCTREPCMInitialized(m_index); } - glass::DataSource* GetOutputData() override { return &m_output; } + glass::BooleanSource* GetOutputData() override { return &m_output; } void SetOutput(bool val) override { HALSIM_SetCTREPCMSolenoidOutput(m_index, m_channel, val); diff --git a/simulation/halsim_gui/src/main/native/cpp/PHSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/PHSimGui.cpp index 0fc66914c7b..abd0a0d7d72 100644 --- a/simulation/halsim_gui/src/main/native/cpp/PHSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/PHSimGui.cpp @@ -39,12 +39,12 @@ class CompressorSimModel : public glass::CompressorModel { bool Exists() override { return HALSIM_GetREVPHInitialized(m_index); } - glass::DataSource* GetRunningData() override { return &m_running; } - glass::DataSource* GetEnabledData() override { return nullptr; } - glass::DataSource* GetPressureSwitchData() override { + glass::BooleanSource* GetRunningData() override { return &m_running; } + glass::BooleanSource* GetEnabledData() override { return nullptr; } + glass::BooleanSource* GetPressureSwitchData() override { return &m_pressureSwitch; } - glass::DataSource* GetCurrentData() override { return &m_current; } + glass::DoubleSource* GetCurrentData() override { return &m_current; } void SetRunning(bool val) override { HALSIM_SetREVPHCompressorOn(m_index, val); @@ -73,7 +73,7 @@ class SolenoidSimModel : public glass::SolenoidModel { bool Exists() override { return HALSIM_GetREVPHInitialized(m_index); } - glass::DataSource* GetOutputData() override { return &m_output; } + glass::BooleanSource* GetOutputData() override { return &m_output; } void SetOutput(bool val) override { HALSIM_SetREVPHSolenoidOutput(m_index, m_channel, val); diff --git a/simulation/halsim_gui/src/main/native/cpp/PWMSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/PWMSimGui.cpp index 2a60f9f4ef0..74e4cb8fa32 100644 --- a/simulation/halsim_gui/src/main/native/cpp/PWMSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/PWMSimGui.cpp @@ -31,7 +31,7 @@ class PWMSimModel : public glass::PWMModel { void SetAddressableLED(int led) { m_led = led; } int GetAddressableLED() const override { return m_led; } - glass::DataSource* GetSpeedData() override { return &m_speed; } + glass::DoubleSource* GetSpeedData() override { return &m_speed; } void SetSpeed(double val) override { HALSIM_SetPWMSpeed(m_index, val); } diff --git a/simulation/halsim_gui/src/main/native/cpp/PowerDistributionSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/PowerDistributionSimGui.cpp index a3d4c2b3f72..6b0d8c801a4 100644 --- a/simulation/halsim_gui/src/main/native/cpp/PowerDistributionSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/PowerDistributionSimGui.cpp @@ -47,9 +47,9 @@ class PowerDistributionSimModel : public glass::PowerDistributionModel { int GetNumChannels() const override { return m_currents.size(); } - glass::DataSource* GetTemperatureData() override { return &m_temp; } - glass::DataSource* GetVoltageData() override { return &m_voltage; } - glass::DataSource* GetCurrentData(int channel) override { + glass::DoubleSource* GetTemperatureData() override { return &m_temp; } + glass::DoubleSource* GetVoltageData() override { return &m_voltage; } + glass::DoubleSource* GetCurrentData(int channel) override { return m_currents[channel].get(); } diff --git a/simulation/halsim_gui/src/main/native/cpp/RelaySimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/RelaySimGui.cpp index 1d163fbb32e..286ec29bacf 100644 --- a/simulation/halsim_gui/src/main/native/cpp/RelaySimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/RelaySimGui.cpp @@ -33,10 +33,10 @@ class RelaySimModel : public glass::RelayModel { HALSIM_GetRelayInitializedReverse(m_index); } - glass::DataSource* GetForwardData() override { + glass::BooleanSource* GetForwardData() override { return HALSIM_GetRelayInitializedForward(m_index) ? &m_forward : nullptr; } - glass::DataSource* GetReverseData() override { + glass::BooleanSource* GetReverseData() override { return HALSIM_GetRelayInitializedReverse(m_index) ? &m_reverse : nullptr; } diff --git a/simulation/halsim_gui/src/main/native/cpp/RoboRioSimGui.cpp b/simulation/halsim_gui/src/main/native/cpp/RoboRioSimGui.cpp index 29fa7b4cf24..d0689478c7d 100644 --- a/simulation/halsim_gui/src/main/native/cpp/RoboRioSimGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/RoboRioSimGui.cpp @@ -36,10 +36,10 @@ class RoboRioUser6VRailSimModel : public glass::RoboRioRailModel { public: void Update() override {} bool Exists() override { return true; } - glass::DataSource* GetVoltageData() override { return &m_voltage; } - glass::DataSource* GetCurrentData() override { return &m_current; } - glass::DataSource* GetActiveData() override { return &m_active; } - glass::DataSource* GetFaultsData() override { return &m_faults; } + glass::DoubleSource* GetVoltageData() override { return &m_voltage; } + glass::DoubleSource* GetCurrentData() override { return &m_current; } + glass::BooleanSource* GetActiveData() override { return &m_active; } + glass::IntegerSource* GetFaultsData() override { return &m_faults; } void SetVoltage(double val) override { HALSIM_SetRoboRioUserVoltage6V(val); } void SetCurrent(double val) override { HALSIM_SetRoboRioUserCurrent6V(val); } @@ -57,10 +57,10 @@ class RoboRioUser5VRailSimModel : public glass::RoboRioRailModel { public: void Update() override {} bool Exists() override { return true; } - glass::DataSource* GetVoltageData() override { return &m_voltage; } - glass::DataSource* GetCurrentData() override { return &m_current; } - glass::DataSource* GetActiveData() override { return &m_active; } - glass::DataSource* GetFaultsData() override { return &m_faults; } + glass::DoubleSource* GetVoltageData() override { return &m_voltage; } + glass::DoubleSource* GetCurrentData() override { return &m_current; } + glass::BooleanSource* GetActiveData() override { return &m_active; } + glass::IntegerSource* GetFaultsData() override { return &m_faults; } void SetVoltage(double val) override { HALSIM_SetRoboRioUserVoltage5V(val); } void SetCurrent(double val) override { HALSIM_SetRoboRioUserCurrent5V(val); } @@ -78,10 +78,10 @@ class RoboRioUser3V3RailSimModel : public glass::RoboRioRailModel { public: void Update() override {} bool Exists() override { return true; } - glass::DataSource* GetVoltageData() override { return &m_voltage; } - glass::DataSource* GetCurrentData() override { return &m_current; } - glass::DataSource* GetActiveData() override { return &m_active; } - glass::DataSource* GetFaultsData() override { return &m_faults; } + glass::DoubleSource* GetVoltageData() override { return &m_voltage; } + glass::DoubleSource* GetCurrentData() override { return &m_current; } + glass::BooleanSource* GetActiveData() override { return &m_active; } + glass::IntegerSource* GetFaultsData() override { return &m_faults; } void SetVoltage(double val) override { HALSIM_SetRoboRioUserVoltage3V3(val); } void SetCurrent(double val) override { HALSIM_SetRoboRioUserCurrent3V3(val); } @@ -105,10 +105,10 @@ class RoboRioSimModel : public glass::RoboRioModel { glass::RoboRioRailModel* GetUser5VRail() override { return &m_user5VRail; } glass::RoboRioRailModel* GetUser3V3Rail() override { return &m_user3V3Rail; } - glass::DataSource* GetUserButton() override { return &m_userButton; } - glass::DataSource* GetVInVoltageData() override { return &m_vInVoltage; } - glass::DataSource* GetVInCurrentData() override { return &m_vInCurrent; } - glass::DataSource* GetBrownoutVoltage() override { + glass::BooleanSource* GetUserButton() override { return &m_userButton; } + glass::DoubleSource* GetVInVoltageData() override { return &m_vInVoltage; } + glass::DoubleSource* GetVInCurrentData() override { return &m_vInCurrent; } + glass::DoubleSource* GetBrownoutVoltage() override { return &m_brownoutVoltage; } diff --git a/simulation/halsim_gui/src/main/native/cpp/SimDeviceGui.cpp b/simulation/halsim_gui/src/main/native/cpp/SimDeviceGui.cpp index aee5130e440..5f66a6e7046 100644 --- a/simulation/halsim_gui/src/main/native/cpp/SimDeviceGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/SimDeviceGui.cpp @@ -22,14 +22,43 @@ using namespace halsimgui; namespace { -class SimValueSource : public glass::DataSource { +#define DEFINE_SIMVALUESOURCE(Type, TYPE, v_type) \ + class Sim##Type##ValueSource : public glass::Type##Source { \ + public: \ + explicit Sim##Type##ValueSource(HAL_SimValueHandle handle, \ + const char* device, const char* name) \ + : Type##Source(fmt::format("{}-{}", device, name)), \ + m_callback{HALSIM_RegisterSimValueChangedCallback( \ + handle, this, CallbackFunc, true)} {} \ + ~Sim##Type##ValueSource() override { \ + if (m_callback != 0) { \ + HALSIM_CancelSimValueChangedCallback(m_callback); \ + } \ + } \ + \ + private: \ + static void CallbackFunc(const char*, void* param, HAL_SimValueHandle, \ + int32_t, const HAL_Value* value) { \ + auto source = static_cast(param); \ + if (value->type == HAL_##TYPE) { \ + source->SetValue(value->data.v_##v_type); \ + } \ + } \ + \ + int32_t m_callback; \ + }; + +DEFINE_SIMVALUESOURCE(Boolean, BOOLEAN, boolean) +DEFINE_SIMVALUESOURCE(Double, DOUBLE, double) + +class SimIntegerValueSource : public glass::IntegerSource { public: - explicit SimValueSource(HAL_SimValueHandle handle, const char* device, - const char* name) - : DataSource(fmt::format("{}-{}", device, name)), + explicit SimIntegerValueSource(HAL_SimValueHandle handle, const char* device, + const char* name) + : IntegerSource(fmt::format("{}-{}", device, name)), m_callback{HALSIM_RegisterSimValueChangedCallback( handle, this, CallbackFunc, true)} {} - ~SimValueSource() override { + ~SimIntegerValueSource() override { if (m_callback != 0) { HALSIM_CancelSimValueChangedCallback(m_callback); } @@ -38,13 +67,13 @@ class SimValueSource : public glass::DataSource { private: static void CallbackFunc(const char*, void* param, HAL_SimValueHandle, int32_t, const HAL_Value* value) { - auto source = static_cast(param); - if (value->type == HAL_BOOLEAN) { - source->SetValue(value->data.v_boolean); - source->SetDigital(true); - } else if (value->type == HAL_DOUBLE) { - source->SetValue(value->data.v_double); - source->SetDigital(false); + auto source = static_cast(param); + if (value->type == HAL_ENUM) { + source->SetValue(value->data.v_enum); + } else if (value->type == HAL_INT) { + source->SetValue(value->data.v_int); + } else if (value->type == HAL_LONG) { + source->SetValue(value->data.v_long); } } @@ -61,7 +90,8 @@ class SimDevicesModel : public glass::Model { } private: - wpi::DenseMap> m_sources; + wpi::DenseMap> + m_sources; }; } // namespace @@ -81,9 +111,33 @@ void SimDevicesModel::Update() { int32_t direction, const HAL_Value* value) { auto data = static_cast(dataV); auto& source = data->self->m_sources[handle]; - if (!source) { - source = std::make_unique(handle, data->device, - name); + switch (value->type) { + case HAL_BOOLEAN: + if (!source || + source->GetKind() != glass::DataSource::kBoolean) { + source = std::make_unique( + handle, data->device, name); + } + break; + case HAL_DOUBLE: + if (!source || + source->GetKind() != glass::DataSource::kDouble) { + source = std::make_unique( + handle, data->device, name); + } + break; + case HAL_ENUM: + case HAL_INT: + case HAL_LONG: + if (!source || + source->GetKind() != glass::DataSource::kInteger) { + source = std::make_unique( + handle, data->device, name); + } + break; + default: + source.reset(); + break; } }); }); diff --git a/simulation/halsim_gui/src/main/native/include/HALDataSource.h b/simulation/halsim_gui/src/main/native/include/HALDataSource.h index 295b3f8ba52..2d94a38fe0c 100644 --- a/simulation/halsim_gui/src/main/native/include/HALDataSource.h +++ b/simulation/halsim_gui/src/main/native/include/HALDataSource.h @@ -6,15 +6,13 @@ #include -#define HALSIMGUI_DATASOURCE(cbname, id, TYPE, vtype) \ - class cbname##Source : public ::glass::DataSource { \ +#define HALSIMGUI_DATASOURCE(cbname, id, TYPE, Type, vtype) \ + class cbname##Source : public ::glass::Type##Source { \ public: \ cbname##Source() \ - : DataSource(id), \ + : Type##Source{id}, \ m_callback{ \ - HALSIM_Register##cbname##Callback(CallbackFunc, this, true)} { \ - SetDigital(HAL_##TYPE == HAL_BOOLEAN); \ - } \ + HALSIM_Register##cbname##Callback(CallbackFunc, this, true)} {} \ \ ~cbname##Source() { \ if (m_callback != 0) \ @@ -32,25 +30,24 @@ } #define HALSIMGUI_DATASOURCE_BOOLEAN(cbname, id) \ - HALSIMGUI_DATASOURCE(cbname, id, BOOLEAN, boolean) + HALSIMGUI_DATASOURCE(cbname, id, BOOLEAN, Boolean, boolean) #define HALSIMGUI_DATASOURCE_DOUBLE(cbname, id) \ - HALSIMGUI_DATASOURCE(cbname, id, DOUBLE, double) + HALSIMGUI_DATASOURCE(cbname, id, DOUBLE, Double, double) #define HALSIMGUI_DATASOURCE_INT(cbname, id) \ - HALSIMGUI_DATASOURCE(cbname, id, INT, int) + HALSIMGUI_DATASOURCE(cbname, id, INT, Integer, int) -#define HALSIMGUI_DATASOURCE_INDEXED(cbname, id, TYPE, vtype) \ - class cbname##Source : public ::glass::DataSource { \ +#define HALSIMGUI_DATASOURCE_INDEXED(cbname, id, TYPE, Type, vtype) \ + class cbname##Source : public ::glass::Type##Source { \ public: \ explicit cbname##Source(int32_t index, int channel = -1) \ - : DataSource(id, channel < 0 ? index : channel), \ + : Type##Source{::glass::MakeSourceId(id, \ + channel < 0 ? index : channel)}, \ m_index{index}, \ m_channel{channel < 0 ? index : channel}, \ m_callback{HALSIM_Register##cbname##Callback(index, CallbackFunc, \ - this, true)} { \ - SetDigital(HAL_##TYPE == HAL_BOOLEAN); \ - } \ + this, true)} {} \ \ ~cbname##Source() { \ if (m_callback != 0) \ @@ -78,22 +75,20 @@ } #define HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(cbname, id) \ - HALSIMGUI_DATASOURCE_INDEXED(cbname, id, BOOLEAN, boolean) + HALSIMGUI_DATASOURCE_INDEXED(cbname, id, BOOLEAN, Boolean, boolean) #define HALSIMGUI_DATASOURCE_DOUBLE_INDEXED(cbname, id) \ - HALSIMGUI_DATASOURCE_INDEXED(cbname, id, DOUBLE, double) + HALSIMGUI_DATASOURCE_INDEXED(cbname, id, DOUBLE, Double, double) -#define HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, TYPE, vtype) \ - class cbname##Source : public ::glass::DataSource { \ +#define HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, TYPE, Type, vtype) \ + class cbname##Source : public ::glass::Type##Source { \ public: \ explicit cbname##Source(int32_t index, int32_t channel) \ - : DataSource(id, index, channel), \ + : Type##Source{::glass::MakeSourceId(id, index, channel)}, \ m_index{index}, \ m_channel{channel}, \ m_callback{HALSIM_Register##cbname##Callback( \ - index, channel, CallbackFunc, this, true)} { \ - SetDigital(HAL_##TYPE == HAL_BOOLEAN); \ - } \ + index, channel, CallbackFunc, this, true)} {} \ \ ~cbname##Source() { \ if (m_callback != 0) \ @@ -121,7 +116,7 @@ } #define HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED2(cbname, id) \ - HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, BOOLEAN, boolean) + HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, BOOLEAN, Boolean, boolean) #define HALSIMGUI_DATASOURCE_DOUBLE_INDEXED2(cbname, id) \ - HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, DOUBLE, double) + HALSIMGUI_DATASOURCE_INDEXED2(cbname, id, DOUBLE, Double, double)