55375b1406
Project CI / AI game creator shell Rust crates (push) Successful in 1m18s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m30s
Project CI / Backend tests (push) Successful in 3m58s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 10m12s
Project CI / Native shell tests (push) Successful in 5m49s
Project CI / Frontend tests (push) Successful in 2m18s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m50s
Project CI / AI game creator shell web tests (push) Failing after 2m11s
Project CI / Repository checks (push) Successful in 2m55s
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/509 Co-authored-by: Linghong <ink29535@proton.me> Co-committed-by: Linghong <ink29535@proton.me>
116 lines
4.7 KiB
Rust
116 lines
4.7 KiB
Rust
//! 已链接的编辑器适配器目录。
|
|
//!
|
|
//! 编辑器专属实现随 `plugins/` 工作区里的插件包分发;其中 native 适配器模块
|
|
//! 目前由宿主在编译期链接(Cargo path 依赖),再按插件 manifest 的 `adapter`
|
|
//! 字段注册到通用插件宿主。宿主只认适配器 id,不包含目标编辑器知识。
|
|
|
|
mod execution;
|
|
pub(crate) use execution::*;
|
|
|
|
// 桌面注册与 Runner 资源定位属于生产启动接入。
|
|
#[cfg(not(test))]
|
|
mod startup;
|
|
#[cfg(not(test))]
|
|
pub(crate) use startup::*;
|
|
|
|
#[cfg(test)]
|
|
use serde_json::json;
|
|
|
|
#[cfg(test)]
|
|
mod unity_receipt_tests {
|
|
use super::*;
|
|
|
|
#[cfg(all(windows, target_arch = "x86_64", feature = "unity-editor-execute"))]
|
|
#[test]
|
|
fn unity_delivery_ack_distinguishes_busy_disabled_and_known_pre_dispatch_failure() {
|
|
let _guard = crate::builtin_plugins::test_lock();
|
|
let config = tempfile::tempdir().unwrap();
|
|
let project = tempfile::tempdir().unwrap();
|
|
for directory in ["Assets", "Packages", "ProjectSettings"] {
|
|
std::fs::create_dir(project.path().join(directory)).unwrap();
|
|
}
|
|
std::fs::write(
|
|
project.path().join("ProjectSettings/ProjectVersion.txt"),
|
|
"m_EditorVersion: 6000.0.1f1",
|
|
)
|
|
.unwrap();
|
|
let previous_config = crate::game_creator_runtime_config_dir_lock()
|
|
.lock()
|
|
.unwrap()
|
|
.clone();
|
|
*crate::game_creator_runtime_config_dir_lock()
|
|
.lock()
|
|
.unwrap() = Some(config.path().to_path_buf());
|
|
crate::builtin_plugins::initialize(config.path()).unwrap();
|
|
let params = json!({"projectPath":project.path().to_string_lossy(),"code":"return 2;"});
|
|
{
|
|
let _busy = unity_pending_delivery().lock().unwrap();
|
|
let result = managed_editor_rpc_owned(
|
|
ManagedEditor::Unity,
|
|
"execute",
|
|
params.clone(),
|
|
Some("busy-request"),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(result["status"], "failed");
|
|
assert_eq!(result["dispatched"], false);
|
|
assert!(!unity_delivery_requires_ack("busy-request"));
|
|
}
|
|
crate::builtin_plugins::set_enabled(
|
|
crate::builtin_plugins::AGC_UNITY_EDITOR_PLUGIN_ID,
|
|
false,
|
|
)
|
|
.unwrap();
|
|
assert!(managed_editor_rpc_owned(
|
|
ManagedEditor::Unity,
|
|
"execute",
|
|
params.clone(),
|
|
Some("disabled-request")
|
|
)
|
|
.is_err());
|
|
assert!(!unity_delivery_requires_ack("disabled-request"));
|
|
crate::builtin_plugins::set_enabled(
|
|
crate::builtin_plugins::AGC_UNITY_EDITOR_PLUGIN_ID,
|
|
true,
|
|
)
|
|
.unwrap();
|
|
// 空代码在 native 发送前失败,但本次 Runner delivery 已建 fence,仍须确认回执。
|
|
let result = managed_editor_rpc_owned(
|
|
ManagedEditor::Unity,
|
|
"execute",
|
|
json!({"projectPath":project.path().to_string_lossy(),"code":""}),
|
|
Some("known-failure"),
|
|
)
|
|
.unwrap();
|
|
assert_eq!(result["status"], "failed");
|
|
assert_eq!(result["dispatched"], false);
|
|
assert_eq!(result["ackRequired"], true);
|
|
assert!(unity_delivery_requires_ack("known-failure"));
|
|
assert!(acknowledge_editor_delivery(ManagedEditor::Unity, "wrong-id").is_err());
|
|
assert!(editor_execution_fence_path(ManagedEditor::Unity, config.path()).exists());
|
|
acknowledge_editor_delivery(ManagedEditor::Unity, "known-failure").unwrap();
|
|
assert!(!editor_execution_fence_path(ManagedEditor::Unity, config.path()).exists());
|
|
*crate::game_creator_runtime_config_dir_lock()
|
|
.lock()
|
|
.unwrap() = previous_config;
|
|
}
|
|
|
|
#[test]
|
|
fn unity_ack_requires_complete_consistent_execution_receipt() {
|
|
assert!(editor_execute_receipt_is_valid(
|
|
&json!({"status":"completed","ok":true,"dispatched":true,"retryAllowed":false,"result":null})
|
|
));
|
|
assert!(editor_execute_receipt_is_valid(
|
|
&json!({"status":"failed","ok":false,"dispatched":false,"retryAllowed":false,"error":{"code":"missing-helper","message":"no helper"}})
|
|
));
|
|
for value in [
|
|
json!({"status":"completed","ok":true}),
|
|
json!({"status":"completed","ok":false,"dispatched":true,"retryAllowed":false,"result":1}),
|
|
json!({"status":"failed","ok":false,"dispatched":true,"retryAllowed":false}),
|
|
json!({"status":"needs-reconciliation","ok":false,"dispatched":false,"retryAllowed":false,"error":"lost"}),
|
|
] {
|
|
assert!(!editor_execute_receipt_is_valid(&value));
|
|
}
|
|
}
|
|
}
|