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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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