[feat] acknowledge remote input and wait for visual changes

This commit is contained in:
dijunkun
2026-11-06 20:12:41 +08:00
parent a49eb7ad5b
commit 0eab020c38
15 changed files with 285 additions and 11 deletions
@@ -0,0 +1,56 @@
#include "controller_session.h"
#include <stream_names.h>
namespace crossdesk {
using nlohmann::json;
uint64_t ControllerSession::RequestRemote(const std::string &method, json arguments) {
if (!Connected() || remote_results_.size() >= 512) return 0;
const auto id = ++remote_sequence_;
remote_results_[id] = nullptr;
const auto message = json{{"type", "automation"}, {"version", 1},
{"id", id}, {"method", method}, {"arguments", std::move(arguments)}}.dump();
if (!Send(kControlStream, message)) {
remote_results_.erase(id);
return 0;
}
return id;
}
std::optional<json> ControllerSession::TakeRemoteResult(uint64_t request) {
const auto found = remote_results_.find(request);
if (found == remote_results_.end() || found->second.is_null()) return {};
auto result = std::move(found->second);
remote_results_.erase(found);
return result;
}
void ControllerSession::BeginInput() {
for (const auto id : input_requests_) remote_results_.erase(id);
input_requests_.clear();
input_result_ = "applied";
input_ack_active_ = InputAcknowledged();
}
bool ControllerSession::SendInput(const char *stream, const RemoteAction &action) {
if (!input_ack_active_) return Send(stream, action.to_json());
const auto id = RequestRemote("input", json::parse(action.to_json()));
if (!id) return false;
input_requests_.push_back(id);
return true;
}
std::string ControllerSession::InputResult() {
if (!input_ack_active_) return "unsupported";
for (auto it = input_requests_.begin(); it != input_requests_.end();) {
auto reply = TakeRemoteResult(*it);
if (!reply) { ++it; continue; }
const auto result = reply->value("result", json{});
if (reply->value("ok", json{}) != true || !result.is_object() ||
result.value("state", json{}) != "applied")
input_result_ = "failed";
it = input_requests_.erase(it);
}
return input_requests_.empty() ? input_result_ : "pending";
}
} // namespace crossdesk