Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 91 additions & 133 deletions SerialPrograms/Source/CommonFramework/Options/NestedBoxDrawOption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@
*
*/

#include "Common/Cpp/Containers/Pimpl.tpp"
#include "Common/Cpp/Concurrency/Mutex.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "NestedBoxDrawOption.h"

namespace PokemonAutomation{
namespace NintendoSwitch{



NestedBoxDrawOption::NestedBoxDrawOption(LockMode lock_while_program_is_running)
NestedBoxDrawOption::~NestedBoxDrawOption(){
m_overlay.remove_hid_listener(*this);
CONTENT_BOX.remove_listener(*this);
INFERENCE_BOX.remove_listener(*this);
}
NestedBoxDrawOption::NestedBoxDrawOption(
LockMode lock_while_program_is_running,
VideoOverlay& overlay
)
: BatchOption(lock_while_program_is_running)
, INFERENCE_BOX(
"Inference Box",
Expand All @@ -29,157 +34,110 @@ NestedBoxDrawOption::NestedBoxDrawOption(LockMode lock_while_program_is_running)
true,
{0.1, 0.1, .8, .8}
)
, m_overlay(overlay)
, m_overlay_set(overlay)
{
PA_ADD_OPTION(INFERENCE_BOX);
PA_ADD_OPTION(CONTENT_BOX);
}

INFERENCE_BOX.add_listener(*this);
CONTENT_BOX.add_listener(*this);
overlay.add_hid_listener(*this);
}

class NestedBoxDrawOption::DrawnBox final
: public ConfigOption::Listener
, public VideoDisplayHidListener
{
public:
~DrawnBox(){
detach();
void NestedBoxDrawOption::on_config_value_changed(void* object){
if (this->visibility() != ConfigOptionState::ENABLED){
return;
}
DrawnBox(
VideoOverlay& overlay,
BoxOption& content_box,
BoxOption& inference_box
)
: m_content_box(content_box)
, m_inference_box(inference_box)
, m_overlay(overlay)
, m_overlay_set(overlay)
{
// DrawnBox listens to changes in the config option (X, Y, WIDTH, HEIGHT)
// and mouse events on the video overlay layer.
try{
m_inference_box.add_listener(*this);
m_content_box.add_listener(*this);
overlay.add_hid_listener(*this);
on_config_value_changed(nullptr);
}catch (...){
detach();
throw;
}

std::lock_guard<Mutex> lg(m_lock);
m_overlay_set.clear();
double ix = INFERENCE_BOX.X;
double iy = INFERENCE_BOX.Y;
double iw = INFERENCE_BOX.WIDTH;
double ih = INFERENCE_BOX.HEIGHT;
if (CONTENT_BOX.enabled()){
double cx = CONTENT_BOX.X;
double cy = CONTENT_BOX.Y;
double cw = CONTENT_BOX.WIDTH;
double ch = CONTENT_BOX.HEIGHT;
m_overlay_set.add(COLOR_GREEN, {cx, cy, cw, ch});
ix *= cw;
iy *= ch;
iw *= cw;
ih *= ch;
ix += cx;
iy += cy;
}
virtual void on_config_value_changed(void* object) override{
{
std::lock_guard<Mutex> lg(m_lock);
m_overlay_set.clear();
double ix = m_inference_box.X;
double iy = m_inference_box.Y;
double iw = m_inference_box.WIDTH;
double ih = m_inference_box.HEIGHT;
if (m_content_box.enabled()){
double cx = m_content_box.X;
double cy = m_content_box.Y;
double cw = m_content_box.WIDTH;
double ch = m_content_box.HEIGHT;
m_overlay_set.add(COLOR_GREEN, {cx, cy, cw, ch});
ix *= cw;
iy *= ch;
iw *= cw;
ih *= ch;
ix += cx;
iy += cy;
}
m_overlay_set.add(COLOR_RED, {ix, iy, iw, ih});
}
// if (object != &m_inference_box){
// m_inference_box.on_config_value_changed(object);
// }
m_overlay_set.add(COLOR_RED, {ix, iy, iw, ih});
}
void NestedBoxDrawOption::on_mouse_press(double x, double y){
if (this->visibility() != ConfigOptionState::ENABLED){
return;
}
virtual void on_mouse_press(double x, double y) override{
// m_parent.WIDTH.set(0);
// m_parent.HEIGHT.set(0);
// m_parent.X.set(x);
// m_parent.Y.set(y);
m_mouse_start.emplace();
m_mouse_start->first = x;
m_mouse_start->second = y;
m_mouse_start.emplace();
m_mouse_start->first = x;
m_mouse_start->second = y;
}
void NestedBoxDrawOption::on_mouse_release(double x, double y){
if (this->visibility() != ConfigOptionState::ENABLED){
return;
}
virtual void on_mouse_release(double x, double y) override{
m_mouse_start.reset();
m_mouse_start.reset();
}
void NestedBoxDrawOption::on_mouse_move(double x, double y){
if (this->visibility() != ConfigOptionState::ENABLED){
return;
}
virtual void on_mouse_move(double x, double y) override{
if (!m_mouse_start){
return;
}

double xl = m_mouse_start->first;
double xh = x;
double yl = m_mouse_start->second;
double yh = y;

if (m_content_box.enabled()){
double cx = m_content_box.X;
double cy = m_content_box.Y;
double cw = m_content_box.WIDTH;
double ch = m_content_box.HEIGHT;

xl = (xl - cx) / cw;
xl = std::max(xl, 0.);
xl = std::min(xl, 1.);

yl = (yl - cy) / ch;
yl = std::max(yl, 0.);
yl = std::min(yl, 1.);

xh = (xh - cx) / cw;
xh = std::max(xh, 0.);
xh = std::min(xh, 1.);

yh = (yh - cy) / ch;
yh = std::max(yh, 0.);
yh = std::min(yh, 1.);
}

if (xl > xh){
std::swap(xl, xh);
}
if (yl > yh){
std::swap(yl, yh);
}

m_inference_box.X.set(xl);
m_inference_box.Y.set(yl);
m_inference_box.WIDTH.set(xh - xl);
m_inference_box.HEIGHT.set(yh - yl);
// m_parent.update_box_coordinates();
if (!m_mouse_start){
return;
}

private:
void detach(){
m_overlay.remove_hid_listener(*this);
m_content_box.remove_listener(*this);
m_inference_box.remove_listener(*this);
}
double xl = m_mouse_start->first;
double xh = x;
double yl = m_mouse_start->second;
double yh = y;

private:
BoxOption& m_content_box;
BoxOption& m_inference_box;
VideoOverlay& m_overlay;
VideoOverlaySet m_overlay_set;
Mutex m_lock;
if (CONTENT_BOX.enabled()){
double cx = CONTENT_BOX.X;
double cy = CONTENT_BOX.Y;
double cw = CONTENT_BOX.WIDTH;
double ch = CONTENT_BOX.HEIGHT;

std::optional<std::pair<double, double>> m_mouse_start;
};
xl = (xl - cx) / cw;
xl = std::max(xl, 0.);
xl = std::min(xl, 1.);

yl = (yl - cy) / ch;
yl = std::max(yl, 0.);
yl = std::min(yl, 1.);

xh = (xh - cx) / cw;
xh = std::max(xh, 0.);
xh = std::min(xh, 1.);

Pimpl<NestedBoxDrawOption::DrawnBox> NestedBoxDrawOption::make_session(VideoOverlay& overlay){
return Pimpl<DrawnBox>(CONSTRUCT_TOKEN, overlay, CONTENT_BOX, INFERENCE_BOX);
}
yh = (yh - cy) / ch;
yh = std::max(yh, 0.);
yh = std::min(yh, 1.);
}

if (xl > xh){
std::swap(xl, xh);
}
if (yl > yh){
std::swap(yl, yh);
}

INFERENCE_BOX.X.set(xl);
INFERENCE_BOX.Y.set(yl);
INFERENCE_BOX.WIDTH.set(xh - xl);
INFERENCE_BOX.HEIGHT.set(yh - yl);
}


//template Pimpl<NintendoSwitch::NestedBoxDrawOption::DrawnBox>::Pimpl();
template Pimpl<NintendoSwitch::NestedBoxDrawOption::DrawnBox>::~Pimpl();





}
Expand Down
33 changes: 23 additions & 10 deletions SerialPrograms/Source/CommonFramework/Options/NestedBoxDrawOption.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,43 @@
#ifndef PokemonAutomation_NestedBoxDrawOption_H
#define PokemonAutomation_NestedBoxDrawOption_H

#include "Common/Cpp/Containers/Pimpl.h"
#include "Common/Cpp/Concurrency/Mutex.h"
#include "CommonFramework/VideoPipeline/VideoOverlay.h"
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
#include "BoxOption.h"

namespace PokemonAutomation{
namespace NintendoSwitch{


class NestedBoxDrawOption : public BatchOption, public ConfigOption::Listener{
public:
NestedBoxDrawOption(LockMode lock_while_program_is_running);

class DrawnBox;
Pimpl<DrawnBox> make_session(VideoOverlay& overlay);
class NestedBoxDrawOption
: public BatchOption
, public ConfigOption::Listener
, public VideoDisplayHidListener
{
public:
~NestedBoxDrawOption();
NestedBoxDrawOption(
LockMode lock_while_program_is_running,
VideoOverlay& overlay
);

virtual void on_config_value_changed(void* object) override;
virtual void on_mouse_press(double x, double y) override;
virtual void on_mouse_release(double x, double y) override;
virtual void on_mouse_move(double x, double y) override;

public:
BoxOption INFERENCE_BOX;
BoxOption CONTENT_BOX;
};


private:
VideoOverlay& m_overlay;
Mutex m_lock;
std::optional<std::pair<double, double>> m_mouse_start;
VideoOverlaySet m_overlay_set;
};


}
}
#endif
6 changes: 4 additions & 2 deletions SerialPrograms/Source/ConsoleInfra/ConsolePanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*
* From: https://github.com/PokemonAutomation/
*
* ConsolePanel is a panel with a console and options. It cannot be run.
*
*/

#ifndef PokemonAutomation_ConsoleInfra_ConsolePanel_H
Expand All @@ -27,7 +29,7 @@ class ConsolePanelDescriptor : public PanelDescriptor{
std::string category, std::string display_name,
std::string doc_link,
std::string description,
size_t num_controllers,
size_t num_controllers = 1,
bool deprecated = false,
std::vector<std::string> required_resources = {}
);
Expand Down Expand Up @@ -86,7 +88,7 @@ class ConsolePanelWrapper : public Descriptor{
virtual std::unique_ptr<ConsolePanelInstance> make_instance(
ConsoleSystemSession& system
) const override{
if constexpr (std::is_constructible_v<ConsoleSystemSession&>){
if constexpr (std::is_constructible_v<Instance, ConsoleSystemSession&>){
return std::make_unique<Instance>(system);
}else{
return std::make_unique<Instance>();
Expand Down
44 changes: 44 additions & 0 deletions SerialPrograms/Source/ConsoleInfra/Panels/BoxDraw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* Box Draw
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "ConsoleInfra/ConsoleSystemSession.h"
#include "BoxDraw.h"

//#include <iostream>
//using std::cout;
//using std::endl;

namespace PokemonAutomation{
namespace ConsoleInfra{



BoxDraw_Descriptor::BoxDraw_Descriptor()
: ConsolePanelDescriptor(
Color(),
"NintendoSwitch:BoxDraw",
"Nintendo Switch", "Box Draw",
"",
"Test box coordinates for development."
)
{}


BoxDraw::BoxDraw(ConsoleSystemSession& system)
: BOX_DRAW(LockMode::UNLOCK_WHILE_RUNNING, system.overlay())
{
PA_ADD_OPTION(BOX_DRAW);
}








}
}
Loading
Loading