Skip to content

Commit d385c17

Browse files
committed
Refactor: Separate connection and controller.
1 parent 9657302 commit d385c17

31 files changed

+418
-304
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ file(GLOB MAIN_SOURCES
610610
Source/ComputerPrograms/Framework/ComputerProgramWidget.cpp
611611
Source/ComputerPrograms/Framework/ComputerProgramWidget.h
612612
Source/Controllers/Controller.h
613+
Source/Controllers/ControllerCapability.cpp
613614
Source/Controllers/ControllerCapability.h
614615
Source/Controllers/ControllerDescriptor.cpp
615616
Source/Controllers/ControllerDescriptor.h

SerialPrograms/SerialPrograms.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ SOURCES += \
310310
Source/ComputerPrograms/Framework/ComputerProgramOption.cpp \
311311
Source/ComputerPrograms/Framework/ComputerProgramSession.cpp \
312312
Source/ComputerPrograms/Framework/ComputerProgramWidget.cpp \
313+
Source/Controllers/ControllerCapability.cpp \
313314
Source/Controllers/ControllerConnection.cpp \
314315
Source/Controllers/ControllerSelectorWidget.cpp \
315316
Source/Controllers/ControllerSession.cpp \

SerialPrograms/Source/Controllers/Controller.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@
77
#ifndef PokemonAutomation_Controllers_Controller_H
88
#define PokemonAutomation_Controllers_Controller_H
99

10+
#include <string>
1011
#include "Common/Compiler.h"
1112

1213
class QKeyEvent;
1314

1415
namespace PokemonAutomation{
1516

1617

17-
class Controller{
18+
class AbstractController{
1819
public:
20+
virtual ~AbstractController() = default;
21+
22+
virtual bool is_ready() const = 0;
23+
virtual std::string error_string() const = 0;
24+
25+
public:
26+
// Keyboard Controls
1927
virtual void keyboard_release_all(){}
2028
virtual void keyboard_press(const QKeyEvent& event){}
2129
virtual void keyboard_release(const QKeyEvent& event){}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* Controller Capabilities
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include "ControllerCapability.h"
8+
9+
namespace PokemonAutomation{
10+
11+
12+
const char* to_string(ControllerType type){
13+
switch (type){
14+
case ControllerType::NintendoSwitch_WiredProController:
15+
return "NintendoSwitch_WiredProController";
16+
case ControllerType::NintendoSwitch_WirelessProController:
17+
return "NintendoSwitch_WirelessProController";
18+
case ControllerType::NintendoSwitch_LeftJoycon:
19+
return "NintendoSwitch_LeftJoycon";
20+
case ControllerType::NintendoSwitch_RightJoycon:
21+
return "NintendoSwitch_RightJoycon";
22+
}
23+
return nullptr;
24+
}
25+
26+
27+
28+
const char* to_string(ControllerFeature feature){
29+
switch (feature){
30+
case ControllerFeature::TickPrecise:
31+
return "TickPrecise";
32+
case ControllerFeature::QueryTickSize:
33+
return "QueryTickSize";
34+
case ControllerFeature::QueryCommandQueueSize:
35+
return "QueryCommandQueueSize";
36+
case ControllerFeature::NintendoSwitch_ProController:
37+
return "NintendoSwitch_ProController";
38+
case ControllerFeature::NintendoSwitch_DateSkip:
39+
return "NintendoSwitch_DateSkip";
40+
}
41+
return nullptr;
42+
}
43+
44+
45+
46+
47+
48+
}

SerialPrograms/Source/Controllers/ControllerCapability.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,34 @@
3030
namespace PokemonAutomation{
3131

3232

33+
34+
enum class ControllerInterface{
35+
SerialPABotBase,
36+
};
37+
38+
39+
enum class ControllerType{
40+
None,
41+
NintendoSwitch_WiredProController,
42+
NintendoSwitch_WirelessProController,
43+
NintendoSwitch_LeftJoycon,
44+
NintendoSwitch_RightJoycon,
45+
};
46+
const char* to_string(ControllerType type);
47+
48+
49+
enum class ControllerFeature{
50+
TickPrecise,
51+
QueryTickSize,
52+
QueryCommandQueueSize,
53+
NintendoSwitch_ProController,
54+
NintendoSwitch_DateSkip,
55+
};
56+
const char* to_string(ControllerFeature feature);
57+
58+
59+
60+
3361
//
3462
// This class is a double map.
3563
// The first level is keyed on a string representing the interface type. (serial, bluetooth, etc...)
@@ -44,12 +72,12 @@ namespace PokemonAutomation{
4472
//
4573
class ControllerRequirements{
4674
public:
47-
ControllerRequirements(std::initializer_list<std::map<std::string, std::set<std::string>>::value_type> args)
75+
ControllerRequirements(std::initializer_list<std::map<std::string, std::set<ControllerFeature>>::value_type> args)
4876
: m_map(std::move(args))
4977
, m_sanitizer("ControllerRequirements")
5078
{}
5179

52-
const std::map<std::string, std::set<std::string>>& map() const{
80+
const std::map<std::string, std::set<ControllerFeature>>& map() const{
5381
auto scope_check = m_sanitizer.check_scope();
5482
return m_map;
5583
}
@@ -61,26 +89,26 @@ class ControllerRequirements{
6189

6290
// Check compatibility. If compatible, returns empty string.
6391
// Otherwise returns one of the missing features.
64-
std::string check_compatibility(const std::string& device, const std::set<std::string>& features) const{
92+
std::string check_compatibility(const std::string& device, const std::set<ControllerFeature>& features) const{
6593
auto scope_check = m_sanitizer.check_scope();
6694

6795
auto iter0 = m_map.find(device);
6896
if (iter0 == m_map.end()){
6997
return device;
7098
}
7199

72-
const std::set<std::string>& required = iter0->second;
73-
for (const std::string& feature : required){
100+
const std::set<ControllerFeature>& required = iter0->second;
101+
for (ControllerFeature feature : required){
74102
if (features.find(feature) == features.end()){
75-
return feature;
103+
return to_string(feature);
76104
}
77105
}
78106
return "";
79107
}
80108

81109

82110
private:
83-
std::map<std::string, std::set<std::string>> m_map;
111+
std::map<std::string, std::set<ControllerFeature>> m_map;
84112

85113
LifetimeSanitizer m_sanitizer;
86114
};

SerialPrograms/Source/Controllers/ControllerConnection.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ namespace PokemonAutomation{
1616

1717
void ControllerConnection::add_status_listener(StatusListener& listener){
1818
m_status_listeners.add(listener);
19+
if (m_ready.load(std::memory_order_acquire)){
20+
listener.post_ready(supported_controllers());
21+
}
1922
}
2023
void ControllerConnection::remove_status_listener(StatusListener& listener){
2124
m_status_listeners.remove(listener);
@@ -39,8 +42,8 @@ void ControllerConnection::set_status(const std::string& text){
3942
void ControllerConnection::signal_pre_not_ready(){
4043
m_status_listeners.run_method_unique(&StatusListener::pre_not_ready);
4144
}
42-
void ControllerConnection::signal_post_ready(const std::set<std::string>& capabilities){
43-
m_status_listeners.run_method_unique(&StatusListener::post_ready, capabilities);
45+
void ControllerConnection::signal_post_ready(const std::map<ControllerType, std::set<ControllerFeature>>& controllers){
46+
m_status_listeners.run_method_unique(&StatusListener::post_ready, controllers);
4447
}
4548
void ControllerConnection::signal_status_text_changed(const std::string& text){
4649
// cout << "m_status_listeners.size() = " << m_status_listeners.count_unique() << endl;

SerialPrograms/Source/Controllers/ControllerConnection.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class ControllerConnection{
1919
public:
2020
struct StatusListener{
2121
virtual void pre_not_ready(){}
22-
virtual void post_ready(const std::set<std::string>& capabilities){}
22+
virtual void post_ready(const std::map<ControllerType, std::set<ControllerFeature>>& controllers){}
2323
virtual void post_status_text_changed(const std::string& text){}
2424
};
2525

@@ -30,22 +30,23 @@ class ControllerConnection{
3030
public:
3131
virtual ~ControllerConnection() = default;
3232

33-
bool ready() const{ return m_ready.load(std::memory_order_acquire); }
33+
bool is_ready() const{ return m_ready.load(std::memory_order_acquire); }
3434
std::string status_text() const;
3535

36+
virtual std::map<ControllerType, std::set<ControllerFeature>> supported_controllers() const = 0;
37+
3638

3739
protected:
3840
void set_status(const std::string& text);
3941

4042
void signal_pre_not_ready();
41-
void signal_post_ready(const std::set<std::string>& capabilities);
43+
void signal_post_ready(const std::map<ControllerType, std::set<ControllerFeature>>& controllers);
4244
void signal_status_text_changed(const std::string& text);
4345

4446

4547
protected:
4648
std::atomic<bool> m_ready;
4749

48-
4950
private:
5051
mutable SpinLock m_status_text_lock;
5152
std::string m_status_text;

SerialPrograms/Source/Controllers/ControllerDescriptor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ namespace PokemonAutomation{
2222
//
2323
// Here we store a map of all controller types in the program.
2424
//
25-
std::map<std::string, std::unique_ptr<ControllerType>> CONTROLLER_TYPES;
25+
std::map<std::string, std::unique_ptr<AbstractControllerType>> CONTROLLER_TYPES;
2626

2727

28-
void ControllerType::register_factory(
28+
void AbstractControllerType::register_factory(
2929
const std::string& name,
30-
std::unique_ptr<ControllerType> factory
30+
std::unique_ptr<AbstractControllerType> factory
3131
){
3232
auto ret = CONTROLLER_TYPES.emplace(name, std::move(factory));
3333
if (!ret.second){

SerialPrograms/Source/Controllers/ControllerDescriptor.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
#include <string>
1111
#include <memory>
1212
#include "Common/Cpp/AbstractLogger.h"
13+
#include "ControllerCapability.h"
14+
#include "Controller.h"
1315

1416
namespace PokemonAutomation{
1517

1618
class JsonValue;
1719
class ControllerRequirements;
18-
class ControllerType;
20+
class AbstractControllerType;
1921
class ControllerDescriptor;
2022
class ControllerConnection;
2123

@@ -25,14 +27,14 @@ class ControllerConnection;
2527
//
2628
// For example:
2729
// - "Nintendo Switch via Serial PABotBase" is a type of controller.
28-
// - "Nintendo Switch via Joycon Emulatiion" is a type of controller. (hypothetical)
30+
// - "Nintendo Switch via Joycon Emulation" is a type of controller. (hypothetical)
2931
// - "Xbox One via whatever..." ...
3032
//
3133
// One instance of this class exists for each type of controller.
3234
//
33-
class ControllerType{
35+
class AbstractControllerType{
3436
public:
35-
virtual ~ControllerType() = default;
37+
virtual ~AbstractControllerType() = default;
3638

3739
// Returns a list of all available instances for this controller type.
3840
virtual std::vector<std::shared_ptr<const ControllerDescriptor>> list() const = 0;
@@ -43,7 +45,7 @@ class ControllerType{
4345
protected:
4446
static void register_factory(
4547
const std::string& name,
46-
std::unique_ptr<ControllerType> factory
48+
std::unique_ptr<AbstractControllerType> factory
4749
);
4850
};
4951

@@ -52,7 +54,7 @@ class ControllerType{
5254
// Subclass helper for ControllerType.
5355
//
5456
template <typename DescriptorType>
55-
class ControllerType_t : public ControllerType{
57+
class ControllerType_t : public AbstractControllerType{
5658
public:
5759
// Subclasses must implement this function.
5860
virtual std::vector<std::shared_ptr<const ControllerDescriptor>> list() const override;
@@ -66,7 +68,7 @@ class ControllerType_t : public ControllerType{
6668

6769
private:
6870
static int register_class(){
69-
ControllerType::register_factory(
71+
AbstractControllerType::register_factory(
7072
DescriptorType::TYPENAME,
7173
std::make_unique<ControllerType_t<DescriptorType>>()
7274
);
@@ -96,11 +98,17 @@ class ControllerDescriptor{
9698
virtual void load_json(const JsonValue& json) = 0;
9799
virtual JsonValue to_json() const = 0;
98100

99-
virtual std::unique_ptr<ControllerConnection> open(Logger& logger) const = 0;
100-
virtual std::unique_ptr<ControllerConnection> open(
101+
virtual std::unique_ptr<ControllerConnection> open_connection(
102+
Logger& logger
103+
) const = 0;
104+
virtual std::unique_ptr<AbstractController> make_controller(
101105
Logger& logger,
106+
ControllerConnection& connection,
107+
ControllerType controller_type,
102108
const ControllerRequirements& requirements
103-
) const = 0;
109+
) const{
110+
return nullptr;
111+
}
104112
};
105113

106114

0 commit comments

Comments
 (0)