-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Place template implementations into cpp files (#10)
* switch over 1/3 * BASE SINGLE AXIS * Fix code style issues with clang_format --------- Co-authored-by: Lint Action <[email protected]>
- Loading branch information
1 parent
86b0b15
commit 739898a
Showing
15 changed files
with
872 additions
and
702 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#pragma once | ||
|
||
#include "subzero/autonomous/AutoFactory.h" | ||
|
||
using namespace subzero; | ||
|
||
template <typename T> | ||
bool AutoFactory<T>::AutoFileExists(const std::string fileName) { | ||
const std::string filePath = frc::filesystem::GetDeployDirectory() + | ||
"/pathplanner/autos/" + fileName + ".auto"; | ||
|
||
std::error_code error_code; | ||
std::unique_ptr<wpi::MemoryBuffer> fileBuffer = | ||
wpi::MemoryBuffer::GetFile(filePath, error_code); | ||
|
||
if (fileBuffer == nullptr || error_code) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
template <typename T> | ||
frc2::CommandPtr | ||
AutoFactory<T>::PathPlannerPathFromName(const std::string autoName) { | ||
if (!AutoFileExists(autoName)) { | ||
ConsoleWriter.logError("Auto Factory", | ||
"AUTO '%s' DOES NOT EXIST HELP US EVAN", | ||
autoName.c_str()); | ||
return EmptyCommand().ToPtr(); | ||
} | ||
return pathplanner::PathPlannerAuto(autoName).ToPtr(); | ||
} | ||
|
||
template <typename T> frc2::CommandPtr AutoFactory<T>::GetAuto(T type) { | ||
if (!m_autos.contains(type)) { | ||
ConsoleWriter.logWarning("Auto Factory", | ||
"Auto type %d does not exist, defaulting to empty " | ||
"auto", | ||
static_cast<int>(type)); | ||
return EmptyCommand().ToPtr(); | ||
} | ||
|
||
return PathPlannerPathFromName(m_autos.at(type)); | ||
} |
189 changes: 189 additions & 0 deletions
189
lib/cpp/subzero/frc/smartdashboard/ModifiableChooser.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
#pragma once | ||
|
||
#include "subzero/frc/smartdashboard/ModifiableChooser.h" | ||
|
||
using namespace subzero; | ||
|
||
template <typename T> ModifiableChooser<T>::ModifiableChooser() { | ||
m_instance = m_instances.fetch_add(1); | ||
wpi::SendableRegistry::Add(this, "SendableChangableChooser", m_instance); | ||
} | ||
|
||
template <typename T> ModifiableChooser<T>::~ModifiableChooser() { | ||
wpi::SendableRegistry::Remove(this); | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::AddOption(std::string name, T object) { | ||
m_map[name] = object; | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::RemoveOption(std::string name) { | ||
if (m_map.contains(name)) { | ||
if (m_defaultChoice == name) { | ||
m_defaultChoice = ""; | ||
} | ||
|
||
if (m_selected == name) { | ||
m_selected = m_defaultChoice; | ||
} | ||
|
||
m_map.erase(name); | ||
} | ||
} | ||
|
||
template <typename T> void ModifiableChooser<T>::ClearOptions() { | ||
m_defaultChoice = ""; | ||
m_selected = m_defaultChoice; | ||
|
||
m_map.clear(); | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::SetOptions(std::map<std::string, T> options) { | ||
ClearOptions(); | ||
|
||
m_map = options; | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::SetDefaultOption(std::string name, T object) { | ||
m_defaultChoice = name; | ||
AddOption(name, object); | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::SetOptions(std::map<std::string, T> options, | ||
std::string defaultName, | ||
T defaultObject) { | ||
SetOptions(options); | ||
SetDefaultOption(defaultName, defaultObject); | ||
if (m_selected == "") { | ||
m_selected = defaultName; | ||
} | ||
} | ||
|
||
template <typename T> T ModifiableChooser<T>::GetSelected() { | ||
std::lock_guard<std::recursive_mutex> lk(m_mutex); | ||
|
||
try { | ||
// TODO | ||
if (m_selected != "") { | ||
return m_map[m_selected]; | ||
} | ||
|
||
return m_map[m_defaultChoice]; | ||
} catch (const std::exception &ex) { | ||
std::cerr << ex.what() << '\n'; | ||
} | ||
} | ||
|
||
template <typename T> std::string ModifiableChooser<T>::GetSelectedKey() { | ||
std::lock_guard<std::recursive_mutex> lk(m_mutex); | ||
|
||
try { | ||
// TODO | ||
if (m_selected != "") { | ||
return m_selected; | ||
} | ||
|
||
return m_defaultChoice; | ||
} catch (const std::exception &ex) { | ||
std::cerr << ex.what() << '\n'; | ||
} | ||
} | ||
|
||
template <typename T> std::string ModifiableChooser<T>::GetNtSelected() { | ||
std::optional<T> choice; | ||
std::function<void(std::optional<T>)> listener; | ||
std::string setSelectedTo; | ||
|
||
std::lock_guard<std::recursive_mutex> lk(m_mutex); | ||
|
||
try { | ||
if (m_selected != "") { | ||
setSelectedTo = m_selected; | ||
} else { | ||
setSelectedTo = m_defaultChoice; | ||
} | ||
|
||
if (setSelectedTo != m_previousValue && m_listener && | ||
m_map.contains(setSelectedTo)) { | ||
choice = m_map[setSelectedTo]; | ||
listener = m_listener; | ||
} else { | ||
choice = std::nullopt; | ||
listener = nullptr; | ||
} | ||
|
||
m_previousValue = setSelectedTo; | ||
|
||
if (listener) { | ||
listener(choice); | ||
} | ||
} catch (const std::exception &ex) { | ||
std::cerr << ex.what() << '\n'; | ||
} | ||
|
||
return setSelectedTo; | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::SetNtSelected(std::string val) { | ||
std::optional<T> choice; | ||
std::function<void(std::optional<T>)> listener; | ||
|
||
std::lock_guard<std::recursive_mutex> lk(m_mutex); | ||
|
||
try { | ||
m_selected = val; | ||
|
||
if (!m_map.contains(m_selected)) { | ||
m_selected = m_defaultChoice; | ||
} | ||
|
||
if (m_selected != m_previousValue && m_listener) { | ||
choice = m_map[val]; | ||
listener = m_listener; | ||
} else { | ||
choice = std::nullopt; | ||
listener = nullptr; | ||
} | ||
|
||
m_previousValue = val; | ||
|
||
if (listener) { | ||
listener(choice); | ||
} | ||
} catch (const std::exception &ex) { | ||
std::cerr << ex.what() << '\n'; | ||
} | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::OnChange( | ||
std::function<void(std::optional<T>)> listener) { | ||
std::lock_guard<std::recursive_mutex> lk(m_mutex); | ||
m_listener = listener; | ||
} | ||
|
||
template <typename T> | ||
void ModifiableChooser<T>::InitSendable(wpi::SendableBuilder &builder) { | ||
builder.SetSmartDashboardType("String Chooser"); | ||
builder.PublishConstInteger(kInstance, m_instance); | ||
builder.AddStringProperty( | ||
kDefault, [this] { return m_defaultChoice; }, nullptr); | ||
builder.AddStringArrayProperty( | ||
kOptions, | ||
[this] { | ||
auto keys = std::views::keys(m_map); | ||
return std::vector<std::string>{keys.begin(), keys.end()}; | ||
}, | ||
nullptr); | ||
builder.AddStringProperty( | ||
kActive, std::bind(&ModifiableChooser::GetSelectedKey, this), nullptr); | ||
builder.AddStringProperty( | ||
kSelected, std::bind(&ModifiableChooser::GetNtSelected, this), | ||
[this](std::string_view val) { SetNtSelected(std::string{val}); }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#pragma once | ||
|
||
#include "subzero/frc/smartdashboard/TaggedChooser.h" | ||
|
||
using namespace subzero; | ||
|
||
template <typename T> | ||
TaggedChooser<T>::TaggedChooser( | ||
const std::vector<TaggedChooserEntry> &entries, | ||
const std::vector<TaggedChooserSelectorGroup> &groups, | ||
std::string chooserName) | ||
: m_chooserName{chooserName} { | ||
m_entries = entries; | ||
m_groups.reserve(groups.size()); | ||
|
||
for (auto &group : groups) { | ||
m_groups.push_back({ | ||
.group = group, | ||
.chooser = std::make_unique<frc::SendableChooser<std::string>>(), | ||
}); | ||
} | ||
|
||
m_chooser.OnChange([this](std::optional<T> value) { | ||
if (value && m_onChangeCb) { | ||
m_onChangeCb(value.value()); | ||
} | ||
}); | ||
|
||
frc::SmartDashboard::PutData(m_chooserName, &m_chooser); | ||
} | ||
|
||
template <typename T> | ||
void TaggedChooser<T>::SetOnChangeCallback(std::function<void(T)> cb) { | ||
m_onChangeCb = cb; | ||
} | ||
|
||
template <typename T> void TaggedChooser<T>::Initialize() { | ||
for (auto &group : m_groups) { | ||
for (auto &option : group.group.second) { | ||
group.chooser->AddOption(option, option); | ||
} | ||
|
||
group.chooser->SetDefaultOption("ANY", "ANY"); | ||
group.chooser->OnChange([this](std::string newValue) { | ||
auto availableEntries = GetAvailableEntries(); | ||
PopulateChooser(); | ||
std::vector<T> availableKeys; | ||
availableKeys.reserve(availableEntries.size()); | ||
|
||
std::transform( | ||
availableEntries.begin(), availableEntries.end(), | ||
std::back_inserter(availableKeys), | ||
[](const TaggedChooserValue &value) { return value.first; }); | ||
}); | ||
|
||
frc::SmartDashboard::PutData(group.group.first, group.chooser.get()); | ||
} | ||
|
||
PopulateChooser(); | ||
} | ||
|
||
template <typename T> | ||
std::vector<typename TaggedChooser<T>::TaggedChooserValue> | ||
TaggedChooser<T>::GetAvailableEntries() { | ||
std::vector<TaggedChooserValue> availableEntries; | ||
std::vector<std::string> selectedTags; | ||
for (auto &group : m_groups) { | ||
auto selected = group.chooser->GetSelected(); | ||
if (selected != "ANY") { | ||
selectedTags.push_back(selected); | ||
} | ||
} | ||
|
||
for (auto &entry : m_entries) { | ||
bool matches = true; | ||
for (auto &tag : selectedTags) { | ||
if (!entry.second.contains(tag)) { | ||
matches = false; | ||
break; | ||
} | ||
} | ||
|
||
if (matches) { | ||
availableEntries.push_back(entry.first); | ||
} | ||
} | ||
|
||
return availableEntries; | ||
} | ||
|
||
template <typename T> void TaggedChooser<T>::PopulateChooser() { | ||
auto entries = GetAvailableEntries(); | ||
m_chooser.ClearOptions(); | ||
|
||
for (auto it = entries.begin(); it != entries.end(); it++) { | ||
if (it == entries.begin()) { | ||
m_chooser.SetDefaultOption(it->second, it->first); | ||
continue; | ||
} | ||
|
||
m_chooser.AddOption(it->second, it->first); | ||
} | ||
} |
Oops, something went wrong.