Skip to content

Commit 4b929c4

Browse files
committed
Begin work on PABotBase2 drivers.
1 parent 345be78 commit 4b929c4

17 files changed

+229
-56
lines changed

SerialPrograms/Source/Controllers/ControllerConnection.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace PokemonAutomation{
1515

1616

1717

18-
class ControllerConnection{
18+
class ControllerConnection : public CancellableScope{
1919
public:
2020
struct StatusListener{
2121
// virtual void pre_connection_not_ready(ControllerConnection& connection){}
@@ -32,13 +32,16 @@ class ControllerConnection{
3232
void remove_status_listener(StatusListener& listener);
3333

3434

35-
public:
35+
protected:
3636
ControllerConnection()
3737
: m_current_controller(ControllerType::None)
3838
, m_ready(false)
3939
{}
40+
public:
4041
virtual ~ControllerConnection() = default;
4142

43+
44+
public:
4245
ControllerType current_controller() const{
4346
return m_current_controller.load(std::memory_order_acquire);
4447
}

SerialPrograms/Source/Controllers/SerialPABotBase/SerialPABotBase_StatusThread.h renamed to SerialPrograms/Source/Controllers/ControllerStatusThread.h

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
1-
/* SerialPABotBase: Status Thread Helper
1+
/* Controllers: Status Thread Helper
22
*
33
* From: https://github.com/PokemonAutomation/
44
*
55
* This is a helper class to reuse the code for the status updater thread.
66
*
77
*/
88

9-
#ifndef PokemonAutomation_SerialPABotBase_StatusThread_H
10-
#define PokemonAutomation_SerialPABotBase_StatusThread_H
9+
#ifndef PokemonAutomation_Controllers_StatusThread_H
10+
#define PokemonAutomation_Controllers_StatusThread_H
1111

12+
#include "Common/Cpp/Exceptions.h"
1213
#include "Common/Cpp/PrettyPrint.h"
1314
#include "Common/Cpp/Concurrency/Mutex.h"
1415
#include "Common/Cpp/Concurrency/ConditionVariable.h"
16+
#include "Common/Cpp/Concurrency/AsyncTask.h"
17+
#include "Common/Cpp/Concurrency/ThreadPool.h"
1518
#include "CommonFramework/Tools/GlobalThreadPools.h"
16-
#include "SerialPABotBase_Connection.h"
19+
#include "Controllers/ControllerConnection.h"
1720

1821
//#include <iostream>
1922
//using std::cout;
2023
//using std::endl;
2124

2225
namespace PokemonAutomation{
23-
namespace SerialPABotBase{
2426

2527

2628

@@ -36,7 +38,7 @@ struct ControllerStatusThreadCallback{
3638
class ControllerStatusThread{
3739
public:
3840
ControllerStatusThread(
39-
SerialPABotBase_Connection& connection,
41+
ControllerConnection& connection,
4042
ControllerStatusThreadCallback& callback
4143
)
4244
: m_connection(connection)
@@ -56,12 +58,9 @@ class ControllerStatusThread{
5658
m_scope.cancel(nullptr);
5759
{
5860
std::unique_lock<Mutex> lg(m_sleep_lock);
59-
BotBaseController* botbase = m_connection.botbase();
60-
if (botbase){
61-
botbase->on_cancellable_cancel();
62-
}
63-
m_cv.notify_all();
61+
m_connection.cancel();
6462
}
63+
m_cv.notify_all();
6564
m_status_thread.wait_and_ignore_exceptions();
6665
}
6766

@@ -121,11 +120,7 @@ class ControllerStatusThread{
121120
last_ack.store(current_time(), std::memory_order_relaxed);
122121
}catch (OperationCancelledException&){
123122
break;
124-
}catch (InvalidConnectionStateException& e){
125-
error = e.message();
126-
}catch (SerialProtocolException& e){
127-
error = e.message();
128-
}catch (ConnectionException& e){
123+
}catch (Exception& e){
129124
error = e.message();
130125
}catch (...){
131126
error = "Unknown error.";
@@ -157,7 +152,7 @@ class ControllerStatusThread{
157152
}
158153

159154
private:
160-
SerialPABotBase::SerialPABotBase_Connection& m_connection;
155+
ControllerConnection& m_connection;
161156
ControllerStatusThreadCallback& m_callback;
162157
CancellableHolder<CancellableScope> m_scope;
163158
std::atomic<bool> m_stopping;
@@ -172,6 +167,5 @@ class ControllerStatusThread{
172167

173168

174169

175-
}
176170
}
177171
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* PABotBase2 Connection
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_Controllers_PABotBase2_Connection_H
8+
#define PokemonAutomation_Controllers_PABotBase2_Connection_H
9+
10+
#include <memory>
11+
#include "Common/Cpp/CancellableScope.h"
12+
#include "Controllers/ControllerConnection.h"
13+
#include "PABotBase2_DeviceHandle.h"
14+
15+
namespace PokemonAutomation{
16+
namespace PABotBase2{
17+
18+
19+
class Connection : public ControllerConnection{
20+
public:
21+
PABotBase2::DeviceHandle& device(){
22+
return *m_device;
23+
}
24+
25+
26+
protected:
27+
std::unique_ptr<PABotBase2::DeviceHandle> m_device;
28+
};
29+
30+
31+
32+
}
33+
}
34+
#endif

SerialPrograms/Source/Controllers/PABotBase2/SerialPABotBase2_Connection.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,19 @@
77
#ifndef PokemonAutomation_Controllers_SerialPABotBase2_Connection_H
88
#define PokemonAutomation_Controllers_SerialPABotBase2_Connection_H
99

10-
#include "Common/Cpp/CancellableScope.h"
1110
#include "Common/Cpp/Concurrency/AsyncTask.h"
1211
#include "Common/Cpp/SerialConnection/SerialConnection.h"
1312
#include "Common/PABotBase2/ReliableConnectionLayer/PABotBase2CC_ReliableStreamConnection.h"
13+
#include "Controllers/PABotBase2/PABotBase2_Connection.h"
1414
#include "Controllers/SerialPABotBase/Connection/MessageLogger.h"
15-
#include "Controllers/ControllerConnection.h"
1615
#include "PABotBase2_DeviceHandle.h"
1716

1817
namespace PokemonAutomation{
1918
namespace SerialPABotBase{
2019

2120

2221

23-
class SerialPABotBase2_Connection final
24-
: public ControllerConnection
25-
, private CancellableScope
26-
{
22+
class SerialPABotBase2_Connection final : public PABotBase2::Connection{
2723
public:
2824
SerialPABotBase2_Connection(
2925
Logger& logger,

SerialPrograms/Source/Controllers/SerialPABotBase/SerialPABotBase_Connection.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ ControllerType SerialPABotBase_Connection::refresh_controller_type(){
144144
return current_controller;
145145
}
146146

147+
bool SerialPABotBase_Connection::cancel(std::exception_ptr exception) noexcept{
148+
if (ControllerConnection::cancel(std::move(exception))){
149+
return true;
150+
}
151+
if (m_botbase){
152+
m_botbase->on_cancellable_cancel();
153+
}
154+
return false;
155+
}
147156

148157
void SerialPABotBase_Connection::add_message_printers(){
149158
// Errors

SerialPrograms/Source/Controllers/SerialPABotBase/SerialPABotBase_Connection.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace PokemonAutomation{
2323
namespace SerialPABotBase{
2424

2525

26-
class SerialPABotBase_Connection : public ControllerConnection{
26+
class SerialPABotBase_Connection final : public ControllerConnection{
2727
public:
2828
SerialPABotBase_Connection(
2929
Logger& logger,
@@ -50,6 +50,8 @@ class SerialPABotBase_Connection : public ControllerConnection{
5050

5151
ControllerType refresh_controller_type();
5252

53+
virtual bool cancel(std::exception_ptr exception = nullptr) noexcept override;
54+
5355

5456
private:
5557
void add_message_printers();

SerialPrograms/Source/Controllers/StandardHid/StandardHid_Keyboard_SerialPABotBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ SerialPABotBase_Keyboard::SerialPABotBase_Keyboard(
6060
throw SerialProtocolException(logger, PA_CURRENT_FUNCTION, "Failed to set controller type.");
6161
}
6262

63-
m_status_thread.reset(new SerialPABotBase::ControllerStatusThread(
63+
m_status_thread.reset(new ControllerStatusThread(
6464
connection, *this
6565
));
6666
}

SerialPrograms/Source/Controllers/StandardHid/StandardHid_Keyboard_SerialPABotBase.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#ifndef PokemonAutomation_StandardHid_Keyboard_SerialPABotBase_H
88
#define PokemonAutomation_StandardHid_Keyboard_SerialPABotBase_H
99

10+
#include "Controllers/ControllerStatusThread.h"
1011
#include "Controllers/SerialPABotBase/SerialPABotBase_Connection.h"
11-
#include "Controllers/SerialPABotBase/SerialPABotBase_StatusThread.h"
1212
#include "StandardHid_Keyboard.h"
1313
#include "StandardHid_KeyboardWithScheduler.h"
1414

@@ -20,7 +20,7 @@ namespace StandardHid{
2020
class SerialPABotBase_Keyboard final :
2121
public Keyboard,
2222
public KeyboardControllerWithScheduler,
23-
private SerialPABotBase::ControllerStatusThreadCallback
23+
private ControllerStatusThreadCallback
2424
{
2525
public:
2626
using ContextType = KeyboardContext;
@@ -135,7 +135,7 @@ class SerialPABotBase_Keyboard final :
135135

136136
std::map<uint64_t, KeyboardKey> m_last_state;
137137

138-
std::unique_ptr<SerialPABotBase::ControllerStatusThread> m_status_thread;
138+
std::unique_ptr<ControllerStatusThread> m_status_thread;
139139
};
140140

141141

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* PABotBase2: Controller
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "Common/Cpp/Exceptions.h"
8+
#include "NintendoSwitch_PABotBase2_Controller.h"
9+
10+
namespace PokemonAutomation{
11+
namespace NintendoSwitch{
12+
13+
14+
void PABotBase2_Controller::stop_with_error(std::string error_message) noexcept{
15+
try{
16+
WriteSpinLock lg(m_error_lock);
17+
m_error_string = error_message;
18+
}catch (...){}
19+
m_connection.cancel();
20+
m_connection.set_status_line1(std::move(error_message), COLOR_RED);
21+
}
22+
23+
24+
std::string PABotBase2_Controller::error_string() const{
25+
ReadSpinLock lg(m_error_lock);
26+
return m_error_string;
27+
}
28+
29+
void PABotBase2_Controller::cancel_all_commands(){
30+
std::lock_guard<Mutex> lg(m_state_lock);
31+
if (!is_ready()){
32+
throw InvalidConnectionStateException(error_string());
33+
}
34+
m_connection.device().command_queue().send_cancel();
35+
m_scheduler.clear_on_next();
36+
}
37+
void PABotBase2_Controller::replace_on_next_command(){
38+
std::lock_guard<Mutex> lg(m_state_lock);
39+
if (!is_ready()){
40+
throw InvalidConnectionStateException(error_string());
41+
}
42+
m_connection.device().command_queue().send_replace_on_next();
43+
m_scheduler.clear_on_next();
44+
}
45+
46+
47+
void PABotBase2_Controller::wait_for_all(Cancellable* cancellable){
48+
SuperscalarScheduler::Schedule schedule;
49+
std::lock_guard<Mutex> lg0(m_issue_lock);
50+
{
51+
std::lock_guard<Mutex> lg1(m_state_lock);
52+
53+
ThrottleScope scope(m_logging_throttler);
54+
if (scope){
55+
m_logger.log("wait_for_all()", COLOR_DARKGREEN);
56+
}
57+
58+
if (!is_ready()){
59+
throw InvalidConnectionStateException(error_string());
60+
}
61+
62+
m_scheduler.issue_wait_for_all(schedule);
63+
}
64+
execute_schedule(cancellable, schedule);
65+
m_connection.device().command_queue().wait_for_all();
66+
}
67+
68+
69+
70+
71+
}
72+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* PABotBase2: Controller
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_NintendoSwitch_PABotBase2_Controller_H
8+
#define PokemonAutomation_NintendoSwitch_PABotBase2_Controller_H
9+
10+
#include "Controllers/PABotBase2/PABotBase2_Connection.h"
11+
#include "NintendoSwitch/Controllers/NintendoSwitch_ControllerWithScheduler.h"
12+
13+
namespace PokemonAutomation{
14+
namespace NintendoSwitch{
15+
16+
17+
18+
class PABotBase2_Controller : public ControllerWithScheduler{
19+
public:
20+
PABotBase2_Controller(
21+
Logger& logger,
22+
PABotBase2::Connection& connection
23+
)
24+
: ControllerWithScheduler(logger)
25+
, m_connection(connection)
26+
{}
27+
28+
void stop_with_error(std::string error_message) noexcept;
29+
30+
bool is_ready() const{
31+
return m_connection.is_ready();
32+
}
33+
std::string error_string() const;
34+
35+
36+
public:
37+
void cancel_all_commands();
38+
void replace_on_next_command();
39+
40+
void wait_for_all(Cancellable* cancellable);
41+
42+
43+
protected:
44+
// These are set on construction and never changed again. So it is safe to
45+
// access these asynchronously.
46+
PABotBase2::Connection& m_connection;
47+
48+
mutable SpinLock m_error_lock;
49+
std::string m_error_string;
50+
};
51+
52+
53+
54+
}
55+
}
56+
#endif

0 commit comments

Comments
 (0)