Mountain/Vine/Server/Notification/
SetTextEditorDecorations.rs1
2use std::sync::OnceLock;
24
25use serde_json::Value;
26use tauri::{AppHandle, Emitter};
27use tokio::sync::mpsc::{UnboundedSender, unbounded_channel};
28
29use crate::{Vine::Server::MountainVinegRPCService::MountainVinegRPCService, dev_log};
30
31struct DecoSetItem {
32 Handle:AppHandle,
33
34 Payload:Value,
35}
36
37struct DecoSetChannel {
38 Sender:UnboundedSender<DecoSetItem>,
39}
40
41static DECO_SET_CH:OnceLock<DecoSetChannel> = OnceLock::new();
42
43fn GetOrInitChannel(Handle:&AppHandle) -> &'static DecoSetChannel {
44 DECO_SET_CH.get_or_init(|| {
45 let (Tx, mut Rx) = unbounded_channel::<DecoSetItem>();
46
47 tokio::spawn(async move {
48 let mut Buf:Vec<DecoSetItem> = Vec::with_capacity(64);
49
50 loop {
51 match Rx.recv().await {
52 None => break,
53 Some(Item) => Buf.push(Item),
54 }
55
56 Rx.recv_many(&mut Buf, 4096).await;
58 tokio::time::sleep(std::time::Duration::from_millis(16)).await;
59 Rx.recv_many(&mut Buf, 4096).await;
60
61 if Buf.is_empty() {
62 continue;
63 }
64
65 let Handle = Buf[0].Handle.clone();
67 let Batch:Vec<Value> = Buf.drain(..).map(|I| I.Payload).collect();
68
69 match Handle.emit("sky://decoration/set-ranges", serde_json::json!({ "batch": Batch })) {
70 Ok(()) => dev_log!("sky-emit", "[DecoSet] emitted batch={}", Batch.len()),
71 Err(E) => dev_log!("sky-emit", "[DecoSet] emit failed: {}", E),
72 }
73 }
74 });
75
76 DecoSetChannel { Sender:Tx }
77 })
78}
79
80pub async fn SetTextEditorDecorations(Service:&MountainVinegRPCService, Parameter:&Value) {
81 let Ch = GetOrInitChannel(Service.ApplicationHandle());
82
83 let _ = Ch
84 .Sender
85 .send(DecoSetItem { Handle:Service.ApplicationHandle().clone(), Payload:Parameter.clone() });
86}