Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 🥅 Change all error handling to use errno, add int32_t return codes #25

Merged
merged 15 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

# PROS
bin/
.vscode/
.vscode/*
.cache/
compile_commands.json
temp.log
Expand All @@ -24,3 +24,6 @@ temp.errors

# Linux
debug.log

# Always include development settings
!.vscode/settings.json
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"main"
],
"conventionalCommits.scopes": [
"buttons",
"display",
"joysticks"
]
}
59 changes: 34 additions & 25 deletions include/gamepad/button.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ class Button {
*
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run when the button is pressed, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -84,7 +84,7 @@ class Button {
* gamepad::master.Up.onPress("upPress1", []() { std::cout << "I was pressed!" << std::endl; });
* @endcode
*/
bool onPress(std::string listenerName, std::function<void(void)> func) const;
int32_t onPress(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run when the button is long pressed.
*
Expand All @@ -96,8 +96,8 @@ class Button {
*
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run when the button is long pressed, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -108,14 +108,14 @@ class Button {
* std::endl; });
* @endcode
*/
bool onLongPress(std::string listenerName, std::function<void(void)> func) const;
int32_t onLongPress(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run when the button is released.
*
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run when the button is released, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -125,7 +125,7 @@ class Button {
* gamepad::master.Y.onRelease("stopIntake", []() { intake.move(0); });
* @endcode
*/
bool onRelease(std::string listenerName, std::function<void(void)> func) const;
int32_t onRelease(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run when the button is short released.
*
Expand All @@ -136,8 +136,8 @@ class Button {
*
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run when the button is short released, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -147,7 +147,7 @@ class Button {
* gamepad::master.B.onShortRelease("intakeOnePiece", []() { intake.move_relative(600, 100); });
* @endcode
*/
bool onShortRelease(std::string listenerName, std::function<void(void)> func) const;
int32_t onShortRelease(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run when the button is long released.
*
Expand All @@ -156,8 +156,8 @@ class Button {
*
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run when the button is long released, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -168,7 +168,7 @@ class Button {
* @endcode
*
*/
bool onLongRelease(std::string listenerName, std::function<void(void)> func) const;
int32_t onLongRelease(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run periodically after its been held
*
Expand All @@ -177,8 +177,8 @@ class Button {
*
* @param listenerName The name of the listener, this must be a unique name
* @param func the function to run periodically when the button is held, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -189,15 +189,15 @@ class Button {
* @endcode
*
*/
bool onRepeatPress(std::string listenerName, std::function<void(void)> func) const;
int32_t onRepeatPress(std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Register a function to run for a given event.
*
* @param event Which event to register the listener on.
* @param listenerName The name of the listener, this must be a unique name
* @param func The function to run for the given event, the function MUST NOT block
* @return true The listener was successfully registered
* @return false The listener was not successfully registered (there is already a listener with this name)
* @return 0 The listener was successfully registered
* @return INT32_MAX The listener was not successfully registered (there is already a listener with this name)
*
* @b Example:
* @code {.cpp}
Expand All @@ -207,24 +207,25 @@ class Button {
* gamepad::master.L1.addListener(gamepad::ON_RELEASE, "stop_spin", []() { motor1.brake(); });
* @endcode
*/
bool addListener(EventType event, std::string listenerName, std::function<void(void)> func) const;
int32_t addListener(EventType event, std::string listenerName, std::function<void(void)> func) const;
/**
* @brief Removes a listener from the button
* @warning Usage of this function is discouraged.
*
* @param event the event type of the listener
* @param listenerName The name of the listener to remove
* @return true The specified listener was successfully removed
* @return false The specified listener could not be removed
* @return 0 The specified listener was successfully removed
* @return INT32_MAX The specified listener could not be removed
*
* @b Example:
* @code {.cpp}
* // Add an event listener...
* gamepad::master.L1.addListener(gamepad::ON_PRESS, "do_something", doSomething);
* // ...and now get rid of it
* gamepad::master.L1.removeListener("do_something");
* gamepad::master.L1.removeListener(gamepad::ON_PRESS, "do_something");
* @endcode
*/
bool removeListener(std::string listenerName) const;
int32_t removeListener(EventType event, std::string listenerName) const;

/**
* @brief Returns a value indicating whether the button is currently being held.
Expand All @@ -240,6 +241,14 @@ class Button {
* @param is_held Whether or not the button is currently held down
*/
void update(bool is_held);
/**
* @brief Get the handler object for the given event type
*
* @param event The desired event type
* @return nullptr The event value is invalid
* @return _impl::EventHandler<std::string>* A pointer to the given event's handler
*/
_impl::EventHandler<std::string>* get_handler(EventType event) const;
/// How long the threshold should be for the longPress and shortRelease events
mutable uint32_t m_long_press_threshold = 500;
/// How often repeatPress is called
Expand Down
22 changes: 11 additions & 11 deletions include/gamepad/event_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,37 @@ template <typename Key, typename... Args> class EventHandler {
*
* @param key The listener key (this must be a unique key value)
* @param func The function to run when this event is fired
* @return true The listener was successfully added
* @return false The listener was NOT successfully added (there is already a listener with the same key)
* @return 0 The listener was successfully added
* @return INT32_MAX The listener was NOT successfully added (there is already a listener with the same key)
*/
bool addListener(Key key, Listener func) {
int32_t addListener(Key key, Listener func) {
std::lock_guard lock(m_mutex);
if (std::find(m_keys.begin(), m_keys.end(), key) != m_keys.end()) return false;
if (std::find(m_keys.begin(), m_keys.end(), key) != m_keys.end()) return INT32_MAX;
m_keys.push_back(key);
m_listeners.push_back(func);
return true;
return 0;
}

/**
* @brief Remove a listener from the list of listeners
*
* @param key The listener key (this must be a unique key value)
* @return true The listener was successfully removed
* @return false The listener was NOT successfully removed (there is no listener with the same key)
* @return 0 The listener was successfully removed
* @return INT32_MAX The listener was NOT successfully removed (there is no listener with the same key)
*/
bool removeListener(Key key) {
int32_t removeListener(Key key) {
std::lock_guard lock(m_mutex);
auto i = std::find(m_keys.begin(), m_keys.end(), key);
if (i != m_keys.end()) {
m_keys.erase(i);
m_listeners.erase(m_listeners.begin() + (i - m_keys.begin()));
return true;
return 0;
}
return false;
return INT32_MAX;
}

/**
* @brief Whther or not there are any listeners registered
* @brief Whether or not there are any listeners registered
*
* @return true There are listeners registered
* @return false There are no listeners registered
Expand Down
33 changes: 30 additions & 3 deletions include/gamepad/gamepad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,42 +49,69 @@ class Gamepad {
* @param line the line number to print the string on (0-2)
* @param str the string to print onto the controller (\n to go to the next line)
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The line number is not in the interval [0, 2]
* EMSGSIZE: The string is more than 3 lines long
*
* @b Example:
* @code {.cpp}
* gamepad::master.printLine(1, "This will print on the middle line");
* gamepad::master.printLine(0, "this will print\n\naround the middle line");
* @endcode
*
* @return 0 if the line was printed successfully
* @return INT32_MAX if there was an error, setting errno
*/
void printLine(uint8_t line, std::string str);
int32_t printLine(uint8_t line, std::string str);
/**
* @brief clears all lines on the controller, similar to the pros function (low priority)
*
* @b Example:
* @code {.cpp}
* // clears the whole screen on the controller
* gamepad::master.clear()
* @endcode
*/
void clear();
/**
* @brief clears the specific line on the controller, similar to the pros function clear_line (low priority)
*
* @param line the line to clear (0-2)
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The line number is not in the interval [0, 2]
*
* @b Example:
* @code {.cpp}
* // clears the center line on the controller
* gamepad::master.clear(1);
* @endcode
*
* @return 0 if the line was cleared successfully
* @return INT32_MAX if there was an error, setting errno
*/
void clear(uint8_t line);
int32_t clear(uint8_t line);
/**
* makes the controller rumble like pros (low priority)
*
* @param rumble_pattern A string consisting of the characters '.', '-', and ' ', where dots are short rumbles,
* dashes are long rumbles, and spaces are pauses. Maximum supported length is 8 characters.
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The rumble pattern contains a character other than '.', '-', or ' '
* EMSGSIZE: The pattern is more than 8 characters long
*
* @b Example:
* @code {.cpp}
* // rumbles in the following pattern: short, pause, long, short short
* gamepad::master.rumble(". -..");
* @endcode
*
* @return 0 if the rumble was successful
* @return INT32_MAX if there was an error, setting errno
*/
void rumble(std::string rumble_pattern);
/**
Expand Down Expand Up @@ -150,7 +177,7 @@ class Gamepad {
* @return std::string A unique listener name
*/
static std::string uniqueName();
static Button Gamepad::*buttonToPtr(pros::controller_digital_e_t button);
static Button Gamepad::* buttonToPtr(pros::controller_digital_e_t button);
void updateButton(pros::controller_digital_e_t button_id);

void updateScreens();
Expand Down
11 changes: 10 additions & 1 deletion include/gamepad/screens/alertScreen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,17 @@ class AlertScreen : public AbstractScreen {
* @param duration how long the alert should persist on the screen
* @param rumble A string consisting of the characters '.', '-', and ' ', where dots are short rumbles,
* dashes are long rumbles, and spaces are pauses. Maximum supported length is 8 characters.
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The line number is not in the interval [0, 2]
* EMSGSIZE: The alert is more than 3 lines long
*
* @return 0 if the alert was added successfully
* @return INT32_MAX if there was an error, setting errno
*
*/
void addAlerts(uint8_t line, std::string strs, uint32_t duration, std::string rumble = "");
int32_t addAlerts(uint8_t line, std::string strs, uint32_t duration, std::string rumble = "");
private:
struct AlertBuffer {
ScreenBuffer screen;
Expand Down
20 changes: 18 additions & 2 deletions include/gamepad/screens/defaultScreen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,32 @@ class DefaultScreen : public AbstractScreen {
*
* @param line the line number to print the string on (0-2)
* @param str the string to print onto the controller (\n to go to the next line)
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The line number is not in the interval [0, 2]
* EMSGSIZE: The string is more than 3 lines long
*
* @return 0 if the alert was added successfully
* @return INT32_MAX if there was an error, setting errno
*/
void printLine(uint8_t line, std::string str);
int32_t printLine(uint8_t line, std::string str);

/**
* makes the controller rumble like pros
*
* @param rumble_pattern A string consisting of the characters '.', '-', and ' ', where dots are short rumbles,
* dashes are long rumbles, and spaces are pauses. Maximum supported length is 8 characters.
*
* This function uses the following value(s) of errno when an error state is reached:
*
* EINVAL: The rumble pattern contains a character other than '.', '-', or ' '
* EMSGSIZE: The pattern is more than 8 characters long
*
* @return 0 if the alert was added successfully
* @return INT32_MAX if there was an error, setting errno
*/
void rumble(std::string rumble_pattern);
int32_t rumble(std::string rumble_pattern);
private:
ScreenBuffer m_current_buffer {};
pros::Mutex m_mutex {};
Expand Down
Loading