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

✨ Global instances of gamepad #7

Merged
merged 12 commits into from
Aug 21, 2024
20 changes: 16 additions & 4 deletions include/gamepad/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@ class Button {
EventHandler<> onReleaseEvent;
};

namespace _impl {
static struct ControllerInit {
ion098 marked this conversation as resolved.
Show resolved Hide resolved
ControllerInit();
~ControllerInit();
} _controllerInit;
} // namespace _impl

class Controller {
friend struct _impl::ControllerInit;
ion098 marked this conversation as resolved.
Show resolved Hide resolved
public:
explicit Controller(pros::controller_id_e_t id)
: controller(id) {}

/**
* Updates the state of the gamepad (all joysticks and buttons), and also runs
* any registered handlers.
Expand All @@ -69,8 +74,15 @@ class Controller {
Button L1 {}, L2 {}, R1 {}, R2 {}, Up {}, Down {}, Left {}, Right {}, X {}, B {}, Y {}, A {};
float LeftX = 0, LeftY = 0, RightX = 0, RightY = 0;
private:
explicit Controller(pros::controller_id_e_t id)
: controller(id) {}

static Button Controller::*button_to_ptr(pros::controller_digital_e_t button);
void updateButton(pros::controller_digital_e_t button_id);
pros::Controller controller;
}; // namespace Gamepad
};

extern Controller& master;
extern Controller& partner;

} // namespace Gamepad
36 changes: 36 additions & 0 deletions src/gamepad/controller.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
#include "gamepad/controller.hpp"
#include "gamepad/todo.hpp"
#include "pros/misc.h"

#include <new>

namespace Gamepad {

union ControllerBuf {
// this is here to allow us to control when we initialize the Controller
char c;
Controller as_controller;

// empty destructor, the Controller must be manually destroyed by ControllerInit
~ControllerBuf() {}
};

static uint32_t nifty_counter; // zero initialized at load time
ion098 marked this conversation as resolved.
Show resolved Hide resolved
ControllerBuf master_buf {};
Controller& master = master_buf.as_controller;
ControllerBuf partner_buf {};
Controller& partner = partner_buf.as_controller;

_impl::ControllerInit::ControllerInit() {
// only initialize once, if we're the first ControllerInit instance
if (nifty_counter == 0) {
new (&master_buf.as_controller) Controller(pros::E_CONTROLLER_MASTER);
new (&partner_buf.as_controller) Controller(pros::E_CONTROLLER_PARTNER);
}
++nifty_counter;
}

_impl::ControllerInit::~ControllerInit() {
--nifty_counter;
// only destroy if we're the last ControllerInit instance
if (nifty_counter == 0) {
master.~Controller();
partner.~Controller();
}
}

uint32_t Button::onPress(std::function<void(void)> func) { return this->onPressEvent.add_listener(std::move(func)); }

uint32_t Button::onLongPress(std::function<void(void)> func) {
Expand Down
29 changes: 13 additions & 16 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "main.h"
#include "gamepad/api.hpp"

/**
* A callback function for LLEMU's center button.
Expand Down Expand Up @@ -74,21 +75,17 @@ void autonomous() {}
* task, not resume it from where it left off.
*/
void opcontrol() {
pros::Controller master(pros::E_CONTROLLER_MASTER);
pros::MotorGroup left_mg({1, -2, 3}); // Creates a motor group with forwards ports 1 & 3 and reversed port 2
pros::MotorGroup right_mg({-4, 5, -6}); // Creates a motor group with forwards port 4 and reversed ports 4 & 6
ion098 marked this conversation as resolved.
Show resolved Hide resolved
pros::MotorGroup left_mg({1, -2, 3}); // Creates a motor group with forwards ports 1 & 3 and reversed port 2
pros::MotorGroup right_mg({-4, 5, -6}); // Creates a motor group with forwards port 4 and reversed ports 4 & 6

while (true) {
pros::lcd::print(0, "%d %d %d", (pros::lcd::read_buttons() & LCD_BTN_LEFT) >> 2,
(pros::lcd::read_buttons() & LCD_BTN_CENTER) >> 1,

(pros::lcd::read_buttons() & LCD_BTN_RIGHT) >> 0); // Prints status of the emulated screen LCDs

// Arcade control scheme
int dir = master.get_analog(ANALOG_LEFT_Y); // Gets amount forward/backward from left joystick
int turn = master.get_analog(ANALOG_RIGHT_X); // Gets the turn left/right from right joystick
left_mg.move(dir - turn); // Sets left motor voltage
right_mg.move(dir + turn); // Sets right motor voltage
pros::delay(20); // Run for 20 ms then update
}
while (true) {
Gamepad::master.update();
// Arcade control scheme
int dir = Gamepad::master.LeftY; // Gets amount forward/backward from left joystick
int turn = Gamepad::master.RightX; // Gets the turn left/right from right joystick
left_mg.move(dir - turn); // Sets left motor voltage
right_mg.move(dir + turn); // Sets right motor voltage
pros::delay(20); // Run for 20 ms then update
ion098 marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading