mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	input_common, common: Add a few functions
These functions include reloading udp client, testing communication and configuring calibration. I also added a function to common/thread.h to use WaitFor.
This commit is contained in:
		
							parent
							
								
									58639220a0
								
							
						
					
					
						commit
						8af89b6979
					
				
					 7 changed files with 153 additions and 7 deletions
				
			
		|  | @ -11,7 +11,6 @@ | |||
| #include <boost/asio.hpp> | ||||
| #include <boost/bind.hpp> | ||||
| #include "common/logging/log.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "input_common/udp/client.h" | ||||
| #include "input_common/udp/protocol.h" | ||||
| 
 | ||||
|  | @ -128,12 +127,7 @@ static void SocketLoop(Socket* socket) { | |||
| Client::Client(std::shared_ptr<DeviceStatus> status, const std::string& host, u16 port, | ||||
|                u8 pad_index, u32 client_id) | ||||
|     : status(status) { | ||||
|     SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, | ||||
|                             [this](Response::PortInfo info) { OnPortInfo(info); }, | ||||
|                             [this](Response::PadData data) { OnPadData(data); }}; | ||||
|     LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port); | ||||
|     socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); | ||||
|     thread = std::thread{SocketLoop, this->socket.get()}; | ||||
|     StartCommunication(host, port, pad_index, client_id); | ||||
| } | ||||
| 
 | ||||
| Client::~Client() { | ||||
|  | @ -141,6 +135,12 @@ Client::~Client() { | |||
|     thread.join(); | ||||
| } | ||||
| 
 | ||||
| void Client::ReloadSocket(const std::string& host, u16 port, u8 pad_index, u32 client_id) { | ||||
|     socket->Stop(); | ||||
|     thread.join(); | ||||
|     StartCommunication(host, port, pad_index, client_id); | ||||
| } | ||||
| 
 | ||||
| void Client::OnVersion(Response::Version data) { | ||||
|     LOG_TRACE(Input, "Version packet received: {}", data.version); | ||||
| } | ||||
|  | @ -192,4 +192,93 @@ void Client::OnPadData(Response::PadData data) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Client::StartCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id) { | ||||
|     SocketCallback callback{[this](Response::Version version) { OnVersion(version); }, | ||||
|                             [this](Response::PortInfo info) { OnPortInfo(info); }, | ||||
|                             [this](Response::PadData data) { OnPadData(data); }}; | ||||
|     LOG_INFO(Input, "Starting communication with UDP input server on {}:{}", host, port); | ||||
|     socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback); | ||||
|     thread = std::thread{SocketLoop, this->socket.get()}; | ||||
| } | ||||
| 
 | ||||
| void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
|                        std::function<void()> success_callback, | ||||
|                        std::function<void()> failure_callback) { | ||||
|     std::thread([=] { | ||||
|         Common::Event success_event; | ||||
|         SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {}, | ||||
|                                 [&](Response::PadData data) { success_event.Set(); }}; | ||||
|         Socket socket{host, port, pad_index, client_id, callback}; | ||||
|         std::thread worker_thread{SocketLoop, &socket}; | ||||
|         bool result = success_event.WaitFor(std::chrono::seconds(8)); | ||||
|         socket.Stop(); | ||||
|         worker_thread.join(); | ||||
|         if (result) | ||||
|             success_callback(); | ||||
|         else | ||||
|             failure_callback(); | ||||
|     }) | ||||
|         .detach(); | ||||
| } | ||||
| 
 | ||||
| CalibrationConfigurationJob::CalibrationConfigurationJob( | ||||
|     const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
|     std::function<void(Status)> status_callback, | ||||
|     std::function<void(u16, u16, u16, u16)> data_callback) { | ||||
| 
 | ||||
|     std::thread([=] { | ||||
|         constexpr u16 CALIBRATION_THRESHOLD = 100; | ||||
| 
 | ||||
|         u16 min_x{UINT16_MAX}, min_y{UINT16_MAX}; | ||||
|         u16 max_x, max_y; | ||||
| 
 | ||||
|         Status current_status{Status::Initialized}; | ||||
|         SocketCallback callback{[](Response::Version version) {}, [](Response::PortInfo info) {}, | ||||
|                                 [&](Response::PadData data) { | ||||
|                                     if (current_status == Status::Initialized) { | ||||
|                                         // Receiving data means the communication is ready now
 | ||||
|                                         current_status = Status::Ready; | ||||
|                                         status_callback(current_status); | ||||
|                                     } | ||||
|                                     if (!data.touch_1.is_active) | ||||
|                                         return; | ||||
|                                     LOG_DEBUG(Input, "Current touch: {} {}", data.touch_1.x, | ||||
|                                               data.touch_1.y); | ||||
|                                     min_x = std::min(min_x, static_cast<u16>(data.touch_1.x)); | ||||
|                                     min_y = std::min(min_y, static_cast<u16>(data.touch_1.y)); | ||||
|                                     if (current_status == Status::Ready) { | ||||
|                                         // First touch - min data (min_x/min_y)
 | ||||
|                                         current_status = Status::Stage1Completed; | ||||
|                                         status_callback(current_status); | ||||
|                                     } | ||||
|                                     if (data.touch_1.x - min_x > CALIBRATION_THRESHOLD && | ||||
|                                         data.touch_1.y - min_y > CALIBRATION_THRESHOLD) { | ||||
|                                         // Set the current position as max value and finishes
 | ||||
|                                         // configuration
 | ||||
|                                         max_x = data.touch_1.x; | ||||
|                                         max_y = data.touch_1.y; | ||||
|                                         current_status = Status::Completed; | ||||
|                                         data_callback(min_x, min_y, max_x, max_y); | ||||
|                                         status_callback(current_status); | ||||
| 
 | ||||
|                                         complete_event.Set(); | ||||
|                                     } | ||||
|                                 }}; | ||||
|         Socket socket{host, port, pad_index, client_id, callback}; | ||||
|         std::thread worker_thread{SocketLoop, &socket}; | ||||
|         complete_event.Wait(); | ||||
|         socket.Stop(); | ||||
|         worker_thread.join(); | ||||
|     }) | ||||
|         .detach(); | ||||
| } | ||||
| 
 | ||||
| CalibrationConfigurationJob::~CalibrationConfigurationJob() { | ||||
|     Stop(); | ||||
| } | ||||
| 
 | ||||
| void CalibrationConfigurationJob::Stop() { | ||||
|     complete_event.Set(); | ||||
| } | ||||
| 
 | ||||
| } // namespace InputCommon::CemuhookUDP
 | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <vector> | ||||
| #include <boost/optional.hpp> | ||||
| #include "common/common_types.h" | ||||
| #include "common/thread.h" | ||||
| #include "common/vector_math.h" | ||||
| 
 | ||||
| namespace InputCommon::CemuhookUDP { | ||||
|  | @ -47,15 +48,48 @@ public: | |||
|     explicit Client(std::shared_ptr<DeviceStatus> status, const std::string& host = DEFAULT_ADDR, | ||||
|                     u16 port = DEFAULT_PORT, u8 pad_index = 0, u32 client_id = 24872); | ||||
|     ~Client(); | ||||
|     void ReloadSocket(const std::string& host = "127.0.0.1", u16 port = 26760, u8 pad_index = 0, | ||||
|                       u32 client_id = 24872); | ||||
| 
 | ||||
| private: | ||||
|     void OnVersion(Response::Version); | ||||
|     void OnPortInfo(Response::PortInfo); | ||||
|     void OnPadData(Response::PadData); | ||||
|     void StartCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id); | ||||
| 
 | ||||
|     std::unique_ptr<Socket> socket; | ||||
|     std::shared_ptr<DeviceStatus> status; | ||||
|     std::thread thread; | ||||
|     u64 packet_sequence = 0; | ||||
| }; | ||||
| 
 | ||||
| /// An async job allowing configuration of the touchpad calibration.
 | ||||
| class CalibrationConfigurationJob { | ||||
| public: | ||||
|     enum class Status { | ||||
|         Initialized, | ||||
|         Ready, | ||||
|         Stage1Completed, | ||||
|         Completed, | ||||
|     }; | ||||
|     /**
 | ||||
|      * Constructs and starts the job with the specified parameter. | ||||
|      * | ||||
|      * @param status_callback Callback for job status updates | ||||
|      * @param data_callback Called when calibration data is ready | ||||
|      */ | ||||
|     explicit CalibrationConfigurationJob(const std::string& host, u16 port, u8 pad_index, | ||||
|                                          u32 client_id, std::function<void(Status)> status_callback, | ||||
|                                          std::function<void(u16, u16, u16, u16)> data_callback); | ||||
|     ~CalibrationConfigurationJob(); | ||||
|     void Stop(); | ||||
| 
 | ||||
| private: | ||||
|     Common::Event complete_event; | ||||
| }; | ||||
| 
 | ||||
| void TestCommunication(const std::string& host, u16 port, u8 pad_index, u32 client_id, | ||||
|                        std::function<void()> success_callback, | ||||
|                        std::function<void()> failure_callback); | ||||
| 
 | ||||
| } // namespace InputCommon::CemuhookUDP
 | ||||
|  |  | |||
|  | @ -85,6 +85,11 @@ State::~State() { | |||
|     Input::UnregisterFactory<Input::MotionDevice>("cemuhookudp"); | ||||
| } | ||||
| 
 | ||||
| void State::ReloadUDPClient() { | ||||
|     client->ReloadSocket(Settings::values.udp_input_address, Settings::values.udp_input_port, | ||||
|                          Settings::values.udp_pad_index); | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<State> Init() { | ||||
|     return std::make_unique<State>(); | ||||
| } | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ class State { | |||
| public: | ||||
|     State(); | ||||
|     ~State(); | ||||
|     void ReloadUDPClient(); | ||||
| 
 | ||||
| private: | ||||
|     std::unique_ptr<Client> client; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue