Skip to content

Commit 82a2edc

Browse files
committed
Automatically update serial port dropdown when a serial port changes.
1 parent 2aa5654 commit 82a2edc

4 files changed

Lines changed: 55 additions & 8 deletions

File tree

SerialPrograms/Source/CommonFramework/Globals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace PokemonAutomation{
3939
#endif
4040

4141
#ifndef PA_VERSION_PATCH
42-
#define PA_VERSION_PATCH 2
42+
#define PA_VERSION_PATCH 3
4343
#endif
4444

4545
const bool IS_BETA_VERSION = PA_IS_BETA;

SerialPrograms/Source/Controllers/PABotBase2/SerialPABotBase2_SelectorWidget.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ namespace SerialPABotBase{
2525

2626

2727

28-
class SerialPABotBase2_SelectorWidget : public NoWheelCompactComboBox{
28+
class SerialPABotBase2_SelectorWidget
29+
: public NoWheelCompactComboBox
30+
, public SerialPortPoller::Listener
31+
{
2932
public:
3033
SerialPABotBase2_SelectorWidget(
3134
ControllerSelectorWidget& parent,
@@ -52,7 +55,7 @@ class SerialPABotBase2_SelectorWidget : public NoWheelCompactComboBox{
5255
parent.session().set_device(descriptor);
5356
}
5457

55-
refresh_devices();
58+
refresh_devices(SerialPortPoller::instance().ports());
5659

5760
connect(
5861
this, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
@@ -69,13 +72,18 @@ class SerialPABotBase2_SelectorWidget : public NoWheelCompactComboBox{
6972
}
7073

7174
parent.session().set_device(selected);
72-
refresh_devices();
75+
refresh_devices(SerialPortPoller::instance().ports());
7376
}
7477
);
78+
79+
SerialPortPoller::instance().add_listener(*this);
80+
}
81+
~SerialPABotBase2_SelectorWidget(){
82+
SerialPortPoller::instance().remove_listener(*this);
7583
}
7684

77-
void refresh_devices(){
78-
SerialPortPoller::instance().begin_refresh_now();
85+
void refresh_devices(const QList<QSerialPortInfo>& ports){
86+
// SerialPortPoller::instance().begin_refresh_now();
7987
// cout << "Current = " << width() << " x " << height() << endl;
8088
// cout << "sizeHint = " << sizeHint().width() << " x " << sizeHint().height() << endl;
8189
// cout << "minimumContentsLength = " << this->minimumContentsLength() << endl;
@@ -87,7 +95,7 @@ class SerialPABotBase2_SelectorWidget : public NoWheelCompactComboBox{
8795

8896

8997
m_ports.emplace_back(new SerialPABotBase2_Descriptor());
90-
for (QSerialPortInfo& port : SerialPortPoller::instance().ports()){
98+
for (const QSerialPortInfo& port : ports){
9199
if (filter_serial_port(port)){
92100
m_ports.emplace_back(
93101
new SerialPABotBase2_Descriptor(port.portName().toStdString())
@@ -115,6 +123,10 @@ class SerialPABotBase2_SelectorWidget : public NoWheelCompactComboBox{
115123
setCurrentIndex(index);
116124
}
117125

126+
virtual void on_serial_ports_changed(const QList<QSerialPortInfo>& ports) override{
127+
refresh_devices(ports);
128+
}
129+
118130

119131
private:
120132
ControllerSelectorWidget& m_parent;

SerialPrograms/Source/Controllers/SerialPortPollerQt.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ SerialPortPoller& SerialPortPoller::instance(){
2121
return poller;
2222
}
2323

24-
SerialPortPoller::SerialPortPoller(){
24+
SerialPortPoller::SerialPortPoller()
25+
: m_last_change(current_time())
26+
{
2527
global_periodic_runner().add_runnable(*this, std::chrono::seconds(10));
2628
}
2729
SerialPortPoller::~SerialPortPoller(){
@@ -35,6 +37,10 @@ void SerialPortPoller::stop(){
3537
void SerialPortPoller::begin_refresh_now(){
3638
global_periodic_runner().run_now_nonblocking(*this);
3739
}
40+
WallClock SerialPortPoller::last_changed() const{
41+
ReadSpinLock lg(m_lock);
42+
return m_last_change;
43+
}
3844
QList<QSerialPortInfo> SerialPortPoller::ports() const{
3945
ReadSpinLock lg(m_lock);
4046
return m_list;
@@ -59,15 +65,20 @@ void SerialPortPoller::run() noexcept{
5965
current.emplace(port.portName().toStdString(), port);
6066
}
6167

68+
WallClock now = current_time();
69+
bool changed = false;
70+
6271
WriteSpinLock lg(m_lock);
6372
auto iter0 = m_last.begin();
6473
auto iter1 = current.begin();
6574
while (iter0 != m_last.end() && iter1 != current.end()){
6675
if (iter0->first < iter1->first){
6776
global_logger_tagged().log("Serial Port Removed: " + iter0->first, COLOR_RED);
77+
changed = true;
6878
++iter0;
6979
}else if (iter0->first > iter1->first){
7080
global_logger_tagged().log("Serial Port Added: " + iter1->first, COLOR_BLUE);
81+
changed = true;
7182
++iter1;
7283
}else{
7384
++iter0;
@@ -76,12 +87,20 @@ void SerialPortPoller::run() noexcept{
7687
}
7788
for (; iter0 != m_last.end(); ++iter0){
7889
global_logger_tagged().log("Serial Port Removed: " + iter0->first, COLOR_RED);
90+
changed = true;
7991
}
8092
for (; iter1 != current.end(); ++iter1){
8193
global_logger_tagged().log("Serial Port Added: " + iter1->first, COLOR_BLUE);
94+
changed = true;
8295
}
8396
m_last = std::move(current);
8497
m_list = std::move(list);
98+
99+
if (changed){
100+
m_last_change = now;
101+
m_listeners.run_method(&Listener::on_serial_ports_changed, m_list);
102+
}
103+
85104
}catch (...){}
86105
// cout << "SerialPortPoller::run() - end" << endl;
87106
}

SerialPrograms/Source/Controllers/SerialPortPollerQt.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <map>
1515
#include <QSerialPortInfo>
16+
#include "Common/Cpp/ListenerSet.h"
1617
#include "Common/Cpp/Concurrency/SpinLock.h"
1718
#include "Common/Cpp/Concurrency/PeriodicRunner.h"
1819

@@ -21,12 +22,24 @@ namespace PokemonAutomation{
2122

2223

2324
class SerialPortPoller : public PeriodicRunner::Runnable{
25+
public:
26+
struct Listener{
27+
virtual void on_serial_ports_changed(const QList<QSerialPortInfo>& ports) = 0;
28+
};
29+
void add_listener(Listener& listener){
30+
m_listeners.add(listener);
31+
}
32+
void remove_listener(Listener& listener){
33+
m_listeners.remove(listener);
34+
}
35+
2436
public:
2537
static SerialPortPoller& instance();
2638

2739
void stop();
2840

2941
void begin_refresh_now();
42+
WallClock last_changed() const;
3043
QList<QSerialPortInfo> ports() const;
3144
QSerialPortInfo get_port(const std::string& name) const;
3245

@@ -37,8 +50,11 @@ class SerialPortPoller : public PeriodicRunner::Runnable{
3750
~SerialPortPoller();
3851

3952
mutable SpinLock m_lock;
53+
WallClock m_last_change;
4054
std::map<std::string, QSerialPortInfo> m_last;
4155
QList<QSerialPortInfo> m_list;
56+
57+
ListenerSet<Listener> m_listeners;
4258
};
4359

4460

0 commit comments

Comments
 (0)