Magpie #12
|
@ -4,8 +4,6 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
canary = { path = "../../" }
|
||||
glium = "0.32"
|
||||
magpie-client = { path = "../../crates/magpie-client" }
|
||||
mpris = "2.0.0-rc3"
|
||||
ouroboros = "^0.15"
|
||||
|
|
|
@ -1,54 +1,8 @@
|
|||
use canary::ScriptInstance;
|
||||
use glium::{glutin, Display, Surface};
|
||||
use glutin::event::{Event, WindowEvent};
|
||||
use glutin::event_loop::{ControlFlow, EventLoop};
|
||||
use magpie_client::{magpie_types, MagpieClient};
|
||||
use magpie_types::{CreatePanel, MagpieServerMsg};
|
||||
use mpris::{PlayerFinder, ProgressTracker};
|
||||
use ouroboros::self_referencing;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Vertex {
|
||||
pub position: [f32; 2],
|
||||
pub color: [u8; 4],
|
||||
}
|
||||
|
||||
glium::implement_vertex!(Vertex, position normalize(false), color normalize(true));
|
||||
|
||||
impl From<&canary::MeshVertex> for Vertex {
|
||||
fn from(v: &canary::MeshVertex) -> Self {
|
||||
let (r, g, b, a) = v.color.to_rgba_unmultiplied();
|
||||
Self {
|
||||
position: [v.position.x, v.position.y],
|
||||
color: [r, g, b, a],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const VERTEX_SHADER_SRC: &str = r#"
|
||||
#version 330
|
||||
|
||||
in vec2 position;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
frag_color = color;
|
||||
}
|
||||
"#;
|
||||
|
||||
const FRAGMENT_SHADER_SRC: &str = r#"
|
||||
#version 330
|
||||
|
||||
in vec4 frag_color;
|
||||
|
||||
out vec4 fb_color;
|
||||
|
||||
void main() {
|
||||
fb_color = frag_color;
|
||||
}
|
||||
"#;
|
||||
|
||||
#[self_referencing]
|
||||
pub struct Player {
|
||||
player: mpris::Player,
|
||||
|
@ -60,6 +14,7 @@ pub struct Player {
|
|||
|
||||
impl Player {
|
||||
pub fn from_player(player: mpris::Player) -> Self {
|
||||
println!("Connected to {}", player.identity());
|
||||
PlayerBuilder {
|
||||
player,
|
||||
tracker_builder: |player| player.track_progress(100).unwrap(),
|
||||
|
@ -72,10 +27,14 @@ impl Player {
|
|||
let tick = tracker.tick();
|
||||
|
||||
if tick.progress_changed {
|
||||
let p = tick.progress;
|
||||
println!(
|
||||
"{:?}/{:?}",
|
||||
tick.progress.position(),
|
||||
tick.progress.length()
|
||||
"({:?}/{:?}) {:?} - {:?} - {:?}",
|
||||
p.position(),
|
||||
p.length(),
|
||||
p.metadata().artists(),
|
||||
p.metadata().album_name(),
|
||||
p.metadata().title(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -88,109 +47,6 @@ impl Player {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
display: Display,
|
||||
program: glium::Program,
|
||||
player_finder: PlayerFinder,
|
||||
player: Option<Player>,
|
||||
script: canary::WasmtimeScript<canary::ScriptAbiImpl>,
|
||||
panel: canary::PanelId,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(module_path: &str, display: Display) -> Self {
|
||||
let program =
|
||||
glium::Program::from_source(&display, VERTEX_SHADER_SRC, FRAGMENT_SHADER_SRC, None)
|
||||
.unwrap();
|
||||
|
||||
let runtime = canary::WasmtimeRuntime::new().unwrap();
|
||||
let abi = Default::default();
|
||||
let module = std::fs::read(module_path).unwrap();
|
||||
let mut script = runtime.load_module(abi, &module).unwrap();
|
||||
let panel = script.bind_panel(vec![]);
|
||||
|
||||
Self {
|
||||
display,
|
||||
program,
|
||||
player_finder: PlayerFinder::new().expect("Could not connect to D-Bus"),
|
||||
player: None,
|
||||
script,
|
||||
panel,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
self.display.gl_window().window().request_redraw();
|
||||
|
||||
/*let disconnected = if let Some(player) = self.player.as_mut() {
|
||||
player.tick()
|
||||
} else {
|
||||
match self.player_finder.find_active() {
|
||||
Ok(player) => {
|
||||
println!("Connected to MPRIS");
|
||||
self.player = Some(Player::from_player(player));
|
||||
}
|
||||
Err(e) => eprintln!("PlayerFinder: {:?}", e),
|
||||
}
|
||||
|
||||
false
|
||||
};
|
||||
|
||||
if disconnected {
|
||||
println!("Disconnected from MPRIS");
|
||||
self.player = None;
|
||||
}*/
|
||||
|
||||
self.script.update(self.panel, 0.01667);
|
||||
}
|
||||
|
||||
pub fn draw(&mut self) {
|
||||
let mut target = self.display.draw();
|
||||
target.clear_color(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
self.script.draw(self.panel, |commands| {
|
||||
let mut joined_vs: Vec<Vertex> = Vec::new();
|
||||
let mut joined_is = Vec::new();
|
||||
|
||||
for command in commands.iter() {
|
||||
match command {
|
||||
canary::DrawCommand::Mesh { vertices, indices } => {
|
||||
let voff = joined_vs.len() as canary::MeshIndex;
|
||||
joined_vs.extend(vertices.iter().map(Vertex::from));
|
||||
joined_is.extend(indices.iter().map(|i| i + voff));
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
let vertex_buffer = glium::VertexBuffer::new(&self.display, &joined_vs).unwrap();
|
||||
let index_buffer = glium::IndexBuffer::new(
|
||||
&self.display,
|
||||
glium::index::PrimitiveType::TrianglesList,
|
||||
&joined_is,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let params = glium::DrawParameters {
|
||||
blend: glium::Blend::alpha_blending(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
target
|
||||
.draw(
|
||||
&vertex_buffer,
|
||||
&index_buffer,
|
||||
&self.program,
|
||||
&glium::uniforms::EmptyUniforms,
|
||||
¶ms,
|
||||
)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
target.finish().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let module_path = args
|
||||
|
@ -198,30 +54,29 @@ fn main() {
|
|||
.expect("Please pass a path to a Canary script!")
|
||||
.to_owned();
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let wb = glutin::window::WindowBuilder::new();
|
||||
let cb = glutin::ContextBuilder::new();
|
||||
let display = glium::Display::new(wb, cb, &event_loop).unwrap();
|
||||
let player_finder = PlayerFinder::new().expect("Could not connect to D-Bus");
|
||||
|
||||
let mut app = App::new(&module_path, display);
|
||||
let mut magpie = MagpieClient::new().unwrap();
|
||||
let script = std::path::PathBuf::from(&module_path);
|
||||
let msg = CreatePanel { id: 0, script };
|
||||
let msg = MagpieServerMsg::CreatePanel(msg);
|
||||
magpie.messenger.send(&msg).unwrap();
|
||||
|
||||
event_loop.run(move |ev, _, control_flow| {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
match ev {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
return;
|
||||
}
|
||||
_ => return,
|
||||
},
|
||||
Event::MainEventsCleared => {
|
||||
app.update();
|
||||
loop {
|
||||
println!("Connecting to MRPIS...");
|
||||
|
||||
let mut player = match player_finder.find_active() {
|
||||
Ok(player) => Player::from_player(player),
|
||||
Err(err) => {
|
||||
eprintln!("Couldn't find player: {:?}", err);
|
||||
let wait = std::time::Duration::from_secs(1);
|
||||
std::thread::sleep(wait);
|
||||
continue;
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
app.draw();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
while !player.tick() {}
|
||||
|
||||
println!("Disconnected from MPRIS");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue