Skip to content

Commit 1282a65

Browse files
authored
Merge pull request #670 from PokemonAutomation/main
Update to latest.
2 parents 154e25d + 3d3588c commit 1282a65

File tree

13 files changed

+257
-97
lines changed

13 files changed

+257
-97
lines changed

SerialPrograms/Source/CommonFramework/Globals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace PokemonAutomation{
2626
const bool IS_BETA_VERSION = true;
2727
const int PROGRAM_VERSION_MAJOR = 0;
2828
const int PROGRAM_VERSION_MINOR = 55;
29-
const int PROGRAM_VERSION_PATCH = 1;
29+
const int PROGRAM_VERSION_PATCH = 2;
3030

3131
const std::string PROGRAM_VERSION_BASE =
3232
"v" + std::to_string(PROGRAM_VERSION_MAJOR) +

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.cpp

Lines changed: 178 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -90,109 +90,208 @@ void VideoSession::set(const VideoSourceOption& option){
9090
}
9191

9292
void VideoSession::reset(){
93-
m_logger.log("Resetting the video...", COLOR_GREEN);
94-
dispatch_to_main_thread([this]{
95-
std::lock_guard<std::mutex> lg0(m_reset_lock);
93+
{
94+
WriteSpinLock lg(m_queue_lock);
95+
// cout << "VideoSession::reset(): " << m_queued_commands.size() << endl;
96+
m_queued_commands.emplace_back(
97+
Command{
98+
CommandType::RESET,
99+
nullptr,
100+
Resolution{}
101+
}
102+
);
103+
}
104+
dispatch_to_main_thread([this]{ run_commands(); });
105+
}
106+
void VideoSession::set_source(
107+
const std::shared_ptr<VideoSourceDescriptor>& device,
108+
Resolution resolution
109+
){
110+
{
111+
WriteSpinLock lg(m_queue_lock);
112+
// cout << "VideoSession::set_source(): " << m_queued_commands.size() << endl;
113+
m_queued_commands.emplace_back(
114+
Command{
115+
CommandType::SET_SOURCE,
116+
device,
117+
resolution
118+
}
119+
);
120+
}
121+
dispatch_to_main_thread([this]{ run_commands(); });
122+
}
123+
void VideoSession::set_resolution(Resolution resolution){
124+
{
125+
WriteSpinLock lg(m_queue_lock);
126+
// cout << "VideoSession::set_resolution(): " << m_queued_commands.size() << endl;
127+
m_queued_commands.emplace_back(
128+
Command{
129+
CommandType::SET_RESOLUTION,
130+
nullptr,
131+
resolution
132+
}
133+
);
134+
}
135+
dispatch_to_main_thread([this]{ run_commands(); });
136+
}
96137

97-
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
138+
void VideoSession::internal_reset(){
139+
m_logger.log("Resetting the video...", COLOR_GREEN);
140+
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
98141

99-
{
100-
WriteSpinLock lg(m_state_lock);
101-
if (m_video_source){
102-
m_video_source->remove_source_frame_listener(*this);
103-
m_video_source->remove_rendered_frame_listener(*this);
104-
m_video_source.reset();
105-
}
142+
Resolution resolution = m_option.m_resolution;
143+
std::unique_ptr<VideoSource> source;
144+
{
145+
WriteSpinLock lg(m_state_lock);
146+
source = std::move(m_video_source);
147+
}
148+
if (source){
149+
source->remove_source_frame_listener(*this);
150+
source->remove_rendered_frame_listener(*this);
151+
source.reset();
152+
}
106153

107-
m_video_source = m_descriptor->make_VideoSource(m_logger, m_option.m_resolution);
154+
source = m_descriptor->make_VideoSource(m_logger, resolution);
155+
if (source){
156+
resolution = source->current_resolution();
157+
source->add_source_frame_listener(*this);
158+
source->add_rendered_frame_listener(*this);
159+
}
108160

109-
if (m_video_source){
110-
m_option.m_resolution = m_video_source->current_resolution();
111-
m_video_source->add_source_frame_listener(*this);
112-
m_video_source->add_rendered_frame_listener(*this);
113-
}
114-
}
161+
{
162+
WriteSpinLock lg(m_state_lock);
163+
m_option.m_resolution = resolution;
164+
m_video_source = std::move(source);
165+
}
115166

116-
m_state_listeners.run_method_unique(
117-
&StateListener::post_startup,
118-
m_video_source.get()
119-
);
120-
});
167+
m_state_listeners.run_method_unique(
168+
&StateListener::post_startup,
169+
m_video_source.get()
170+
);
121171
}
122-
void VideoSession::set_source(
172+
void VideoSession::internal_set_source(
123173
const std::shared_ptr<VideoSourceDescriptor>& device,
124174
Resolution resolution
125175
){
126176
m_logger.log("Changing video...", COLOR_GREEN);
127-
dispatch_to_main_thread([this, device, resolution]{
128-
std::lock_guard<std::mutex> lg0(m_reset_lock);
129-
if (*m_descriptor == *device && !m_descriptor->should_reload()){
130-
return;
131-
}
132-
133-
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
134-
135-
{
136-
WriteSpinLock lg(m_state_lock);
137-
if (m_video_source){
138-
m_video_source->remove_source_frame_listener(*this);
139-
m_video_source->remove_rendered_frame_listener(*this);
140-
m_video_source.reset();
141-
}
177+
if (*m_descriptor == *device && !m_descriptor->should_reload()){
178+
return;
179+
}
142180

143-
m_option.set_descriptor(device);
144-
m_descriptor = device;
181+
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
145182

146-
Resolution desired_resolution = resolution ? resolution : m_option.m_resolution;
147-
// cout << "VideoSession::set_source(): " << &m_option << " - " << desired_resolution.width << " x " << desired_resolution.height << endl;
183+
std::unique_ptr<VideoSource> source;
184+
{
185+
WriteSpinLock lg(m_state_lock);
186+
source = std::move(m_video_source);
187+
}
188+
if (source){
189+
source->remove_source_frame_listener(*this);
190+
source->remove_rendered_frame_listener(*this);
191+
source.reset();
192+
}
193+
{
194+
WriteSpinLock lg(m_state_lock);
195+
m_option.set_descriptor(device);
196+
m_descriptor = device;
197+
}
148198

149-
m_video_source = device->make_VideoSource(m_logger, desired_resolution);
199+
Resolution desired_resolution = resolution ? resolution : m_option.m_resolution;
200+
source = device->make_VideoSource(m_logger, desired_resolution);
201+
if (source){
202+
resolution = source->current_resolution();
203+
source->add_source_frame_listener(*this);
204+
source->add_rendered_frame_listener(*this);
205+
}
150206

151-
if (m_video_source){
152-
m_option.m_resolution = m_video_source->current_resolution();
153-
m_video_source->add_source_frame_listener(*this);
154-
m_video_source->add_rendered_frame_listener(*this);
155-
}
156-
}
207+
{
208+
WriteSpinLock lg(m_state_lock);
209+
m_option.m_resolution = resolution;
210+
m_video_source = std::move(source);
211+
}
157212

158-
m_state_listeners.run_method_unique(
159-
&StateListener::post_startup,
160-
m_video_source.get()
161-
);
162-
});
213+
m_state_listeners.run_method_unique(
214+
&StateListener::post_startup,
215+
m_video_source.get()
216+
);
163217
}
164-
void VideoSession::set_resolution(Resolution resolution){
218+
void VideoSession::internal_set_resolution(Resolution resolution){
165219
m_logger.log("Changing resolution...", COLOR_GREEN);
166-
dispatch_to_main_thread([this, resolution]{
167-
std::lock_guard<std::mutex> lg0(m_reset_lock);
168-
if (m_option.m_resolution == resolution){
169-
return;
170-
}
220+
if (m_option.m_resolution == resolution){
221+
return;
222+
}
223+
224+
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
225+
226+
std::unique_ptr<VideoSource> source;
227+
{
228+
WriteSpinLock lg(m_state_lock);
229+
source = std::move(m_video_source);
230+
}
231+
if (source){
232+
source->remove_source_frame_listener(*this);
233+
source->remove_rendered_frame_listener(*this);
234+
source.reset();
235+
}
236+
237+
source = m_descriptor->make_VideoSource(m_logger, resolution);
238+
if (source){
239+
resolution = source->current_resolution();
240+
source->add_source_frame_listener(*this);
241+
source->add_rendered_frame_listener(*this);
242+
}
243+
244+
{
245+
WriteSpinLock lg(m_state_lock);
246+
m_option.m_resolution = resolution;
247+
m_video_source = std::move(source);
248+
}
171249

172-
{
173-
WriteSpinLock lg(m_state_lock);
174-
m_state_listeners.run_method_unique(&StateListener::pre_shutdown);
250+
m_state_listeners.run_method_unique(
251+
&StateListener::post_startup,
252+
m_video_source.get()
253+
);
254+
}
175255

176-
if (m_video_source){
177-
m_video_source->remove_source_frame_listener(*this);
178-
m_video_source->remove_rendered_frame_listener(*this);
179-
m_video_source.reset();
256+
void VideoSession::run_commands(){
257+
std::lock_guard<std::recursive_mutex> lg0(m_reset_lock);
258+
if (m_recursion_depth != 0){
259+
m_logger.log("Suppressing re-entrant command...", COLOR_RED);
260+
return;
261+
}
262+
m_recursion_depth++;
263+
try{
264+
while (true){
265+
Command command;
266+
{
267+
WriteSpinLock lg(m_queue_lock);
268+
// cout << "VideoSession::run_commands(): " << m_queued_commands.size() << endl;
269+
if (m_queued_commands.empty()){
270+
break;
271+
}
272+
command = std::move(m_queued_commands.front());
273+
m_queued_commands.pop_front();
180274
}
181275

182-
m_video_source = m_descriptor->make_VideoSource(m_logger, resolution);
276+
switch (command.command_type){
277+
case CommandType::RESET:
278+
internal_reset();
279+
break;
183280

184-
if (m_video_source){
185-
m_option.m_resolution = m_video_source->current_resolution();
186-
m_video_source->add_source_frame_listener(*this);
187-
m_video_source->add_rendered_frame_listener(*this);
281+
case CommandType::SET_SOURCE:
282+
internal_set_source(command.device, command.resolution);
283+
break;
284+
285+
case CommandType::SET_RESOLUTION:
286+
internal_set_resolution(command.resolution);
287+
break;
188288
}
189289
}
190-
191-
m_state_listeners.run_method_unique(
192-
&StateListener::post_startup,
193-
m_video_source.get()
194-
);
195-
});
290+
m_recursion_depth--;
291+
}catch (...){
292+
m_recursion_depth--;
293+
throw;
294+
}
196295
}
197296

198297

SerialPrograms/Source/CommonFramework/VideoPipeline/VideoSession.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define PokemonAutomation_VideoPipeline_VideoSession_H
99

1010
#include <memory>
11+
#include <deque>
1112
#include <mutex>
1213
#include "Common/Cpp/EventRateTracker.h"
1314
#include "Common/Cpp/Concurrency/SpinLock.h"
@@ -176,7 +177,28 @@ class VideoSession
176177

177178

178179
private:
179-
mutable std::mutex m_reset_lock;
180+
enum CommandType{
181+
RESET,
182+
SET_SOURCE,
183+
SET_RESOLUTION
184+
};
185+
struct Command{
186+
CommandType command_type;
187+
std::shared_ptr<VideoSourceDescriptor> device;
188+
Resolution resolution;
189+
};
190+
void run_commands();
191+
192+
void internal_reset();
193+
void internal_set_source(
194+
const std::shared_ptr<VideoSourceDescriptor>& device,
195+
Resolution resolution = {}
196+
);
197+
void internal_set_resolution(Resolution resolution);
198+
199+
200+
private:
201+
mutable std::recursive_mutex m_reset_lock;
180202
mutable SpinLock m_state_lock;
181203

182204
Logger& m_logger;
@@ -189,6 +211,12 @@ class VideoSession
189211
std::shared_ptr<const VideoSourceDescriptor> m_descriptor;
190212
std::unique_ptr<VideoSource> m_video_source;
191213

214+
// We need to queue up all reset commands and run them on the main thread.
215+
// This is needed to prevent re-entrant calls from event processing.
216+
SpinLock m_queue_lock;
217+
size_t m_recursion_depth = 0;
218+
std::deque<Command> m_queued_commands;
219+
192220
ListenerSet<StateListener> m_state_listeners;
193221
ListenerSet<VideoFrameListener> m_frame_listeners;
194222
};

SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@
139139
#include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_PathSide.h"
140140
#include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_PathMap.h"
141141
#include "NintendoSwitch/Inference/NintendoSwitch_SelectedSettingDetector.h"
142+
#include "PokemonSV/Inference/Boxes/PokemonSV_BoxShinyDetector.h"
143+
#include "PokemonSwSh/Inference/PokemonSwSh_DialogBoxDetector.h"
142144

143145
#include <QPixmap>
144146
#include <QVideoFrame>
@@ -260,10 +262,23 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope&
260262

261263
auto screenshot = feed.snapshot();
262264

263-
YCommIconDetector detector(true);
265+
PokemonSwSh::BlackDialogBoxDetector detector(true);
266+
detector.make_overlays(overlays);
264267
cout << detector.process_frame(screenshot, current_time()) << endl;
265268

266269

270+
271+
// PokemonSV::BoxShinyDetector detector;
272+
// cout << detector.detect(screenshot) << endl;
273+
274+
275+
276+
277+
#if 0
278+
YCommIconDetector detector(true);
279+
cout << detector.process_frame(screenshot, current_time()) << endl;
280+
#endif
281+
267282
#if 0
268283
bool switch2 = true;
269284
ImageFloatBox key1_box;

SerialPrograms/Source/NintendoSwitch/NintendoSwitch_Settings.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,6 @@ ConsoleSettingsPanel::ConsoleSettingsPanel(const ConsoleSettings_Descriptor& des
165165
, settings(ConsoleSettings::instance())
166166
{
167167
PA_ADD_OPTION(settings);
168-
169-
settings.CONTROLLER_SETTINGS.set_visibility(
170-
settings.CONTROLLER_SETTINGS.current_rows() > 0
171-
? ConfigOptionState::ENABLED
172-
: ConfigOptionState::HIDDEN
173-
);
174168
}
175169

176170

0 commit comments

Comments
 (0)