fix(orders): bind replace on owned script queues

OwnedOrderQueue documented append/replace/interrupt but only append was
exposed, so examples/commandery-rts threw on right-click move. Bind the
remaining CommandQueue mutations on the owned proxy and cover replace
from script.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
This commit is contained in:
Cursor Agentand西风逍遥游 committed 2026-09-02 10:40:58 +00:00
1 parent 768e5aee4c
commit 09618f4d01
2 files changed
+80

No files matched your search

+55
View File
@@ -766,6 +766,61 @@ void Orders::expose(ssq::Table& table) {
return eve::script::projectResult(vm, queueView->append(kind, priority, timeout),
[](std::string&& id) { return eve::Value(std::move(id)); });
});
ownedQueue.addFunc("replace", [vm](ScriptCommandQueue* value, const std::string& kind, int priority, float timeout) {
if (!value)
return eve::script::projectResult(
vm,
orderFailure<std::string>(eve::DiagnosticCode::InvalidArgument,
"owned order queue proxy must not be null", "queue"),
[](std::string&& id) { return eve::Value(std::move(id)); });
auto queueView = Orders::resolve(value->reference);
if (!queueView.isBound())
return eve::script::projectResult(vm,
orderFailure<std::string>(eve::DiagnosticCode::StaleHandle,
"owned order queue handle is stale", "queue"),
[](std::string&& id) { return eve::Value(std::move(id)); });
return eve::script::projectResult(vm, queueView->replace(kind, priority, timeout),
[](std::string&& id) { return eve::Value(std::move(id)); });
});
ownedQueue.addFunc("interrupt", [vm](ScriptCommandQueue* value, const std::string& kind, int priority,
float timeout) {
if (!value)
return eve::script::projectResult(
vm,
orderFailure<std::string>(eve::DiagnosticCode::InvalidArgument,
"owned order queue proxy must not be null", "queue"),
[](std::string&& id) { return eve::Value(std::move(id)); });
auto queueView = Orders::resolve(value->reference);
if (!queueView.isBound())
return eve::script::projectResult(vm,
orderFailure<std::string>(eve::DiagnosticCode::StaleHandle,
"owned order queue handle is stale", "queue"),
[](std::string&& id) { return eve::Value(std::move(id)); });
return eve::script::projectResult(vm, queueView->interrupt(kind, priority, timeout),
[](std::string&& id) { return eve::Value(std::move(id)); });
});
ownedQueue.addFunc("fail", [vm](ScriptCommandQueue* value, const std::string& id, const std::string& reason) {
if (!value)
return eve::script::projectResult(
vm, orderFailure<void>(eve::DiagnosticCode::InvalidArgument, "owned order queue proxy must not be null",
"queue"));
auto queueView = Orders::resolve(value->reference);
if (!queueView.isBound())
return eve::script::projectResult(
vm, orderFailure<void>(eve::DiagnosticCode::StaleHandle, "owned order queue handle is stale", "queue"));
return eve::script::projectResult(vm, queueView->fail(id, reason));
});
ownedQueue.addFunc("cancel", [vm](ScriptCommandQueue* value, const std::string& id, const std::string& reason) {
if (!value)
return eve::script::projectResult(
vm, orderFailure<void>(eve::DiagnosticCode::InvalidArgument, "owned order queue proxy must not be null",
"queue"));
auto queueView = Orders::resolve(value->reference);
if (!queueView.isBound())
return eve::script::projectResult(
vm, orderFailure<void>(eve::DiagnosticCode::StaleHandle, "owned order queue handle is stale", "queue"));
return eve::script::projectResult(vm, queueView->cancel(id, reason));
});
ownedQueue.addFunc("current", [](ScriptCommandQueue* value) -> Order* {
if (!value) return nullptr;
auto queueView = Orders::resolve(value->reference);
+25
View File
@@ -185,3 +185,28 @@ TEST_CASE("orders.script.queueAndPayloadApi") {
)"));
CHECK_EQ(vm.find("result").toString(), std::string("completed"));
}
TEST_CASE("orders.script.ownedQueueReplace") {
ssq::VM vm(1024, ssq::Libs::ALL);
eve::ModuleManager::expose(vm);
vm.run(vm.compileSource(R"(
result <- "fail";
local module = eve.Orders();
local queueResult = module.newQueueOwned();
if (!queueResult.ok) throw queueResult.status.summary;
local queue = queueResult.value;
local first = queue.append("move", 1, 0.0);
if (!first.ok) throw first.status.summary;
local replaced = queue.replace("move", 10, 0.0);
if (!replaced.ok) throw replaced.status.summary;
local order = queue.current();
if (order != null && order.getId() == replaced.value && order.getKind() == "move" &&
order.getState() == "active") {
order.getPayload().setNumber("x", 400.0);
order.getPayload().setNumber("y", 360.0);
if (order.getPayload().has("x") && order.getPayload().has("y"))
result = "replaced";
}
)"));
CHECK_EQ(vm.find("result").toString(), std::string("replaced"));
}