| 484 | } |
| 485 | |
| 486 | bool ControllerAgent::handle_swipe(const SwipeParam& param) |
| 487 | { |
| 488 | if (!control_unit_) { |
| 489 | LogError << "control_unit_ is nullptr"; |
| 490 | return false; |
| 491 | } |
| 492 | |
| 493 | const bool use_touch_down_up = control_unit_->get_features() & MaaControllerFeature_UseMouseDownAndUpInsteadOfClick; |
| 494 | if (!use_touch_down_up) { |
| 495 | LogWarn << "touch not supported, use swipe instead. some features can not work"; |
| 496 | } |
| 497 | |
| 498 | cv::Point begin = preproc_touch_point(param.begin); |
| 499 | bool ret = !param.end.empty(); |
| 500 | |
| 501 | if (!param.only_hover && use_touch_down_up) { |
| 502 | ret &= control_unit_->touch_down(param.contact, begin.x, begin.y, param.pressure); |
| 503 | } |
| 504 | |
| 505 | for (size_t i = 0; i < param.end.size(); ++i) { |
| 506 | const cv::Point& end = preproc_touch_point(param.end.at(i)); |
| 507 | const uint duration = param.duration.empty() ? 200 : (i < param.duration.size()) ? param.duration.at(i) : param.duration.back(); |
| 508 | const uint end_hold = param.end_hold.empty() ? 0 : (i < param.end_hold.size()) ? param.end_hold.at(i) : param.end_hold.back(); |
| 509 | |
| 510 | if (use_touch_down_up) { |
| 511 | constexpr double kInterval = 10; // ms |
| 512 | const std::chrono::milliseconds delay(static_cast<int>(kInterval)); |
| 513 | |
| 514 | const double total_step = duration / kInterval; |
| 515 | const double x_step_len = (end.x - begin.x) / total_step; |
| 516 | const double y_step_len = (end.y - begin.y) / total_step; |
| 517 | |
| 518 | auto now = std::chrono::steady_clock::now(); |
| 519 | |
| 520 | for (int step = 1; step < total_step; ++step) { |
| 521 | int mx = static_cast<int>(begin.x + step * x_step_len); |
| 522 | int my = static_cast<int>(begin.y + step * y_step_len); |
| 523 | |
| 524 | std::this_thread::sleep_until(now + delay); |
| 525 | |
| 526 | now = std::chrono::steady_clock::now(); |
| 527 | ret &= control_unit_->touch_move(param.contact, mx, my, param.pressure); |
| 528 | } |
| 529 | |
| 530 | std::this_thread::sleep_until(now + delay); |
| 531 | |
| 532 | now = std::chrono::steady_clock::now(); |
| 533 | ret &= control_unit_->touch_move(param.contact, end.x, end.y, param.pressure); |
| 534 | |
| 535 | std::this_thread::sleep_until(now + delay); |
| 536 | } |
| 537 | else { |
| 538 | ret &= control_unit_->swipe(begin.x, begin.y, end.x, end.y, duration); |
| 539 | } |
| 540 | |
| 541 | std::this_thread::sleep_for(std::chrono::milliseconds(end_hold)); |
| 542 | |
| 543 | begin = end; |
nothing calls this directly
no test coverage detected