Skip to content

Instantly share code, notes, and snippets.

@hugopeixoto
Last active November 23, 2015 01:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugopeixoto/df0a97fb8d613f3e2efd to your computer and use it in GitHub Desktop.
Save hugopeixoto/df0a97fb8d613f3e2efd to your computer and use it in GitHub Desktop.
rust FRP piston mashup
extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;
extern crate carboxyl;
use std::collections::HashSet;
use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
fn main() {
// Change this to OpenGL::V2_1 if not working.
let opengl = OpenGL::V3_2;
// Create an Glutin window.
let window : Window = WindowSettings::new ("spinning-square", [ 200, 200 ])
.opengl(opengl)
.exit_on_esc(true)
.build()
.unwrap();
let mouse_cursor_sink = carboxyl::Sink::new();
let mouse_cursor_stream = mouse_cursor_sink.stream();
let press_sink = carboxyl::Sink::new();
let press_stream = press_sink.stream();
let release_sink = carboxyl::Sink::new();
let release_stream = release_sink.stream();
let click_stream = &release_stream;
let delta_time_sink = carboxyl::Sink::new();
let delta_time_stream = delta_time_sink.stream();
// Create a new game and run it.
let mut gl = GlGraphics::new (opengl);
let renderer = create_main_menu_renderer(&mouse_cursor_stream, &delta_time_stream, &press_stream, &release_stream);
for e in window.events() {
e.mouse_cursor(|x, y| { mouse_cursor_sink.send((x, y)); });
if let Some(p) = e.press_args() { press_sink.send(p); }
if let Some(r) = e.release_args() { release_sink.send(r); }
if let Some(u) = e.update_args() { delta_time_sink.send(u.dt); }
if let Some(r) = e.render_args() {
renderer(&mut gl, r.viewport());
}
}
}
fn create_main_menu_renderer(
mouse_position: &carboxyl::Stream<(f64, f64)>,
delta_time : &carboxyl::Stream<f64>,
button_pressed : &carboxyl::Stream<piston::input::Button>,
button_released : &carboxyl::Stream<piston::input::Button>
) -> Box<Fn(&mut GlGraphics, graphics::Viewport)> {
let mouse_position_state = mouse_position.hold((0.0, 0.0));
let rotation = carboxyl::Signal::cyclic(|a| a.snapshot(
&delta_time,
|p, dt| p + 2.0 * dt).hold(0.0));
let left_mouse_button_state = button_pressed.map(|b| (true, b))
.merge(&button_released.map(|b| (false, b)))
.filter(|&(state, button)| { if let Button::Mouse(mouse::MouseButton::Left) = button { true } else { false } })
.map(|(t, b)| t).hold(false);
Box::new(move |gl : &mut GlGraphics, viewport : graphics::Viewport| {
use graphics::*;
let square = rectangle::square(0.0, 0.0, 50.0);
const WHITE : [f32; 4] = [ 1.0, 1.0, 1.0, 1.0 ];
const GREEN : [f32; 4] = [ 0.0, 1.0, 0.0, 1.0 ];
const RED : [f32; 4] = [ 150.0 / 256.0, 79.0 / 256.0, 76.0 / 256.0, 1.0 ];
gl.draw(viewport, | c, gl | {
// Clear the screen.
clear(WHITE, gl);
let transform =
c.transform
.trans(mouse_position_state.sample().0, mouse_position_state.sample().1)
.rot_rad(rotation.sample())
.trans(-25.0, -25.0);
// Draw a box rotating around the middle of the screen.
if left_mouse_button_state.sample() {
rectangle(RED, square, transform, gl);
} else {
rectangle(GREEN, square, transform, gl);
}
});
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment