mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[glass] Split DataSource into type-specific variants (#7588)
This commit is contained in:
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/ContextInternal.h"
|
||||
|
||||
@@ -12,17 +16,13 @@ using namespace glass;
|
||||
|
||||
wpi::sig::Signal<const char*, DataSource*> DataSource::sourceCreated;
|
||||
|
||||
DataSource::DataSource(std::string_view id)
|
||||
: m_id{id}, m_name{gContext->sourceNameStorage.GetString(m_id)} {
|
||||
gContext->sources.try_emplace(m_id, this);
|
||||
sourceCreated(m_id.c_str(), this);
|
||||
std::string glass::MakeSourceId(std::string_view id, int index) {
|
||||
return fmt::format("{}[{}]", id, index);
|
||||
}
|
||||
|
||||
DataSource::DataSource(std::string_view id, int index)
|
||||
: DataSource{fmt::format("{}[{}]", id, index)} {}
|
||||
|
||||
DataSource::DataSource(std::string_view id, int index, int index2)
|
||||
: DataSource{fmt::format("{}[{},{}]", id, index, index2)} {}
|
||||
std::string glass::MakeSourceId(std::string_view id, int index, int index2) {
|
||||
return fmt::format("{}[{},{}]", id, index, index2);
|
||||
}
|
||||
|
||||
DataSource::~DataSource() {
|
||||
if (!gContext) {
|
||||
@@ -99,10 +99,11 @@ bool DataSource::InputInt(const char* label, int* v, int step, int step_fast,
|
||||
|
||||
void DataSource::EmitDrag(ImGuiDragDropFlags flags) const {
|
||||
if (ImGui::BeginDragDropSource(flags)) {
|
||||
char buf[32];
|
||||
std::snprintf(buf, sizeof(buf), "DataSource:%s", GetType());
|
||||
auto self = this;
|
||||
ImGui::SetDragDropPayload("DataSource", &self, sizeof(self)); // NOLINT
|
||||
const char* name = GetName().c_str();
|
||||
ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name);
|
||||
ImGui::SetDragDropPayload(buf, &self, sizeof(self)); // NOLINT
|
||||
DragDropTooltip();
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
@@ -114,3 +115,38 @@ DataSource* DataSource::Find(std::string_view id) {
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::string& DataSource::GetNameStorage(std::string_view id) {
|
||||
return gContext->sourceNameStorage.GetString(id);
|
||||
}
|
||||
|
||||
void DataSource::Register() {
|
||||
gContext->sources.insert_or_assign(m_id, this);
|
||||
sourceCreated(m_id.c_str(), this);
|
||||
}
|
||||
|
||||
void DataSource::DragDropTooltip() const {
|
||||
const char* name = GetName().c_str();
|
||||
ImGui::TextUnformatted(name[0] == '\0' ? m_id.c_str() : name);
|
||||
ImGui::Text("(%s)", GetType());
|
||||
}
|
||||
|
||||
const char* BooleanSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* DoubleSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* FloatSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* IntegerSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
const char* StringSource::GetType() const {
|
||||
return kType;
|
||||
}
|
||||
|
||||
@@ -75,14 +75,14 @@ void DisplayDIOImpl(DIOModel* model, int index, bool outputsEnabled) {
|
||||
dioData->LabelText(label, "unknown");
|
||||
ImGui::PopStyleColor();
|
||||
} else if (model->IsReadOnly()) {
|
||||
dioData->LabelText(
|
||||
label, "%s",
|
||||
outputsEnabled ? (dioData->GetValue() != 0 ? "1 (high)" : "0 (low)")
|
||||
: "1 (disabled)");
|
||||
dioData->LabelText(label, "%s",
|
||||
outputsEnabled
|
||||
? (dioData->GetValue() ? "1 (high)" : "0 (low)")
|
||||
: "1 (disabled)");
|
||||
|
||||
} else {
|
||||
static const char* options[] = {"0 (low)", "1 (high)"};
|
||||
int val = dioData->GetValue() != 0 ? 1 : 0;
|
||||
int val = dioData->GetValue() ? 1 : 0;
|
||||
if (dioData->Combo(label, &val, options, 2)) {
|
||||
model->SetValue(val);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -58,7 +58,7 @@ void glass::DisplayRelay(RelayModel* model, int index, bool outputsEnabled) {
|
||||
IM_COL32(128, 128, 128, 255)};
|
||||
int values[2] = {reverseData ? (reverse ? 2 : -2) : -3,
|
||||
forwardData ? (forward ? 1 : -1) : -3};
|
||||
DataSource* sources[2] = {reverseData, forwardData};
|
||||
BooleanSource* sources[2] = {reverseData, forwardData};
|
||||
DrawLEDSources(values, sources, 2, 2, colors);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <imgui_internal.h>
|
||||
#include <numbers>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -80,12 +80,12 @@ void glass::DisplayFMS(FMSModel* model, bool editableDsAttached) {
|
||||
}
|
||||
|
||||
// Game Specific Message
|
||||
wpi::SmallString<64> gameSpecificMessageBuf;
|
||||
std::string gameSpecificMessage{
|
||||
model->GetGameSpecificMessage(gameSpecificMessageBuf)};
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
if (ImGui::InputText("Game Specific", &gameSpecificMessage)) {
|
||||
model->SetGameSpecificMessage(gameSpecificMessage);
|
||||
if (auto data = model->GetGameSpecificMessageData()) {
|
||||
std::string gameSpecificMessage = data->GetValue();
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
if (ImGui::InputText("Game Specific", &gameSpecificMessage)) {
|
||||
model->SetGameSpecificMessage(gameSpecificMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,11 +148,11 @@ void glass::DisplayFMSReadOnly(FMSModel* model) {
|
||||
ImGui::TextUnformatted("?");
|
||||
}
|
||||
}
|
||||
|
||||
wpi::SmallString<64> gameSpecificMessageBuf;
|
||||
std::string_view gameSpecificMessage =
|
||||
model->GetGameSpecificMessage(gameSpecificMessageBuf);
|
||||
ImGui::Text("Game Specific: %s", exists ? gameSpecificMessage.data() : "?");
|
||||
if (auto data = model->GetGameSpecificMessageData()) {
|
||||
wpi::SmallString<64> gsmBuf;
|
||||
ImGui::Text("Game Specific: %s",
|
||||
exists ? data->GetValue(gsmBuf).data() : "?");
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
|
||||
#include "glass/other/PIDController.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -82,12 +82,13 @@ class PlotSeries {
|
||||
private:
|
||||
bool IsDigital() const {
|
||||
return m_digital.GetValue() == kDigital ||
|
||||
(m_digital.GetValue() == kAuto && m_source && m_source->IsDigital());
|
||||
(m_digital.GetValue() == kAuto && m_source && m_digitalSource);
|
||||
}
|
||||
void AppendValue(double value, int64_t time);
|
||||
|
||||
// source linkage
|
||||
DataSource* m_source = nullptr;
|
||||
bool m_digitalSource = false;
|
||||
wpi::sig::ScopedConnection m_sourceCreatedConn;
|
||||
wpi::sig::ScopedConnection m_newValueConn;
|
||||
std::string& m_id;
|
||||
@@ -255,11 +256,39 @@ void PlotSeries::CheckSource() {
|
||||
void PlotSeries::SetSource(DataSource* source) {
|
||||
m_source = source;
|
||||
|
||||
// add initial value
|
||||
AppendValue(source->GetValue(), 0);
|
||||
if (auto s = dynamic_cast<BooleanSource*>(source)) {
|
||||
m_digitalSource = true;
|
||||
|
||||
m_newValueConn = source->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](bool value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<DoubleSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<FloatSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](double value, int64_t time) { AppendValue(value, time); });
|
||||
} else if (auto s = dynamic_cast<IntegerSource*>(source)) {
|
||||
m_digitalSource = false;
|
||||
|
||||
// add initial value
|
||||
AppendValue(s->GetValue(), 0);
|
||||
|
||||
m_newValueConn = s->valueChanged.connect_connection(
|
||||
[this](int64_t value, int64_t time) { AppendValue(value, time); });
|
||||
}
|
||||
}
|
||||
|
||||
void PlotSeries::AppendValue(double value, int64_t timeUs) {
|
||||
@@ -522,9 +551,18 @@ Plot::Plot(Storage& storage)
|
||||
}
|
||||
|
||||
void Plot::DragDropAccept(PlotView& view, size_t i, int yAxis) {
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload("DataSource")) {
|
||||
auto source = *static_cast<DataSource**>(payload->Data);
|
||||
// accept any of double/float/boolean/integer sources
|
||||
DataSource* source = AcceptDragDropPayload<DoubleSource>();
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<FloatSource>();
|
||||
}
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<BooleanSource>();
|
||||
}
|
||||
if (!source) {
|
||||
source = AcceptDragDropPayload<IntegerSource>();
|
||||
}
|
||||
if (source) {
|
||||
// don't add duplicates unless it's onto a different Y axis
|
||||
auto it =
|
||||
std::find_if(m_series.begin(), m_series.end(), [=](const auto& elem) {
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
|
||||
#include "glass/other/ProfiledPIDController.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace glass {
|
||||
|
||||
void DrawLEDSources(const int* values, DataSource** sources, int numValues,
|
||||
void DrawLEDSources(const int* values, BooleanSource** sources, int numValues,
|
||||
int cols, const ImU32* colors, float size, float spacing,
|
||||
const LEDConfig& config) {
|
||||
if (numValues == 0 || cols < 1) {
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <wpi/Signal.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
#include <wpi/spinlock.h>
|
||||
|
||||
namespace glass {
|
||||
@@ -20,35 +24,21 @@ 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);
|
||||
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(); }
|
||||
|
||||
virtual const char* GetType() const = 0;
|
||||
|
||||
void SetName(std::string_view name) { m_name = name; }
|
||||
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;
|
||||
}
|
||||
|
||||
int64_t GetValueTime() const {
|
||||
std::scoped_lock lock{m_valueMutex};
|
||||
return m_valueTime;
|
||||
@@ -69,8 +59,6 @@ class DataSource {
|
||||
ImGuiInputTextFlags flags = 0) const;
|
||||
void EmitDrag(ImGuiDragDropFlags flags = 0) const;
|
||||
|
||||
wpi::sig::SignalBase<wpi::spinlock, double, int64_t> valueChanged;
|
||||
|
||||
static DataSource* Find(std::string_view id);
|
||||
|
||||
static wpi::sig::Signal<const char*, DataSource*> sourceCreated;
|
||||
@@ -78,10 +66,151 @@ class DataSource {
|
||||
private:
|
||||
std::string m_id;
|
||||
std::string& m_name;
|
||||
bool m_digital = false;
|
||||
|
||||
static std::string& GetNameStorage(std::string_view id);
|
||||
|
||||
protected:
|
||||
explicit DataSource(std::string id)
|
||||
: m_id{std::move(id)}, m_name{GetNameStorage(m_id)} {}
|
||||
|
||||
void Register();
|
||||
|
||||
virtual void DragDropTooltip() const;
|
||||
|
||||
mutable wpi::spinlock m_valueMutex;
|
||||
double m_value = 0;
|
||||
int64_t m_valueTime = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
requires std::derived_from<T, DataSource> && requires {
|
||||
{ T::kType } -> std::convertible_to<const char*>;
|
||||
}
|
||||
static T* AcceptDragDropPayload(ImGuiDragDropFlags flags = 0) {
|
||||
char buf[32];
|
||||
std::snprintf(buf, sizeof(buf), "DataSource:%s", T::kType);
|
||||
if (auto payload = ImGui::AcceptDragDropPayload(buf, flags)) {
|
||||
return static_cast<T*>(*static_cast<DataSource**>(payload->Data));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string MakeSourceId(std::string_view id, int index);
|
||||
std::string MakeSourceId(std::string_view id, int index, int index2);
|
||||
|
||||
template <typename T>
|
||||
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<wpi::spinlock, T, int64_t> valueChanged;
|
||||
|
||||
private:
|
||||
T m_value = 0;
|
||||
|
||||
protected:
|
||||
explicit ValueSource(std::string id) : DataSource{std::move(id)} {}
|
||||
};
|
||||
|
||||
class BooleanSource : public ValueSource<bool> {
|
||||
public:
|
||||
static constexpr const char* kType = "boolean";
|
||||
|
||||
explicit BooleanSource(std::string id) : ValueSource{std::move(id)} {
|
||||
Register();
|
||||
}
|
||||
|
||||
const char* GetType() const override;
|
||||
};
|
||||
|
||||
class DoubleSource : public ValueSource<double> {
|
||||
public:
|
||||
static constexpr const char* kType = "boolean";
|
||||
|
||||
explicit DoubleSource(std::string id) : ValueSource{std::move(id)} {
|
||||
Register();
|
||||
}
|
||||
|
||||
const char* GetType() const override;
|
||||
};
|
||||
|
||||
class FloatSource : public ValueSource<float> {
|
||||
public:
|
||||
static constexpr const char* kType = "float";
|
||||
|
||||
explicit FloatSource(std::string id) : ValueSource{std::move(id)} {
|
||||
Register();
|
||||
}
|
||||
|
||||
const char* GetType() const override;
|
||||
};
|
||||
|
||||
class IntegerSource : public ValueSource<int64_t> {
|
||||
public:
|
||||
static constexpr const char* kType = "integer";
|
||||
|
||||
explicit IntegerSource(std::string id) : ValueSource{std::move(id)} {
|
||||
Register();
|
||||
}
|
||||
|
||||
const char* GetType() const override;
|
||||
};
|
||||
|
||||
class StringSource : public DataSource {
|
||||
public:
|
||||
static constexpr const char* kType = "string";
|
||||
|
||||
explicit StringSource(std::string id) : DataSource{std::move(id)} {
|
||||
Register();
|
||||
}
|
||||
|
||||
const char* GetType() const override;
|
||||
|
||||
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<char>& buf) const {
|
||||
std::scoped_lock lock{m_valueMutex};
|
||||
buf.assign(m_value.begin(), m_value.end());
|
||||
return {buf.begin(), buf.end()};
|
||||
}
|
||||
|
||||
wpi::sig::SignalBase<wpi::spinlock, std::string_view, int64_t> valueChanged;
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
};
|
||||
|
||||
} // namespace glass
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<void(double)> setter;
|
||||
|
||||
WheelInfo(std::string_view name, DataSource* percent,
|
||||
WheelInfo(std::string_view name, DoubleSource* percent,
|
||||
std::function<void(double)> setter)
|
||||
: name(name), percent(percent), setter(std::move(setter)) {}
|
||||
};
|
||||
|
||||
@@ -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<char>& 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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{});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
#include <wpi/timestamp.h>
|
||||
@@ -32,19 +34,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<char>& 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 +62,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() {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <concepts>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@@ -632,19 +631,53 @@ static void UpdateJsonValueSource(NetworkTablesModel& model,
|
||||
}
|
||||
|
||||
void NetworkTablesModel::ValueSource::UpdateDiscreteSource(
|
||||
std::string_view name, double value, int64_t time, bool digital) {
|
||||
std::string_view name, bool value, int64_t time) {
|
||||
valueChildren.clear();
|
||||
if (!source) {
|
||||
source = std::make_unique<DataSource>(fmt::format("NT:{}", name));
|
||||
auto s = dynamic_cast<BooleanSource*>(source.get());
|
||||
if (!s) {
|
||||
source = std::make_unique<BooleanSource>(fmt::format("NT:{}", name));
|
||||
s = static_cast<BooleanSource*>(source.get());
|
||||
}
|
||||
source->SetValue(value, time);
|
||||
source->SetDigital(digital);
|
||||
s->SetValue(value, time);
|
||||
}
|
||||
|
||||
template <typename T, typename MakeValue>
|
||||
void NetworkTablesModel::ValueSource::UpdateDiscreteSource(
|
||||
std::string_view name, float value, int64_t time) {
|
||||
valueChildren.clear();
|
||||
auto s = dynamic_cast<FloatSource*>(source.get());
|
||||
if (!s) {
|
||||
source = std::make_unique<FloatSource>(fmt::format("NT:{}", name));
|
||||
s = static_cast<FloatSource*>(source.get());
|
||||
}
|
||||
s->SetValue(value, time);
|
||||
}
|
||||
|
||||
void NetworkTablesModel::ValueSource::UpdateDiscreteSource(
|
||||
std::string_view name, double value, int64_t time) {
|
||||
valueChildren.clear();
|
||||
auto s = dynamic_cast<DoubleSource*>(source.get());
|
||||
if (!s) {
|
||||
source = std::make_unique<DoubleSource>(fmt::format("NT:{}", name));
|
||||
s = static_cast<DoubleSource*>(source.get());
|
||||
}
|
||||
s->SetValue(value, time);
|
||||
}
|
||||
|
||||
void NetworkTablesModel::ValueSource::UpdateDiscreteSource(
|
||||
std::string_view name, int64_t value, int64_t time) {
|
||||
valueChildren.clear();
|
||||
auto s = dynamic_cast<IntegerSource*>(source.get());
|
||||
if (!s) {
|
||||
source = std::make_unique<IntegerSource>(fmt::format("NT:{}", name));
|
||||
s = static_cast<IntegerSource*>(source.get());
|
||||
}
|
||||
s->SetValue(value, time);
|
||||
}
|
||||
|
||||
template <bool IsBoolean, typename T, typename MakeValue>
|
||||
void NetworkTablesModel::ValueSource::UpdateDiscreteArray(
|
||||
std::string_view name, std::span<const T> arr, int64_t time,
|
||||
MakeValue makeValue, bool digital) {
|
||||
MakeValue makeValue) {
|
||||
if (valueChildrenMap) {
|
||||
valueChildren.clear();
|
||||
valueChildrenMap = false;
|
||||
@@ -657,7 +690,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<bool>(arr[i]), time);
|
||||
} else {
|
||||
child.UpdateDiscreteSource(child.path, arr[i], time);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@@ -667,8 +704,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 +716,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<true>(name, value.GetBooleanArray(), value.time(),
|
||||
nt::Value::MakeBoolean);
|
||||
break;
|
||||
case NT_INTEGER_ARRAY:
|
||||
UpdateDiscreteArray(name, value.GetIntegerArray(), value.time(),
|
||||
nt::Value::MakeInteger);
|
||||
UpdateDiscreteArray<false>(name, value.GetIntegerArray(), value.time(),
|
||||
nt::Value::MakeInteger);
|
||||
break;
|
||||
case NT_FLOAT_ARRAY:
|
||||
UpdateDiscreteArray(name, value.GetFloatArray(), value.time(),
|
||||
nt::Value::MakeFloat);
|
||||
UpdateDiscreteArray<false>(name, value.GetFloatArray(), value.time(),
|
||||
nt::Value::MakeFloat);
|
||||
break;
|
||||
case NT_DOUBLE_ARRAY:
|
||||
UpdateDiscreteArray(name, value.GetDoubleArray(), value.time(),
|
||||
nt::Value::MakeDouble);
|
||||
UpdateDiscreteArray<false>(name, value.GetDoubleArray(), value.time(),
|
||||
nt::Value::MakeDouble);
|
||||
break;
|
||||
case NT_STRING_ARRAY: {
|
||||
auto arr = value.GetStringArray();
|
||||
@@ -729,6 +765,13 @@ void NetworkTablesModel::ValueSource::UpdateFromValue(
|
||||
os << '"';
|
||||
os.write_escaped(value.GetString());
|
||||
os << '"';
|
||||
|
||||
auto s = dynamic_cast<StringSource*>(source.get());
|
||||
if (!s) {
|
||||
source = std::make_unique<StringSource>(fmt::format("NT:{}", name));
|
||||
s = static_cast<StringSource*>(source.get());
|
||||
}
|
||||
s->SetValue(value.GetString(), value.time());
|
||||
}
|
||||
break;
|
||||
case NT_RAW:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<DriveModel::WheelInfo> m_wheels;
|
||||
ImVec2 m_speedVector;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<char>& 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<DriveModel::WheelInfo> m_wheels;
|
||||
ImVec2 m_speedVector;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -58,13 +58,16 @@ class NetworkTablesModel : public Model {
|
||||
bool valueChildrenMap = false;
|
||||
|
||||
private:
|
||||
void UpdateDiscreteSource(std::string_view name, double value, int64_t time,
|
||||
bool digital = false);
|
||||
void UpdateDiscreteSource(std::string_view name, bool value, int64_t time);
|
||||
void UpdateDiscreteSource(std::string_view name, float value, int64_t time);
|
||||
void UpdateDiscreteSource(std::string_view name, double value,
|
||||
int64_t time);
|
||||
void UpdateDiscreteSource(std::string_view name, int64_t value,
|
||||
int64_t time);
|
||||
|
||||
template <typename T, typename MakeValue>
|
||||
template <bool IsBoolean, typename T, typename MakeValue>
|
||||
void UpdateDiscreteArray(std::string_view name, std::span<const T> arr,
|
||||
int64_t time, MakeValue makeValue,
|
||||
bool digital = false);
|
||||
int64_t time, MakeValue makeValue);
|
||||
};
|
||||
|
||||
struct EntryValueTreeNode : public ValueSource {
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -197,11 +197,11 @@ class JoystickModel {
|
||||
int axisCount;
|
||||
int buttonCount;
|
||||
int povCount;
|
||||
std::unique_ptr<glass::DataSource> axes[HAL_kMaxJoystickAxes];
|
||||
std::unique_ptr<glass::DoubleSource> 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<glass::DataSource> povs[HAL_kMaxJoystickPOVs];
|
||||
glass::BooleanSource* buttons[32];
|
||||
std::unique_ptr<glass::IntegerSource> 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<char>& 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<glass::DataSource>(
|
||||
axes[i] = std::make_unique<glass::DoubleSource>(
|
||||
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<glass::DataSource>(
|
||||
povs[i] = std::make_unique<glass::IntegerSource>(
|
||||
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<const char*>(info.gameSpecificMessage),
|
||||
reinterpret_cast<const char*>(info.gameSpecificMessage) +
|
||||
info.gameSpecificMessageSize});
|
||||
}
|
||||
|
||||
bool FMSSimModel::IsReadOnly() {
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <glass/DataSource.h>
|
||||
#include <glass/hardware/Encoder.h>
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/EncoderData.h>
|
||||
#include <hal/simulation/SimDeviceData.h>
|
||||
|
||||
#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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Sim##Type##ValueSource*>(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<SimValueSource*>(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<SimIntegerValueSource*>(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<HAL_SimValueHandle, std::unique_ptr<SimValueSource>> m_sources;
|
||||
wpi::DenseMap<HAL_SimValueHandle, std::unique_ptr<glass::DataSource>>
|
||||
m_sources;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -81,9 +111,30 @@ void SimDevicesModel::Update() {
|
||||
int32_t direction, const HAL_Value* value) {
|
||||
auto data = static_cast<Data*>(dataV);
|
||||
auto& source = data->self->m_sources[handle];
|
||||
if (!source) {
|
||||
source = std::make_unique<SimValueSource>(handle, data->device,
|
||||
name);
|
||||
switch (value->type) {
|
||||
case HAL_BOOLEAN:
|
||||
if (!dynamic_cast<SimBooleanValueSource*>(source.get())) {
|
||||
source = std::make_unique<SimBooleanValueSource>(
|
||||
handle, data->device, name);
|
||||
}
|
||||
break;
|
||||
case HAL_DOUBLE:
|
||||
if (!dynamic_cast<SimDoubleValueSource*>(source.get())) {
|
||||
source = std::make_unique<SimDoubleValueSource>(
|
||||
handle, data->device, name);
|
||||
}
|
||||
break;
|
||||
case HAL_ENUM:
|
||||
case HAL_INT:
|
||||
case HAL_LONG:
|
||||
if (!dynamic_cast<SimIntegerValueSource*>(source.get())) {
|
||||
source = std::make_unique<SimIntegerValueSource>(
|
||||
handle, data->device, name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
source.reset();
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
|
||||
#include <glass/DataSource.h>
|
||||
|
||||
#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)
|
||||
|
||||
Reference in New Issue
Block a user