Skip to content

Commit

Permalink
Preview window: added render lag
Browse files Browse the repository at this point in the history
  • Loading branch information
Levitanus committed Feb 15, 2023
1 parent 2a48aed commit bc93a9f
Showing 1 changed file with 89 additions and 43 deletions.
132 changes: 89 additions & 43 deletions plugin/src/preview_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ use std::{
path::PathBuf,
sync::mpsc::{channel, Receiver},
thread,
time::Instant,
};

use rea_rs::{ExtState, Measure, PluginContext, Position, Reaper, Timer};
use rea_score::lilypond_render::{preview_string, RendersToLilypond};
use rea_rs::{
ExtState, Measure, PluginContext, Position, Reaper, Timer,
};
use rea_score::lilypond_render::{
preview_string, RendersToLilypond,
};
use reaper_imgui::{
Context, ContextFlags, Dock, ImGui, ImageHandle, SetWidth, Size,
};
Expand All @@ -20,6 +25,7 @@ struct State {
dpi: u32,
dock: Dock,
preview_bars_amount: u32,
render_lag: u32,
}

pub struct PreviewWindow {
Expand All @@ -33,20 +39,27 @@ pub struct PreviewWindow {
next_dock: Dock,
hash: String,
cursor_pos: Position,
last_render: Instant,
ready_for_render: bool,
}
impl PreviewWindow {
pub fn init(context: PluginContext, temp_path: impl Into<PathBuf>) {
pub fn init(
context: PluginContext,
temp_path: impl Into<PathBuf>,
) {
let imgui = ImGui::load(context);
let mut ctx = imgui
.create_context("ReaScore preview")
.with_flags(ContextFlags::DockingEnable);
let temp_path = temp_path.into().join("rea_score_preview.png");
let temp_path =
temp_path.into().join("rea_score_preview.png");
let image = ctx.image_handle(temp_path);
let state = State {
code: String::from("c'"),
dpi: 80,
dock: Dock::Reaper(3),
preview_bars_amount: 4,
render_lag: 500,
};
let state = ExtState::new(
"ReaScore",
Expand All @@ -55,8 +68,10 @@ impl PreviewWindow {
true,
Reaper::get(),
);
let next_dock =
state.get().expect("can not load Preview Window state").dock;
let next_dock = state
.get()
.expect("can not load Preview Window state")
.dock;
Reaper::get_mut().register_timer(Box::new(Self {
ctx,
_imgui: imgui,
Expand All @@ -68,6 +83,8 @@ impl PreviewWindow {
next_dock,
hash: Default::default(),
cursor_pos: Default::default(),
last_render: Instant::now(),
ready_for_render: false,
}));
}
fn state(&self) -> State {
Expand All @@ -83,12 +100,18 @@ impl PreviewWindow {
let size = self.size;
let dpi = state.dpi;
thread::spawn(move || {
preview_string(text, path, (size.width, size.height), dpi)
.expect("Can not preview string");
preview_string(
text,
path,
(size.width, size.height),
dpi,
)
.expect("Can not preview string");
send.send(true)
});
}
fn check_item(&mut self) {
let now = Instant::now();
let rpr = Reaper::get();
let pr = rpr.current_project();
let cursor_pos = pr.get_cursor_position();
Expand All @@ -103,14 +126,29 @@ impl PreviewWindow {
if hash == self.hash && cursor_pos == self.cursor_pos {
return;
}
if !self.ready_for_render {
self.ready_for_render = true;
self.last_render = now;
return;
}
let render_lag = self.state().render_lag;
if now.duration_since(self.last_render).as_millis()
< render_lag as u128
{
return;
}
self.ready_for_render = false;
self.last_render = now;
self.hash = hash;
self.cursor_pos = cursor_pos;
let (start_pos, end_pos) = match self.preview_bounds(rpr, &pr) {
Ok(value) => value,
Err(value) => return value,
};
let code =
rea_score::dom::parse_track_in_bounds(track, start_pos, end_pos);
let (start_pos, end_pos) =
match self.preview_bounds(rpr, &pr) {
Ok(value) => value,
Err(value) => return value,
};
let code = rea_score::dom::parse_track_in_bounds(
track, start_pos, end_pos,
);
let code = match code {
Ok(c) => c,
Err(err) => {
Expand All @@ -120,8 +158,10 @@ impl PreviewWindow {
)
}
};
let mut state =
self.state.get().expect("can not load Preview Window state");
let mut state = self
.state
.get()
.expect("can not load Preview Window state");
let code = code.render_lilypond();
println!("Lily code:\n{code}");
state.code = code;
Expand All @@ -135,29 +175,32 @@ impl PreviewWindow {
pr: &rea_rs::Project,
) -> Result<(Position, Position), ()> {
let cursor_pos: Position = match rpr.active_midi_editor() {
Some(e) => match e.item(pr).active_take().iter_midi(None) {
Ok(mid) => match mid
.filter_note_on()
.filter(|ev| ev.selected())
.next()
{
Some(ev) => Position::from_ppq(
ev.ppq_position(),
&e.item(pr).active_take(),
),
None => pr.get_cursor_position(),
},
Err(err) => {
return Err(error_box(
"Error while rendering preview!",
err.to_string(),
))
Some(e) => {
match e.item(pr).active_take().iter_midi(None) {
Ok(mid) => match mid
.filter_note_on()
.filter(|ev| ev.selected())
.next()
{
Some(ev) => Position::from_ppq(
ev.ppq_position(),
&e.item(pr).active_take(),
),
None => pr.get_cursor_position(),
},
Err(err) => {
return Err(error_box(
"Error while rendering preview!",
err.to_string(),
))
}
}
},
}
None => pr.get_cursor_position(),
};
let bars = self.state().preview_bars_amount;
let mut start_idx = Measure::from_position(cursor_pos, pr).index;
let mut start_idx =
Measure::from_position(cursor_pos, pr).index;
if start_idx > bars / 2 {
start_idx -= bars / 2;
}
Expand All @@ -183,11 +226,8 @@ impl Timer for PreviewWindow {
self.check_item();
let mut state = self.state();
// println!("code before window:\n{}", state.code);
if !self
.ctx
.window("preview")
.dock(&self.next_dock)
.open(|ctx| {
if !self.ctx.window("preview").dock(&self.next_dock).open(
|ctx| {
let mut size = ctx.window_viewport().work_size();
if size.height > 40 {
size.height -= 40;
Expand Down Expand Up @@ -220,7 +260,13 @@ impl Timer for PreviewWindow {
self.render = true;
});

// ctx.sameline(360, None);
ctx.sameline(400, None);
ctx.int_input(
"render lag ms",
state.render_lag as i32,
)
.set_width(80)
.changed(|lag| state.render_lag = lag as u32);

let reload = match &self.reload {
None => false,
Expand All @@ -234,8 +280,8 @@ impl Timer for PreviewWindow {
.force_reload(reload)
.show();
self.state.set(state.clone());
})
{
},
) {
self.stop()
};

Expand Down

0 comments on commit bc93a9f

Please sign in to comment.