mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
Use std::string_view and fmtlib across all libraries (#3402)
- Twine, StringRef, Format, and NativeFormatting have been removed - Logging now uses fmtlib style formatting - Nearly all uses of wpi::outs/errs have been replaced with fmt::print() or std::puts()/std::fputs() (for unformatted strings). - A wpi/fmt/raw_ostream.h header has been added to enable fmt::print() with wpi::raw_ostream
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <imgui_stdlib.h>
|
||||
#include <wpi/StringRef.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/timestamp.h>
|
||||
#include <wpigui.h>
|
||||
|
||||
@@ -23,64 +23,47 @@ Context* glass::gContext;
|
||||
|
||||
static bool ConvertInt(Storage::Value* value) {
|
||||
value->type = Storage::Value::kInt;
|
||||
if (value->stringVal.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
if (wpi::StringRef{value->stringVal}.getAsInteger(10, value->intVal)) {
|
||||
return false;
|
||||
}
|
||||
if (auto val = wpi::parse_integer<int>(value->stringVal, 10)) {
|
||||
value->intVal = val.value();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ConvertInt64(Storage::Value* value) {
|
||||
value->type = Storage::Value::kInt64;
|
||||
if (value->stringVal.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
if (wpi::StringRef{value->stringVal}.getAsInteger(10, value->int64Val)) {
|
||||
return false;
|
||||
}
|
||||
if (auto val = wpi::parse_integer<int64_t>(value->stringVal, 10)) {
|
||||
value->int64Val = val.value();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ConvertBool(Storage::Value* value) {
|
||||
value->type = Storage::Value::kBool;
|
||||
if (value->stringVal.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
int val;
|
||||
if (wpi::StringRef{value->stringVal}.getAsInteger(10, val)) {
|
||||
return false;
|
||||
}
|
||||
value->boolVal = (val != 0);
|
||||
if (auto val = wpi::parse_integer<int>(value->stringVal, 10)) {
|
||||
value->intVal = (val.value() != 0);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ConvertFloat(Storage::Value* value) {
|
||||
value->type = Storage::Value::kFloat;
|
||||
if (value->stringVal.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
if (std::sscanf(value->stringVal.c_str(), "%f", &value->floatVal) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (auto val = wpi::parse_float<float>(value->stringVal)) {
|
||||
value->floatVal = val.value();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ConvertDouble(Storage::Value* value) {
|
||||
value->type = Storage::Value::kDouble;
|
||||
if (value->stringVal.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
if (std::sscanf(value->stringVal.c_str(), "%lf", &value->doubleVal) != 1) {
|
||||
return false;
|
||||
}
|
||||
if (auto val = wpi::parse_float<double>(value->stringVal)) {
|
||||
value->doubleVal = val.value();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void* GlassStorageReadOpen(ImGuiContext*, ImGuiSettingsHandler* handler,
|
||||
@@ -96,7 +79,7 @@ static void* GlassStorageReadOpen(ImGuiContext*, ImGuiSettingsHandler* handler,
|
||||
static void GlassStorageReadLine(ImGuiContext*, ImGuiSettingsHandler*,
|
||||
void* entry, const char* line) {
|
||||
auto storage = static_cast<Storage*>(entry);
|
||||
auto [key, val] = wpi::StringRef{line}.split('=');
|
||||
auto [key, val] = wpi::split(line, '=');
|
||||
auto& keys = storage->GetKeys();
|
||||
auto& values = storage->GetValues();
|
||||
auto it = std::find(keys.begin(), keys.end(), key);
|
||||
@@ -144,7 +127,8 @@ static void GlassStorageWriteAll(ImGuiContext*, ImGuiSettingsHandler* handler,
|
||||
for (auto&& entryIt : sorted) {
|
||||
auto& entry = *entryIt;
|
||||
out_buf->append("[GlassStorage][");
|
||||
out_buf->append(entry.first().begin(), entry.first().end());
|
||||
out_buf->append(entry.first().data(),
|
||||
entry.first().data() + entry.first().size());
|
||||
out_buf->append("]\n");
|
||||
auto& keys = entry.second->GetKeys();
|
||||
auto& values = entry.second->GetValues();
|
||||
@@ -233,7 +217,7 @@ uint64_t glass::GetZeroTime() {
|
||||
return gContext->zeroTime;
|
||||
}
|
||||
|
||||
Storage::Value& Storage::GetValue(wpi::StringRef key) {
|
||||
Storage::Value& Storage::GetValue(std::string_view key) {
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key);
|
||||
if (it == m_keys.end()) {
|
||||
m_keys.emplace_back(key);
|
||||
@@ -244,49 +228,49 @@ Storage::Value& Storage::GetValue(wpi::StringRef key) {
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFUN(CapsName, LowerName, CType) \
|
||||
CType Storage::Get##CapsName(wpi::StringRef key, CType defaultVal) const { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) \
|
||||
return defaultVal; \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
if (value.type != Value::k##CapsName) { \
|
||||
if (!Convert##CapsName(&value)) \
|
||||
value.LowerName##Val = defaultVal; \
|
||||
} \
|
||||
return value.LowerName##Val; \
|
||||
} \
|
||||
\
|
||||
void Storage::Set##CapsName(wpi::StringRef key, CType val) { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) { \
|
||||
m_keys.emplace_back(key); \
|
||||
m_values.emplace_back(std::make_unique<Value>()); \
|
||||
m_values.back()->type = Value::k##CapsName; \
|
||||
m_values.back()->LowerName##Val = val; \
|
||||
} else { \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
value.type = Value::k##CapsName; \
|
||||
value.LowerName##Val = val; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
CType* Storage::Get##CapsName##Ref(wpi::StringRef key, CType defaultVal) { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) { \
|
||||
m_keys.emplace_back(key); \
|
||||
m_values.emplace_back(std::make_unique<Value>()); \
|
||||
m_values.back()->type = Value::k##CapsName; \
|
||||
m_values.back()->LowerName##Val = defaultVal; \
|
||||
return &m_values.back()->LowerName##Val; \
|
||||
} else { \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
if (value.type != Value::k##CapsName) { \
|
||||
if (!Convert##CapsName(&value)) \
|
||||
value.LowerName##Val = defaultVal; \
|
||||
} \
|
||||
return &value.LowerName##Val; \
|
||||
} \
|
||||
#define DEFUN(CapsName, LowerName, CType) \
|
||||
CType Storage::Get##CapsName(std::string_view key, CType defaultVal) const { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) \
|
||||
return defaultVal; \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
if (value.type != Value::k##CapsName) { \
|
||||
if (!Convert##CapsName(&value)) \
|
||||
value.LowerName##Val = defaultVal; \
|
||||
} \
|
||||
return value.LowerName##Val; \
|
||||
} \
|
||||
\
|
||||
void Storage::Set##CapsName(std::string_view key, CType val) { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) { \
|
||||
m_keys.emplace_back(key); \
|
||||
m_values.emplace_back(std::make_unique<Value>()); \
|
||||
m_values.back()->type = Value::k##CapsName; \
|
||||
m_values.back()->LowerName##Val = val; \
|
||||
} else { \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
value.type = Value::k##CapsName; \
|
||||
value.LowerName##Val = val; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
CType* Storage::Get##CapsName##Ref(std::string_view key, CType defaultVal) { \
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key); \
|
||||
if (it == m_keys.end()) { \
|
||||
m_keys.emplace_back(key); \
|
||||
m_values.emplace_back(std::make_unique<Value>()); \
|
||||
m_values.back()->type = Value::k##CapsName; \
|
||||
m_values.back()->LowerName##Val = defaultVal; \
|
||||
return &m_values.back()->LowerName##Val; \
|
||||
} else { \
|
||||
Value& value = *m_values[it - m_keys.begin()]; \
|
||||
if (value.type != Value::k##CapsName) { \
|
||||
if (!Convert##CapsName(&value)) \
|
||||
value.LowerName##Val = defaultVal; \
|
||||
} \
|
||||
return &value.LowerName##Val; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFUN(Int, int, int)
|
||||
@@ -295,18 +279,18 @@ DEFUN(Bool, bool, bool)
|
||||
DEFUN(Float, float, float)
|
||||
DEFUN(Double, double, double)
|
||||
|
||||
std::string Storage::GetString(wpi::StringRef key,
|
||||
const std::string& defaultVal) const {
|
||||
std::string Storage::GetString(std::string_view key,
|
||||
std::string_view defaultVal) const {
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key);
|
||||
if (it == m_keys.end()) {
|
||||
return defaultVal;
|
||||
return std::string{defaultVal};
|
||||
}
|
||||
Value& value = *m_values[it - m_keys.begin()];
|
||||
value.type = Value::kString;
|
||||
return value.stringVal;
|
||||
}
|
||||
|
||||
void Storage::SetString(wpi::StringRef key, const wpi::Twine& val) {
|
||||
void Storage::SetString(std::string_view key, std::string_view val) {
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key);
|
||||
if (it == m_keys.end()) {
|
||||
m_keys.emplace_back(key);
|
||||
@@ -315,12 +299,12 @@ void Storage::SetString(wpi::StringRef key, const wpi::Twine& val) {
|
||||
} else {
|
||||
Value& value = *m_values[it - m_keys.begin()];
|
||||
value.type = Value::kString;
|
||||
value.stringVal = val.str();
|
||||
value.stringVal = val;
|
||||
}
|
||||
}
|
||||
|
||||
std::string* Storage::GetStringRef(wpi::StringRef key,
|
||||
wpi::StringRef defaultVal) {
|
||||
std::string* Storage::GetStringRef(std::string_view key,
|
||||
std::string_view defaultVal) {
|
||||
auto it = std::find(m_keys.begin(), m_keys.end(), key);
|
||||
if (it == m_keys.end()) {
|
||||
m_keys.emplace_back(key);
|
||||
@@ -342,7 +326,7 @@ Storage& glass::GetStorage() {
|
||||
return *storage;
|
||||
}
|
||||
|
||||
Storage& glass::GetStorage(wpi::StringRef id) {
|
||||
Storage& glass::GetStorage(std::string_view id) {
|
||||
auto& storage = gContext->storage[id];
|
||||
if (!storage) {
|
||||
storage = std::make_unique<Storage>();
|
||||
@@ -350,10 +334,10 @@ Storage& glass::GetStorage(wpi::StringRef id) {
|
||||
return *storage;
|
||||
}
|
||||
|
||||
static void PushIDStack(wpi::StringRef label_id) {
|
||||
static void PushIDStack(std::string_view label_id) {
|
||||
gContext->idStack.emplace_back(gContext->curId.size());
|
||||
|
||||
auto [label, id] = wpi::StringRef{label_id}.split("###");
|
||||
auto [label, id] = wpi::split(label_id, "###");
|
||||
// if no ###id, use label as id
|
||||
if (id.empty()) {
|
||||
id = label;
|
||||
@@ -392,7 +376,7 @@ void glass::EndChild() {
|
||||
|
||||
bool glass::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) {
|
||||
wpi::SmallString<64> openKey;
|
||||
auto [name, id] = wpi::StringRef{label}.split("###");
|
||||
auto [name, id] = wpi::split(label, "###");
|
||||
// if no ###id, use name as id
|
||||
if (id.empty()) {
|
||||
id = name;
|
||||
@@ -400,7 +384,7 @@ bool glass::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) {
|
||||
openKey = id;
|
||||
openKey += "###open";
|
||||
|
||||
bool* open = GetStorage().GetBoolRef(openKey);
|
||||
bool* open = GetStorage().GetBoolRef(openKey.str());
|
||||
*open = ImGui::CollapsingHeader(
|
||||
label, flags | (*open ? ImGuiTreeNodeFlags_DefaultOpen : 0));
|
||||
return *open;
|
||||
@@ -428,7 +412,7 @@ void glass::PushID(const char* str_id) {
|
||||
}
|
||||
|
||||
void glass::PushID(const char* str_id_begin, const char* str_id_end) {
|
||||
PushIDStack(wpi::StringRef(str_id_begin, str_id_end - str_id_begin));
|
||||
PushIDStack(std::string_view(str_id_begin, str_id_end - str_id_begin));
|
||||
ImGui::PushID(str_id_begin, str_id_end);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
|
||||
#include "glass/DataSource.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "glass/ContextInternal.h"
|
||||
|
||||
using namespace glass;
|
||||
|
||||
wpi::sig::Signal<const char*, DataSource*> DataSource::sourceCreated;
|
||||
|
||||
DataSource::DataSource(const wpi::Twine& id) : m_id{id.str()} {
|
||||
DataSource::DataSource(std::string_view id) : m_id{id} {
|
||||
auto it = gContext->sources.try_emplace(m_id, this);
|
||||
auto& srcName = it.first->getValue();
|
||||
m_name = srcName.name.get();
|
||||
@@ -20,12 +22,11 @@ DataSource::DataSource(const wpi::Twine& id) : m_id{id.str()} {
|
||||
sourceCreated(m_id.c_str(), this);
|
||||
}
|
||||
|
||||
DataSource::DataSource(const wpi::Twine& id, int index)
|
||||
: DataSource{id + wpi::Twine('[') + wpi::Twine(index) + wpi::Twine(']')} {}
|
||||
DataSource::DataSource(std::string_view id, int index)
|
||||
: DataSource{fmt::format("{}[{}]", id, index)} {}
|
||||
|
||||
DataSource::DataSource(const wpi::Twine& id, int index, int index2)
|
||||
: DataSource{id + wpi::Twine('[') + wpi::Twine(index) + wpi::Twine(',') +
|
||||
wpi::Twine(index2) + wpi::Twine(']')} {}
|
||||
DataSource::DataSource(std::string_view id, int index, int index2)
|
||||
: DataSource{fmt::format("{}[{},{}]", id, index, index2)} {}
|
||||
|
||||
DataSource::~DataSource() {
|
||||
if (!gContext) {
|
||||
@@ -41,7 +42,7 @@ DataSource::~DataSource() {
|
||||
}
|
||||
}
|
||||
|
||||
void DataSource::SetName(const wpi::Twine& name) {
|
||||
void DataSource::SetName(std::string_view name) {
|
||||
m_name->SetName(name);
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ void DataSource::EmitDrag(ImGuiDragDropFlags flags) const {
|
||||
}
|
||||
}
|
||||
|
||||
DataSource* DataSource::Find(wpi::StringRef id) {
|
||||
DataSource* DataSource::Find(std::string_view id) {
|
||||
auto it = gContext->sources.find(id);
|
||||
if (it == gContext->sources.end()) {
|
||||
return nullptr;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "glass/Window.h"
|
||||
|
||||
#include <imgui_internal.h>
|
||||
#include <wpi/StringRef.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
|
||||
@@ -86,26 +86,21 @@ void Window::ScaleDefault(float scale) {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::IniReadLine(const char* lineStr) {
|
||||
wpi::StringRef line{lineStr};
|
||||
auto [name, value] = line.split('=');
|
||||
name = name.trim();
|
||||
value = value.trim();
|
||||
void Window::IniReadLine(const char* line) {
|
||||
auto [name, value] = wpi::split(line, '=');
|
||||
name = wpi::trim(name);
|
||||
value = wpi::trim(value);
|
||||
|
||||
if (name == "name") {
|
||||
m_name = value;
|
||||
} else if (name == "visible") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_visible = num.value();
|
||||
}
|
||||
m_visible = num;
|
||||
} else if (name == "enabled") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_enabled = num.value();
|
||||
}
|
||||
m_enabled = num;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
#include "glass/WindowManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#include <wpi/StringRef.h>
|
||||
#include <wpi/raw_ostream.h>
|
||||
#include <fmt/format.h>
|
||||
#include <wpigui.h>
|
||||
|
||||
using namespace glass;
|
||||
|
||||
WindowManager::WindowManager(const wpi::Twine& iniName)
|
||||
WindowManager::WindowManager(std::string_view iniName)
|
||||
: m_iniSaver{iniName, this} {}
|
||||
|
||||
// read/write open state to ini file
|
||||
@@ -31,42 +31,42 @@ void WindowManager::IniSaver::IniWriteAll(ImGuiTextBuffer* out_buf) {
|
||||
}
|
||||
}
|
||||
|
||||
Window* WindowManager::AddWindow(wpi::StringRef id,
|
||||
Window* WindowManager::AddWindow(std::string_view id,
|
||||
wpi::unique_function<void()> display) {
|
||||
auto win = GetOrAddWindow(id, false);
|
||||
if (!win) {
|
||||
return nullptr;
|
||||
}
|
||||
if (win->HasView()) {
|
||||
wpi::errs() << "GUI: ignoring duplicate window '" << id << "'\n";
|
||||
fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
|
||||
return nullptr;
|
||||
}
|
||||
win->SetView(MakeFunctionView(std::move(display)));
|
||||
return win;
|
||||
}
|
||||
|
||||
Window* WindowManager::AddWindow(wpi::StringRef id,
|
||||
Window* WindowManager::AddWindow(std::string_view id,
|
||||
std::unique_ptr<View> view) {
|
||||
auto win = GetOrAddWindow(id, false);
|
||||
if (!win) {
|
||||
return nullptr;
|
||||
}
|
||||
if (win->HasView()) {
|
||||
wpi::errs() << "GUI: ignoring duplicate window '" << id << "'\n";
|
||||
fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
|
||||
return nullptr;
|
||||
}
|
||||
win->SetView(std::move(view));
|
||||
return win;
|
||||
}
|
||||
|
||||
Window* WindowManager::GetOrAddWindow(wpi::StringRef id, bool duplicateOk) {
|
||||
Window* WindowManager::GetOrAddWindow(std::string_view id, bool duplicateOk) {
|
||||
// binary search
|
||||
auto it = std::lower_bound(
|
||||
m_windows.begin(), m_windows.end(), id,
|
||||
[](const auto& elem, wpi::StringRef s) { return elem->GetId() < s; });
|
||||
[](const auto& elem, std::string_view s) { return elem->GetId() < s; });
|
||||
if (it != m_windows.end() && (*it)->GetId() == id) {
|
||||
if (!duplicateOk) {
|
||||
wpi::errs() << "GUI: ignoring duplicate window '" << id << "'\n";
|
||||
fmt::print(stderr, "GUI: ignoring duplicate window '{}'\n", id);
|
||||
return nullptr;
|
||||
}
|
||||
return it->get();
|
||||
@@ -75,11 +75,11 @@ Window* WindowManager::GetOrAddWindow(wpi::StringRef id, bool duplicateOk) {
|
||||
return m_windows.emplace(it, std::make_unique<Window>(id))->get();
|
||||
}
|
||||
|
||||
Window* WindowManager::GetWindow(wpi::StringRef id) {
|
||||
Window* WindowManager::GetWindow(std::string_view id) {
|
||||
// binary search
|
||||
auto it = std::lower_bound(
|
||||
m_windows.begin(), m_windows.end(), id,
|
||||
[](const auto& elem, wpi::StringRef s) { return elem->GetId() < s; });
|
||||
[](const auto& elem, std::string_view s) { return elem->GetId() < s; });
|
||||
if (it == m_windows.end() || (*it)->GetId() != id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ void glass::DisplayAnalogInput(AnalogInputModel* model, int index) {
|
||||
}
|
||||
|
||||
void glass::DisplayAnalogInputs(AnalogInputsModel* model,
|
||||
wpi::StringRef noneMsg) {
|
||||
std::string_view noneMsg) {
|
||||
ImGui::Text("(Use Ctrl+Click to edit value)");
|
||||
bool hasAny = false;
|
||||
bool first = true;
|
||||
@@ -65,6 +65,6 @@ void glass::DisplayAnalogInputs(AnalogInputsModel* model,
|
||||
hasAny = true;
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ void glass::DisplayDIO(DIOModel* model, int index, bool outputsEnabled) {
|
||||
}
|
||||
|
||||
void glass::DisplayDIOs(DIOsModel* model, bool outputsEnabled,
|
||||
wpi::StringRef noneMsg) {
|
||||
std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
|
||||
@@ -116,6 +116,6 @@ void glass::DisplayDIOs(DIOsModel* model, bool outputsEnabled,
|
||||
});
|
||||
ImGui::PopItemWidth();
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "glass/hardware/Encoder.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
@@ -11,8 +12,8 @@
|
||||
|
||||
using namespace glass;
|
||||
|
||||
void EncoderModel::SetName(const wpi::Twine& name) {
|
||||
if (name.str().empty()) {
|
||||
void EncoderModel::SetName(std::string_view name) {
|
||||
if (name.empty()) {
|
||||
if (auto distancePerPulse = GetDistancePerPulseData()) {
|
||||
distancePerPulse->SetName("");
|
||||
}
|
||||
@@ -33,22 +34,22 @@ void EncoderModel::SetName(const wpi::Twine& name) {
|
||||
}
|
||||
} else {
|
||||
if (auto distancePerPulse = GetDistancePerPulseData()) {
|
||||
distancePerPulse->SetName(name + " Distance/Count");
|
||||
distancePerPulse->SetName(fmt::format("{} Distance/Count", name));
|
||||
}
|
||||
if (auto count = GetCountData()) {
|
||||
count->SetName(name + " Count");
|
||||
count->SetName(fmt::format("{} Count", name));
|
||||
}
|
||||
if (auto period = GetPeriodData()) {
|
||||
period->SetName(name + " Period");
|
||||
period->SetName(fmt::format("{} Period", name));
|
||||
}
|
||||
if (auto direction = GetDirectionData()) {
|
||||
direction->SetName(name + " Direction");
|
||||
direction->SetName(fmt::format("{} Direction", name));
|
||||
}
|
||||
if (auto distance = GetDistanceData()) {
|
||||
distance->SetName(name + " Distance");
|
||||
distance->SetName(fmt::format("{} Distance", name));
|
||||
}
|
||||
if (auto rate = GetRateData()) {
|
||||
rate->SetName(name + " Rate");
|
||||
rate->SetName(fmt::format("{} Rate", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +154,7 @@ void glass::DisplayEncoder(EncoderModel* model) {
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
void glass::DisplayEncoders(EncodersModel* model, wpi::StringRef noneMsg) {
|
||||
void glass::DisplayEncoders(EncodersModel* model, std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
model->ForEachEncoder([&](EncoderModel& encoder, int i) {
|
||||
hasAny = true;
|
||||
@@ -162,6 +163,6 @@ void glass::DisplayEncoders(EncodersModel* model, wpi::StringRef noneMsg) {
|
||||
PopID();
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ bool glass::DisplayPCMSolenoids(PCMModel* model, int index,
|
||||
}
|
||||
|
||||
void glass::DisplayPCMsSolenoids(PCMsModel* model, bool outputsEnabled,
|
||||
wpi::StringRef noneMsg) {
|
||||
std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
model->ForEachPCM([&](PCMModel& pcm, int i) {
|
||||
PushID(i);
|
||||
@@ -93,7 +93,7 @@ void glass::DisplayPCMsSolenoids(PCMsModel* model, bool outputsEnabled,
|
||||
PopID();
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ void glass::DisplayPDP(PDPModel* model, int index) {
|
||||
}
|
||||
}
|
||||
|
||||
void glass::DisplayPDPs(PDPsModel* model, wpi::StringRef noneMsg) {
|
||||
void glass::DisplayPDPs(PDPsModel* model, std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
model->ForEachPDP([&](PDPModel& pdp, int i) {
|
||||
hasAny = true;
|
||||
@@ -88,6 +88,6 @@ void glass::DisplayPDPs(PDPsModel* model, wpi::StringRef noneMsg) {
|
||||
PopID();
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ void glass::DisplayPWM(PWMModel* model, int index, bool outputsEnabled) {
|
||||
}
|
||||
|
||||
void glass::DisplayPWMs(PWMsModel* model, bool outputsEnabled,
|
||||
wpi::StringRef noneMsg) {
|
||||
std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
bool first = true;
|
||||
model->ForEachPWM([&](PWMModel& pwm, int i) {
|
||||
@@ -58,6 +58,6 @@ void glass::DisplayPWMs(PWMsModel* model, bool outputsEnabled,
|
||||
PopID();
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ void glass::DisplayRelay(RelayModel* model, int index, bool outputsEnabled) {
|
||||
}
|
||||
|
||||
void glass::DisplayRelays(RelaysModel* model, bool outputsEnabled,
|
||||
wpi::StringRef noneMsg) {
|
||||
std::string_view noneMsg) {
|
||||
bool hasAny = false;
|
||||
bool first = true;
|
||||
model->ForEachRelay([&](RelayModel& relay, int i) {
|
||||
@@ -77,6 +77,6 @@ void glass::DisplayRelays(RelaysModel* model, bool outputsEnabled,
|
||||
PopID();
|
||||
});
|
||||
if (!hasAny && !noneMsg.empty()) {
|
||||
ImGui::TextUnformatted(noneMsg.begin(), noneMsg.end());
|
||||
ImGui::TextUnformatted(noneMsg.data(), noneMsg.data() + noneMsg.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <frc/geometry/Pose2d.h>
|
||||
#include <frc/geometry/Rotation2d.h>
|
||||
#include <frc/geometry/Translation2d.h>
|
||||
@@ -21,11 +24,11 @@
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/fs.h>
|
||||
#include <wpi/json.h>
|
||||
#include <wpi/raw_istream.h>
|
||||
#include <wpi/raw_ostream.h>
|
||||
#include <wpigui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
@@ -229,7 +232,7 @@ class FieldInfo {
|
||||
private:
|
||||
void Reset();
|
||||
bool LoadImageImpl(const char* fn);
|
||||
void LoadJson(const wpi::Twine& jsonfile);
|
||||
void LoadJson(std::string_view jsonfile);
|
||||
|
||||
std::unique_ptr<pfd::open_file> m_fileOpener;
|
||||
|
||||
@@ -377,7 +380,7 @@ void FieldInfo::LoadImage() {
|
||||
if (m_fileOpener && m_fileOpener->ready(0)) {
|
||||
auto result = m_fileOpener->result();
|
||||
if (!result.empty()) {
|
||||
if (wpi::StringRef(result[0]).endswith(".json")) {
|
||||
if (wpi::ends_with(result[0], ".json")) {
|
||||
LoadJson(result[0]);
|
||||
} else {
|
||||
LoadImageImpl(result[0].c_str());
|
||||
@@ -396,11 +399,11 @@ void FieldInfo::LoadImage() {
|
||||
}
|
||||
}
|
||||
|
||||
void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
void FieldInfo::LoadJson(std::string_view jsonfile) {
|
||||
std::error_code ec;
|
||||
wpi::raw_fd_istream f(jsonfile, ec);
|
||||
if (ec) {
|
||||
wpi::errs() << "GUI: could not open field JSON file\n";
|
||||
std::fputs("GUI: could not open field JSON file\n", stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -409,12 +412,12 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
try {
|
||||
j = wpi::json::parse(f);
|
||||
} catch (const wpi::json::parse_error& e) {
|
||||
wpi::errs() << "GUI: JSON: could not parse: " << e.what() << '\n';
|
||||
fmt::print(stderr, "GUI: JSON: could not parse: {}\n", e.what());
|
||||
}
|
||||
|
||||
// top level must be an object
|
||||
if (!j.is_object()) {
|
||||
wpi::errs() << "GUI: JSON: does not contain a top object\n";
|
||||
std::fputs("GUI: JSON: does not contain a top object\n", stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -423,8 +426,7 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
try {
|
||||
image = j.at("field-image").get<std::string>();
|
||||
} catch (const wpi::json::exception& e) {
|
||||
wpi::errs() << "GUI: JSON: could not read field-image: " << e.what()
|
||||
<< '\n';
|
||||
fmt::print(stderr, "GUI: JSON: could not read field-image: {}\n", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -436,8 +438,8 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
bottom = j.at("field-corners").at("bottom-right").at(1).get<int>();
|
||||
right = j.at("field-corners").at("bottom-right").at(0).get<int>();
|
||||
} catch (const wpi::json::exception& e) {
|
||||
wpi::errs() << "GUI: JSON: could not read field-corners: " << e.what()
|
||||
<< '\n';
|
||||
fmt::print(stderr, "GUI: JSON: could not read field-corners: {}\n",
|
||||
e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -448,7 +450,7 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
width = j.at("field-size").at(0).get<float>();
|
||||
height = j.at("field-size").at(1).get<float>();
|
||||
} catch (const wpi::json::exception& e) {
|
||||
wpi::errs() << "GUI: JSON: could not read field-size: " << e.what() << '\n';
|
||||
fmt::print(stderr, "GUI: JSON: could not read field-size: {}\n", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -457,7 +459,7 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
try {
|
||||
unit = j.at("field-unit").get<std::string>();
|
||||
} catch (const wpi::json::exception& e) {
|
||||
wpi::errs() << "GUI: JSON: could not read field-unit: " << e.what() << '\n';
|
||||
fmt::print(stderr, "GUI: JSON: could not read field-unit: {}\n", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -468,7 +470,7 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
}
|
||||
|
||||
// the image filename is relative to the json file
|
||||
auto pathname = fs::path{jsonfile.str()}.replace_filename(image).string();
|
||||
auto pathname = fs::path{jsonfile}.replace_filename(image).string();
|
||||
|
||||
// load field image
|
||||
if (!LoadImageImpl(pathname.c_str())) {
|
||||
@@ -486,10 +488,10 @@ void FieldInfo::LoadJson(const wpi::Twine& jsonfile) {
|
||||
}
|
||||
|
||||
bool FieldInfo::LoadImageImpl(const char* fn) {
|
||||
wpi::outs() << "GUI: loading field image '" << fn << "'\n";
|
||||
fmt::print("GUI: loading field image '{}'\n", fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn);
|
||||
if (!texture) {
|
||||
wpi::errs() << "GUI: could not read field image\n";
|
||||
std::puts("GUI: could not read field image");
|
||||
return false;
|
||||
}
|
||||
m_texture = std::move(texture);
|
||||
@@ -679,10 +681,10 @@ void ObjectInfo::LoadImage() {
|
||||
}
|
||||
|
||||
bool ObjectInfo::LoadImageImpl(const char* fn) {
|
||||
wpi::outs() << "GUI: loading object image '" << fn << "'\n";
|
||||
fmt::print("GUI: loading object image '{}'\n", fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn);
|
||||
if (!texture) {
|
||||
wpi::errs() << "GUI: could not read object image\n";
|
||||
std::fputs("GUI: could not read object image\n", stderr);
|
||||
return false;
|
||||
}
|
||||
m_texture = std::move(texture);
|
||||
@@ -883,7 +885,7 @@ void glass::DisplayField2DSettings(Field2DModel* model) {
|
||||
}
|
||||
auto obj = objRef.get();
|
||||
|
||||
wpi::SmallString<64> nameBuf = name;
|
||||
wpi::SmallString<64> nameBuf{name};
|
||||
if (ImGui::CollapsingHeader(nameBuf.c_str())) {
|
||||
obj->DisplaySettings();
|
||||
}
|
||||
@@ -899,7 +901,7 @@ class FieldDisplay {
|
||||
const ImVec2& contentSize);
|
||||
|
||||
private:
|
||||
void DisplayObject(FieldObjectModel& model, wpi::StringRef name);
|
||||
void DisplayObject(FieldObjectModel& model, std::string_view name);
|
||||
|
||||
FieldInfo* m_field;
|
||||
ImVec2 m_mousePos;
|
||||
@@ -1018,7 +1020,8 @@ void FieldDisplay::Display(FieldInfo* field, Field2DModel* model,
|
||||
}
|
||||
}
|
||||
|
||||
void FieldDisplay::DisplayObject(FieldObjectModel& model, wpi::StringRef name) {
|
||||
void FieldDisplay::DisplayObject(FieldObjectModel& model,
|
||||
std::string_view name) {
|
||||
PushID(name);
|
||||
auto& objRef = m_field->m_objects[name];
|
||||
if (!objRef) {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "glass/other/Log.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <wpi/raw_ostream.h>
|
||||
|
||||
using namespace glass;
|
||||
|
||||
@@ -17,14 +16,13 @@ void LogData::Clear() {
|
||||
m_lineOffsets.push_back(0);
|
||||
}
|
||||
|
||||
void LogData::Append(const wpi::Twine& msg) {
|
||||
void LogData::Append(std::string_view msg) {
|
||||
if (m_lineOffsets.size() >= m_maxLines) {
|
||||
Clear();
|
||||
}
|
||||
|
||||
size_t oldSize = m_buf.size();
|
||||
wpi::raw_string_ostream os{m_buf};
|
||||
msg.print(os);
|
||||
m_buf.append(msg);
|
||||
for (size_t newSize = m_buf.size(); oldSize < newSize; ++oldSize) {
|
||||
if (m_buf[oldSize] == '\n') {
|
||||
m_lineOffsets.push_back(oldSize + 1);
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <frc/geometry/Pose2d.h>
|
||||
#include <frc/geometry/Rotation2d.h>
|
||||
#include <frc/geometry/Transform2d.h>
|
||||
@@ -21,7 +24,6 @@
|
||||
#include <portable-file-dialogs.h>
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
#include <wpi/raw_ostream.h>
|
||||
#include <wpigui.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
@@ -125,10 +127,10 @@ void BackgroundInfo::LoadImage() {
|
||||
}
|
||||
|
||||
bool BackgroundInfo::LoadImageImpl(const char* fn) {
|
||||
wpi::outs() << "GUI: loading background image '" << fn << "'\n";
|
||||
fmt::print("GUI: loading background image '{}'\n", fn);
|
||||
auto texture = gui::Texture::CreateFromFile(fn);
|
||||
if (!texture) {
|
||||
wpi::errs() << "GUI: could not read background image\n";
|
||||
std::puts("GUI: could not read background image");
|
||||
return false;
|
||||
}
|
||||
m_texture = std::move(texture);
|
||||
@@ -182,7 +184,7 @@ void glass::DisplayMechanism2DSettings(Mechanism2DModel* model) {
|
||||
void FrameData::DrawObject(ImDrawList* drawList, MechanismObjectModel& objModel,
|
||||
const frc::Pose2d& pose) const {
|
||||
const char* type = objModel.GetType();
|
||||
if (wpi::StringRef{type} == "line") {
|
||||
if (std::string_view{type} == "line") {
|
||||
auto startPose =
|
||||
pose + frc::Transform2d{frc::Translation2d{}, objModel.GetAngle()};
|
||||
auto endPose =
|
||||
|
||||
@@ -12,8 +12,11 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
@@ -23,6 +26,7 @@
|
||||
#include <wpi/Signal.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/timestamp.h>
|
||||
|
||||
#include "glass/Context.h"
|
||||
@@ -42,7 +46,7 @@ struct PlotSeriesRef {
|
||||
|
||||
class PlotSeries {
|
||||
public:
|
||||
explicit PlotSeries(wpi::StringRef id);
|
||||
explicit PlotSeries(std::string_view id);
|
||||
explicit PlotSeries(DataSource* source, int yAxis = 0);
|
||||
|
||||
const std::string& GetId() const { return m_id; }
|
||||
@@ -52,7 +56,7 @@ class PlotSeries {
|
||||
void SetSource(DataSource* source);
|
||||
DataSource* GetSource() const { return m_source; }
|
||||
|
||||
bool ReadIni(wpi::StringRef name, wpi::StringRef value);
|
||||
bool ReadIni(std::string_view name, std::string_view value);
|
||||
void WriteIni(ImGuiTextBuffer* out);
|
||||
|
||||
enum Action { kNone, kMoveUp, kMoveDown, kDelete };
|
||||
@@ -102,7 +106,7 @@ class Plot {
|
||||
public:
|
||||
Plot();
|
||||
|
||||
bool ReadIni(wpi::StringRef name, wpi::StringRef value);
|
||||
bool ReadIni(std::string_view name, std::string_view value);
|
||||
void WriteIni(ImGuiTextBuffer* out);
|
||||
|
||||
void DragDropTarget(PlotView& view, size_t i, bool inPlot);
|
||||
@@ -164,7 +168,7 @@ class PlotView : public View {
|
||||
|
||||
} // namespace
|
||||
|
||||
PlotSeries::PlotSeries(wpi::StringRef id) : m_id(id) {
|
||||
PlotSeries::PlotSeries(std::string_view id) : m_id(id) {
|
||||
if (DataSource* source = DataSource::Find(id)) {
|
||||
SetSource(source);
|
||||
return;
|
||||
@@ -241,55 +245,45 @@ void PlotSeries::AppendValue(double value, uint64_t timeUs) {
|
||||
}
|
||||
}
|
||||
|
||||
bool PlotSeries::ReadIni(wpi::StringRef name, wpi::StringRef value) {
|
||||
bool PlotSeries::ReadIni(std::string_view name, std::string_view value) {
|
||||
if (name == "name") {
|
||||
m_name = value;
|
||||
return true;
|
||||
}
|
||||
if (name == "yAxis") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_yAxis = num.value();
|
||||
}
|
||||
m_yAxis = num;
|
||||
return true;
|
||||
} else if (name == "color") {
|
||||
unsigned int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<unsigned int>(value, 10)) {
|
||||
m_color = ImColor(num.value());
|
||||
}
|
||||
m_color = ImColor(num);
|
||||
return true;
|
||||
} else if (name == "marker") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_marker = num.value();
|
||||
}
|
||||
m_marker = num;
|
||||
return true;
|
||||
} else if (name == "weight") {
|
||||
std::sscanf(value.data(), "%f", &m_weight);
|
||||
if (auto num = wpi::parse_float<float>(value)) {
|
||||
m_weight = num.value();
|
||||
}
|
||||
return true;
|
||||
} else if (name == "digital") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_digital = num.value();
|
||||
}
|
||||
m_digital = num;
|
||||
return true;
|
||||
} else if (name == "digitalBitHeight") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_digitalBitHeight = num.value();
|
||||
}
|
||||
m_digitalBitHeight = num;
|
||||
return true;
|
||||
} else if (name == "digitalBitGap") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_digitalBitGap = num.value();
|
||||
}
|
||||
m_digitalBitGap = num;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -478,121 +472,93 @@ Plot::Plot() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Plot::ReadIni(wpi::StringRef name, wpi::StringRef value) {
|
||||
bool Plot::ReadIni(std::string_view name, std::string_view value) {
|
||||
if (name == "name") {
|
||||
m_name = value;
|
||||
return true;
|
||||
} else if (name == "visible") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_visible = num.value() != 0;
|
||||
}
|
||||
m_visible = num != 0;
|
||||
return true;
|
||||
} else if (name == "showPause") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_showPause = num.value() != 0;
|
||||
}
|
||||
m_showPause = num != 0;
|
||||
return true;
|
||||
} else if (name == "lockPrevX") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_lockPrevX = num.value() != 0;
|
||||
}
|
||||
m_lockPrevX = num != 0;
|
||||
return true;
|
||||
} else if (name == "legend") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
}
|
||||
if (num == 0) {
|
||||
m_plotFlags |= ImPlotFlags_NoLegend;
|
||||
} else {
|
||||
m_plotFlags &= ~ImPlotFlags_NoLegend;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
if (num.value() == 0) {
|
||||
m_plotFlags |= ImPlotFlags_NoLegend;
|
||||
} else {
|
||||
m_plotFlags &= ~ImPlotFlags_NoLegend;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (name == "yaxis2") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
}
|
||||
if (num == 0) {
|
||||
m_plotFlags &= ~ImPlotFlags_YAxis2;
|
||||
} else {
|
||||
m_plotFlags |= ImPlotFlags_YAxis2;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
if (num.value() == 0) {
|
||||
m_plotFlags &= ~ImPlotFlags_YAxis2;
|
||||
} else {
|
||||
m_plotFlags |= ImPlotFlags_YAxis2;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (name == "yaxis3") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
}
|
||||
if (num == 0) {
|
||||
m_plotFlags &= ~ImPlotFlags_YAxis3;
|
||||
} else {
|
||||
m_plotFlags |= ImPlotFlags_YAxis3;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
if (num.value() == 0) {
|
||||
m_plotFlags &= ~ImPlotFlags_YAxis3;
|
||||
} else {
|
||||
m_plotFlags |= ImPlotFlags_YAxis3;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (name == "viewTime") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_viewTime = num.value() / 1000.0;
|
||||
}
|
||||
m_viewTime = num / 1000.0;
|
||||
return true;
|
||||
} else if (name == "autoHeight") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_autoHeight = num.value() != 0;
|
||||
}
|
||||
m_autoHeight = num != 0;
|
||||
return true;
|
||||
} else if (name == "height") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_height = num.value();
|
||||
}
|
||||
m_height = num;
|
||||
return true;
|
||||
} else if (name.startswith("y")) {
|
||||
auto [yAxisStr, yName] = name.split('_');
|
||||
int yAxis;
|
||||
if (yAxisStr.substr(1).getAsInteger(10, yAxis)) {
|
||||
return false;
|
||||
}
|
||||
} else if (wpi::starts_with(name, 'y')) {
|
||||
auto [yAxisStr, yName] = wpi::split(name, '_');
|
||||
int yAxis =
|
||||
wpi::parse_integer<int>(wpi::drop_front(yAxisStr), 10).value_or(-1);
|
||||
if (yAxis < 0 || yAxis > 3) {
|
||||
return false;
|
||||
}
|
||||
if (yName == "min") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_axisRange[yAxis].min = num.value() / 1000.0;
|
||||
}
|
||||
m_axisRange[yAxis].min = num / 1000.0;
|
||||
return true;
|
||||
} else if (yName == "max") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_axisRange[yAxis].max = num.value() / 1000.0;
|
||||
}
|
||||
m_axisRange[yAxis].max = num / 1000.0;
|
||||
return true;
|
||||
} else if (yName == "lockMin") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_axisRange[yAxis].lockMin = num.value() != 0;
|
||||
}
|
||||
m_axisRange[yAxis].lockMin = num != 0;
|
||||
return true;
|
||||
} else if (yName == "lockMax") {
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_axisRange[yAxis].lockMax = num.value() != 0;
|
||||
}
|
||||
m_axisRange[yAxis].lockMax = num != 0;
|
||||
return true;
|
||||
} else if (yName == "label") {
|
||||
m_axisLabel[yAxis] = value;
|
||||
@@ -960,10 +926,10 @@ void PlotView::MovePlotSeries(PlotView* fromView, size_t fromPlotIndex,
|
||||
}
|
||||
}
|
||||
|
||||
PlotProvider::PlotProvider(const wpi::Twine& iniName)
|
||||
: WindowManager{iniName + "Window"},
|
||||
PlotProvider::PlotProvider(std::string_view iniName)
|
||||
: WindowManager{fmt::format("{}Window", iniName)},
|
||||
m_plotSaver{iniName, this, false},
|
||||
m_seriesSaver{iniName + "Series", this, true} {}
|
||||
m_seriesSaver{fmt::format("{}Series", iniName), this, true} {}
|
||||
|
||||
PlotProvider::~PlotProvider() = default;
|
||||
|
||||
@@ -1021,21 +987,23 @@ void PlotProvider::DisplayWindows() {
|
||||
WindowManager::DisplayWindows();
|
||||
}
|
||||
|
||||
PlotProvider::IniSaver::IniSaver(const wpi::Twine& typeName,
|
||||
PlotProvider::IniSaver::IniSaver(std::string_view typeName,
|
||||
PlotProvider* provider, bool forSeries)
|
||||
: IniSaverBase{typeName}, m_provider{provider}, m_forSeries{forSeries} {}
|
||||
|
||||
void* PlotProvider::IniSaver::IniReadOpen(const char* name) {
|
||||
auto [viewId, plotNumStr] = wpi::StringRef{name}.split('#');
|
||||
wpi::StringRef seriesId;
|
||||
auto [viewId, plotNumStr] = wpi::split(name, '#');
|
||||
std::string_view seriesId;
|
||||
if (m_forSeries) {
|
||||
std::tie(plotNumStr, seriesId) = plotNumStr.split('#');
|
||||
std::tie(plotNumStr, seriesId) = wpi::split(plotNumStr, '#');
|
||||
if (seriesId.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
unsigned int plotNum;
|
||||
if (plotNumStr.getAsInteger(10, plotNum)) {
|
||||
if (auto plotNumOpt = wpi::parse_integer<unsigned int>(plotNumStr, 10)) {
|
||||
plotNum = plotNumOpt.value();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1071,10 +1039,10 @@ void* PlotProvider::IniSaver::IniReadOpen(const char* name) {
|
||||
.get();
|
||||
}
|
||||
|
||||
void PlotProvider::IniSaver::IniReadLine(void* entry, const char* lineStr) {
|
||||
auto [name, value] = wpi::StringRef{lineStr}.split('=');
|
||||
name = name.trim();
|
||||
value = value.trim();
|
||||
void PlotProvider::IniSaver::IniReadLine(void* entry, const char* line) {
|
||||
auto [name, value] = wpi::split(line, '=');
|
||||
name = wpi::trim(name);
|
||||
value = wpi::trim(value);
|
||||
if (m_forSeries) {
|
||||
static_cast<PlotSeries*>(entry)->ReadIni(name, value);
|
||||
} else {
|
||||
|
||||
@@ -54,9 +54,8 @@ static ImGuiSaver* GetSaverInstance() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
IniSaverBase::IniSaverBase(const wpi::Twine& typeName, IniSaverBackend* backend)
|
||||
: m_typeName(typeName.str()),
|
||||
m_backend{backend ? backend : GetSaverInstance()} {}
|
||||
IniSaverBase::IniSaverBase(std::string_view typeName, IniSaverBackend* backend)
|
||||
: m_typeName(typeName), m_backend{backend ? backend : GetSaverInstance()} {}
|
||||
|
||||
IniSaverBase::~IniSaverBase() {
|
||||
m_backend->Unregister(this);
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
#include <cstring>
|
||||
|
||||
#include <imgui_internal.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
|
||||
using namespace glass;
|
||||
|
||||
void NameInfo::SetName(const wpi::Twine& name) {
|
||||
wpi::SmallString<64> nameBuf;
|
||||
auto nameStr = name.toStringRef(nameBuf);
|
||||
size_t len = (std::min)(nameStr.size(), sizeof(m_name) - 1);
|
||||
std::memcpy(m_name, nameStr.data(), len);
|
||||
void NameInfo::SetName(std::string_view name) {
|
||||
size_t len = (std::min)(name.size(), sizeof(m_name) - 1);
|
||||
std::memcpy(m_name, name.data(), len);
|
||||
m_name[len] = '\0';
|
||||
}
|
||||
|
||||
@@ -74,7 +72,7 @@ void NameInfo::GetLabel(char* buf, size_t size, const char* defaultName,
|
||||
}
|
||||
}
|
||||
|
||||
bool NameInfo::ReadIni(wpi::StringRef name, wpi::StringRef value) {
|
||||
bool NameInfo::ReadIni(std::string_view name, std::string_view value) {
|
||||
if (name != "name") {
|
||||
return false;
|
||||
}
|
||||
@@ -140,15 +138,13 @@ bool NameInfo::InputTextName(const char* label_id, ImGuiInputTextFlags flags) {
|
||||
return ImGui::InputText(label_id, m_name, sizeof(m_name), flags);
|
||||
}
|
||||
|
||||
bool OpenInfo::ReadIni(wpi::StringRef name, wpi::StringRef value) {
|
||||
bool OpenInfo::ReadIni(std::string_view name, std::string_view value) {
|
||||
if (name != "open") {
|
||||
return false;
|
||||
}
|
||||
int num;
|
||||
if (value.getAsInteger(10, num)) {
|
||||
return true;
|
||||
if (auto num = wpi::parse_integer<int>(value, 10)) {
|
||||
m_open = num.value();
|
||||
}
|
||||
m_open = num;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -156,7 +152,7 @@ void OpenInfo::WriteIni(ImGuiTextBuffer* out) {
|
||||
out->appendf("open=%d\n", m_open ? 1 : 0);
|
||||
}
|
||||
|
||||
bool NameOpenInfo::ReadIni(wpi::StringRef name, wpi::StringRef value) {
|
||||
bool NameOpenInfo::ReadIni(std::string_view name, std::string_view value) {
|
||||
if (NameInfo::ReadIni(name, value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user