Skip to content

Commit

Permalink
Place template implementations into cpp files (#10)
Browse files Browse the repository at this point in the history
* switch over 1/3

* BASE SINGLE AXIS

* Fix code style issues with clang_format

---------

Co-authored-by: Lint Action <[email protected]>
  • Loading branch information
having11 and lint-action authored May 24, 2024
1 parent 86b0b15 commit 739898a
Show file tree
Hide file tree
Showing 15 changed files with 872 additions and 702 deletions.
45 changes: 45 additions & 0 deletions lib/cpp/subzero/autonomous/AutoFactory.cpp
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 lib/cpp/subzero/frc/smartdashboard/ModifiableChooser.cpp
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}); });
}
103 changes: 103 additions & 0 deletions lib/cpp/subzero/frc/smartdashboard/TaggedChooser.cpp
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);
}
}
Loading

0 comments on commit 739898a

Please sign in to comment.