Skip to content

Commit

Permalink
dev: rewrite format/user_action actors as tasks (#386)
Browse files Browse the repository at this point in the history
* dev: rewrite format/user_action actors as tasks

* dev: clean some dirty code
  • Loading branch information
Myriad-Dreamin authored Jul 9, 2024
1 parent 675ac1b commit 7bcd4c6
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 205 deletions.
103 changes: 0 additions & 103 deletions crates/tinymist/src/actor/format.rs

This file was deleted.

32 changes: 0 additions & 32 deletions crates/tinymist/src/actor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
//! Bootstrap actors for Tinymist.
pub mod editor;
pub mod format;
#[cfg(feature = "preview")]
pub mod preview;
pub mod typ_client;
pub mod typ_server;
pub mod user_action;

use std::sync::Arc;

Expand All @@ -18,10 +16,8 @@ use typst_ts_compiler::vfs::notify::{FileChangeSet, MemoryEvent};
use typst_ts_core::config::compiler::EntryState;

use self::{
format::run_format_thread,
typ_client::{CompileClientActor, CompileHandler},
typ_server::CompileServerActor,
user_action::run_user_action_thread,
};
use crate::{
task::{ExportConfig, ExportTask, ExportTaskConf},
Expand Down Expand Up @@ -113,32 +109,4 @@ impl LanguageState {
client.add_memory_changes(MemoryEvent::Update(snapshot));
client
}
pub fn run_format_thread(&mut self) {
if self.format_thread.is_some() {
log::error!("formatting thread is already started");
return;
}

let (tx_req, rx_req) = crossbeam_channel::unbounded();
self.format_thread = Some(tx_req);

let client = self.client.clone().to_untyped();
let mode = self.config.formatter;
let enc = self.const_config.position_encoding;
let config = format::FormatConfig { mode, width: 120 };
std::thread::spawn(move || run_format_thread(config, rx_req, client, enc));
}

pub fn run_user_action_thread(&mut self) {
if self.user_action_thread.is_some() {
log::error!("user action threads are already started");
return;
}

let (tx_req, rx_req) = crossbeam_channel::unbounded();
self.user_action_thread = Some(tx_req);

let client = self.client.clone().to_untyped();
std::thread::spawn(move || run_user_action_thread(rx_req, client));
}
}
17 changes: 5 additions & 12 deletions crates/tinymist/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use lsp_server::RequestId;
use lsp_types::*;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use task::TraceParams;
use tinymist_assets::TYPST_PREVIEW_HTML;
use tinymist_query::{ExportKind, PageSelection};
use typst::diag::StrResult;
Expand All @@ -15,7 +16,6 @@ use typst_ts_core::error::prelude::*;

use super::server::*;
use super::*;
use crate::actor::user_action::{TraceParams, UserActionRequest};
use crate::tool::package::InitTask;

#[derive(Debug, Clone, Default, Deserialize)]
Expand Down Expand Up @@ -282,7 +282,6 @@ impl LanguageState {
let self_path = std::env::current_exe()
.map_err(|e| internal_error(format!("Cannot get typst compiler {e}")))?;

let thread = self.user_action_thread.clone();
let entry = self.config.compile.determine_entry(Some(path));

let snap = self.primary().sync_snapshot().map_err(z_internal_error)?;
Expand All @@ -300,22 +299,16 @@ impl LanguageState {
)
.map_err(z_internal_error)?;

let Some(f) = thread else {
return Err(internal_error("user action thread is not available"))?;
};

f.send(UserActionRequest::Trace(
self.client.schedule(
req_id,
TraceParams {
self.user_action.trace(TraceParams {
compiler_program: self_path,
root: root.as_ref().to_owned(),
main,
inputs: snap.world.inputs().as_ref().deref().clone(),
font_paths: snap.world.font_resolver.font_paths().to_owned(),
},
))
.map_err(|_| internal_error("cannot send trace request"))
.map(Some)
}),
)
}

/// Get the metrics of the document.
Expand Down
59 changes: 25 additions & 34 deletions crates/tinymist/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::sync::Arc;

use actor::editor::EditorActor;
use anyhow::anyhow;
use anyhow::{bail, Context};
use anyhow::Context;
use futures::future::BoxFuture;
use log::{error, info, trace};
use lsp_server::RequestId;
Expand All @@ -16,7 +16,7 @@ use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value as JsonValue};
use sync_lsp::*;
use task::ExportConfig;
use task::{ExportConfig, FormatConfig, FormatTask, UserActionTask};
use tinymist_query::{
get_semantic_tokens_options, get_semantic_tokens_registration,
get_semantic_tokens_unregistration, PageSelection, SemanticTokenContext,
Expand All @@ -36,9 +36,7 @@ use typst_ts_core::{error::prelude::*, Bytes, Error, ImmutPath};

use super::{init::*, *};
use crate::actor::editor::EditorRequest;
use crate::actor::format::{FormatConfig, FormatRequest};
use crate::actor::typ_client::CompileClientActor;
use crate::actor::user_action::UserActionRequest;

pub type MaySyncResult<'a> = Result<JsonValue, BoxFuture<'a, JsonValue>>;

Expand Down Expand Up @@ -94,12 +92,12 @@ pub struct LanguageState {
pub primary: Option<CompileClientActor>,
/// The compiler actors for tasks
// pub dedicates: Vec<CompileClientActor>,
/// The formatter thread running in backend.
/// Note: The thread will exit if you drop the sender.
pub format_thread: Option<crossbeam_channel::Sender<FormatRequest>>,
/// The user action thread running in backend.
/// Note: The thread will exit if you drop the sender.
pub user_action_thread: Option<crossbeam_channel::Sender<UserActionRequest>>,
/// The formatter tasks running in backend, which will be scheduled by async
/// runtime.
pub formatter: FormatTask,
/// The user action tasks running in backend, which will be scheduled by
/// async runtime.
pub user_action: UserActionTask,
}

/// Getters and the main loop.
Expand All @@ -116,6 +114,11 @@ impl LanguageState {
const_config.tokens_overlapping_token_support,
const_config.tokens_multiline_token_support,
);
let formatter = FormatTask::new(FormatConfig {
mode: config.formatter,
width: config.formatter_print_width,
position_encoding: const_config.position_encoding,
});

Self {
client: client.clone(),
Expand All @@ -134,8 +137,8 @@ impl LanguageState {
pinning: false,
focusing: None,
tokens_ctx,
format_thread: None,
user_action_thread: None,
formatter,
user_action: Default::default(),
}
}

Expand All @@ -154,9 +157,6 @@ impl LanguageState {
let mut service = LanguageState::new(client.clone(), config, cc.clone(), editor_tx);

if start {
service.run_format_thread();
service.run_user_action_thread();

let editor_actor = EditorActor::new(
client.clone().to_untyped(),
editor_rx,
Expand Down Expand Up @@ -535,15 +535,12 @@ impl LanguageState {
if let Err(err) = err {
error!("could not change formatter config: {err}");
}
if let Some(f) = &self.format_thread {
let err = f.send(FormatRequest::ChangeConfig(FormatConfig {
mode: self.config.formatter,
width: self.config.formatter_print_width,
}));
if let Err(err) = err {
error!("could not change formatter config: {err}");
}
}

self.formatter.change_config(FormatConfig {
mode: self.config.formatter,
width: self.config.formatter_print_width,
position_encoding: self.const_config.position_encoding,
});
}

info!("new settings applied");
Expand Down Expand Up @@ -680,16 +677,10 @@ impl LanguageState {
}

let path: ImmutPath = as_path(params.text_document).as_path().into();
self.query_source(path, |source: typst::syntax::Source| {
if let Some(f) = &self.format_thread {
f.send(FormatRequest::Format(req_id, source.clone()))?;
} else {
bail!("formatter thread is not available");
}

Ok(Some(()))
})
.map_err(|e| internal_error(format!("could not format document: {e}")))
let source = self
.query_source(path, |source: typst::syntax::Source| Ok(source))
.map_err(|e| internal_error(format!("could not format document: {e}")))?;
self.client.schedule(req_id, self.formatter.exec(source))
}

fn inlay_hint(&mut self, req_id: RequestId, params: InlayHintParams) -> ScheduledResult {
Expand Down
Loading

0 comments on commit 7bcd4c6

Please sign in to comment.