DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/Vine/Server/Notification/
RegisterCommand.rs1#![allow(non_snake_case)]
2
3use std::sync::OnceLock;
22
23use serde_json::{Value, json};
24use tauri::{AppHandle, Emitter};
25use tokio::sync::mpsc::{UnboundedSender, unbounded_channel};
26
27use crate::{
28 Environment::CommandProvider::CommandHandler,
29 Vine::Server::MountainVinegRPCService::MountainVinegRPCService,
30 dev_log,
31};
32
33struct CommandBatchChannel {
34 Sender:UnboundedSender<(AppHandle, Value)>,
35}
36
37static CMD_CHANNEL:OnceLock<CommandBatchChannel> = OnceLock::new();
38
39fn GetOrInitChannel(Handle:&AppHandle) -> &'static CommandBatchChannel {
40 CMD_CHANNEL.get_or_init(|| {
41 let (Tx, mut Rx) = unbounded_channel::<(AppHandle, Value)>();
42
43 tokio::spawn(async move {
44 let mut Buf:Vec<(AppHandle, Value)> = Vec::with_capacity(128);
45
46 loop {
47 match Rx.recv().await {
49 None => break,
50 Some(First) => Buf.push(First),
51 }
52
53 Rx.recv_many(&mut Buf, 4096).await;
55
56 tokio::time::sleep(std::time::Duration::from_millis(16)).await;
58
59 Rx.recv_many(&mut Buf, 4096).await;
61
62 if Buf.is_empty() {
63 continue;
64 }
65
66 let Handle = Buf[0].0.clone();
68
69 let Commands:Vec<Value> = Buf.drain(..).map(|(_, V)| V).collect();
70
71 let Count = Commands.len();
72
73 match Handle.emit("sky://command/register", json!({ "commands": Commands })) {
74 Ok(()) => {
75 dev_log!("sky-emit", "[SkyEmit] ok channel=sky://command/register batch={}", Count);
76
77 dev_log!("commands", "[RegisterCommand] batch={}", Count);
85 },
86 Err(E) => {
87 dev_log!(
88 "sky-emit",
89 "[SkyEmit] fail channel=sky://command/register batch={} error={}",
90 Count,
91 E
92 );
93 },
94 }
95 }
96 });
97
98 CommandBatchChannel { Sender:Tx }
99 })
100}
101
102pub async fn RegisterCommand(Service:&MountainVinegRPCService, Parameter:&Value) {
103 let CommandId = Parameter.get("commandId").and_then(Value::as_str).unwrap_or("");
104
105 dev_log!(
106 "command-register",
107 "[MountainVinegRPCService] Cocoon registered command: {}",
108 CommandId
109 );
110
111 if CommandId.is_empty() {
112 return;
113 }
114
115 let Kind = Parameter.get("kind").and_then(Value::as_str).unwrap_or("command").to_string();
116
117 if let Ok(mut Registry) = Service
118 .RunTime()
119 .Environment
120 .ApplicationState
121 .Extension
122 .Registry
123 .CommandRegistry
124 .lock()
125 {
126 Registry.insert(
127 CommandId.to_string(),
128 CommandHandler::Proxied {
129 SideCarIdentifier:"cocoon-main".to_string(),
130 CommandIdentifier:CommandId.to_string(),
131 },
132 );
133 }
134
135 let Ch = GetOrInitChannel(Service.ApplicationHandle());
136
137 let _ = Ch.Sender.send((
138 Service.ApplicationHandle().clone(),
139 json!({ "id": CommandId, "commandId": CommandId, "kind": Kind }),
140 ));
141}