add separate display function for controller and add names for patterns
This commit is contained in:
parent
abdd63d446
commit
ae49876794
16 changed files with 139 additions and 37 deletions
|
@ -1,6 +1,11 @@
|
||||||
use {
|
use {
|
||||||
std::time::{Instant, Duration},
|
std::time::{Instant, Duration},
|
||||||
crate::waveform::Waveform,
|
std::sync::{Arc, RwLock},
|
||||||
|
crate::{
|
||||||
|
waveform::Waveform,
|
||||||
|
SceneLibrary,
|
||||||
|
inputs::Inputs
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Controller {
|
pub struct Controller {
|
||||||
|
@ -8,25 +13,55 @@ pub struct Controller {
|
||||||
pub transition_begin: Instant,
|
pub transition_begin: Instant,
|
||||||
pub last_tap: Instant,
|
pub last_tap: Instant,
|
||||||
|
|
||||||
pub ctrl: bool
|
pub ctrl: bool,
|
||||||
|
|
||||||
|
pub inputs: Arc<RwLock<Inputs>>,
|
||||||
|
pub library: Arc<RwLock<SceneLibrary>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controller {
|
impl Controller {
|
||||||
pub fn new() -> Self {
|
pub fn new(library: Arc<RwLock<SceneLibrary>>, inputs: Arc<RwLock<Inputs>>) -> Self {
|
||||||
Controller {
|
Controller {
|
||||||
tbegin: Instant::now(),
|
tbegin: Instant::now(),
|
||||||
transition_begin: Instant::now(),
|
transition_begin: Instant::now(),
|
||||||
last_tap: Instant::now(),
|
last_tap: Instant::now(),
|
||||||
ctrl: false
|
ctrl: false,
|
||||||
|
library,
|
||||||
|
inputs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn display(&self) {
|
||||||
|
let inputs = self.inputs.read().unwrap();
|
||||||
|
let lib = self.library.read().unwrap();
|
||||||
|
|
||||||
|
eprintln!("----------");
|
||||||
|
|
||||||
|
if inputs.active {
|
||||||
|
eprintln!("(ACTIVE)");
|
||||||
|
} else {
|
||||||
|
eprintln!("(FROZEN)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(scene) = lib.get(inputs.scene_select) {
|
||||||
|
eprintln!("current animation: {}", scene.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
for si in 0..lib.len() {
|
||||||
|
if let Some(scene) = lib.get(si) {
|
||||||
|
eprintln!("({}) {}", si, scene.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("inputs:\n {:?}", inputs);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_key(
|
pub fn handle_key(
|
||||||
&mut self,
|
&mut self,
|
||||||
event: winit::event::KeyEvent,
|
event: winit::event::KeyEvent,
|
||||||
inputs: &mut crate::inputs::Inputs,
|
|
||||||
setup: &mut crate::setup::LightingSetup
|
setup: &mut crate::setup::LightingSetup
|
||||||
) {
|
) {
|
||||||
|
let mut inputs = self.inputs.write().unwrap();
|
||||||
if event.state == winit::event::ElementState::Released {
|
if event.state == winit::event::ElementState::Released {
|
||||||
match event.logical_key {
|
match event.logical_key {
|
||||||
winit::keyboard::Key::Named(
|
winit::keyboard::Key::Named(
|
||||||
|
@ -141,10 +176,6 @@ impl Controller {
|
||||||
_=>{}
|
_=>{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("--------------");
|
|
||||||
eprintln!("updated inputs:\n {:?}", inputs);
|
|
||||||
eprintln!("--------------");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -51,13 +51,15 @@ async fn main() {
|
||||||
socket.write().unwrap().set_read_timeout(Some(std::time::Duration::from_millis(1)));
|
socket.write().unwrap().set_read_timeout(Some(std::time::Duration::from_millis(1)));
|
||||||
socket.write().unwrap().set_write_timeout(Some(std::time::Duration::from_millis(1)));
|
socket.write().unwrap().set_write_timeout(Some(std::time::Duration::from_millis(1)));
|
||||||
|
|
||||||
let mut inputs = Inputs::default();
|
let mut inputs = Arc::new(RwLock::new(Inputs::default()));
|
||||||
|
|
||||||
|
let scene_library = Arc::new(RwLock::new(SceneLibrary::new()));
|
||||||
|
|
||||||
let mut lighting_setup = LightingSetup::new(
|
let mut lighting_setup = LightingSetup::new(
|
||||||
vec![
|
vec![
|
||||||
Fixture::new_matrix(),
|
Fixture::new_matrix(),
|
||||||
// .with_driver( Box::new(MatrixTcpDriver::new("ip:port")) ),
|
// .with_driver( Box::new(MatrixTcpDriver::new("ip:port")) ),
|
||||||
|
/*
|
||||||
Fixture::new_stripe(false)
|
Fixture::new_stripe(false)
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.114:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.114:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(-0.5, 0.0)),
|
.offset(Vector2::new(-0.5, 0.0)),
|
||||||
|
@ -65,7 +67,7 @@ async fn main() {
|
||||||
Fixture::new_stripe(true)
|
Fixture::new_stripe(true)
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.113:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.113:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(-0.4, 0.0)),
|
.offset(Vector2::new(-0.4, 0.0)),
|
||||||
|
*/
|
||||||
Fixture::new_stripe(true)
|
Fixture::new_stripe(true)
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.112:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.112:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(0.4, 0.0)),
|
.offset(Vector2::new(0.4, 0.0)),
|
||||||
|
@ -75,18 +77,20 @@ async fn main() {
|
||||||
.offset(Vector2::new(0.5, 0.0))
|
.offset(Vector2::new(0.5, 0.0))
|
||||||
],
|
],
|
||||||
|
|
||||||
Box::new( SceneLibrary::new() )
|
scene_library.clone()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut controller = controller::Controller::new();
|
let mut controller = controller::Controller::new( scene_library, inputs.clone() );
|
||||||
|
|
||||||
let mut frame_count = 0;
|
let mut frame_count = 0;
|
||||||
let mut fps_sum_window = std::time::Instant::now();
|
let mut fps_sum_window = std::time::Instant::now();
|
||||||
|
{
|
||||||
lighting_setup.advance( &inputs );
|
let inputs = controller.inputs.read().unwrap();
|
||||||
for i in 0..5 {
|
lighting_setup.advance(&(*inputs) );
|
||||||
|
for i in 0 .. lighting_setup.fixtures.len() {
|
||||||
lighting_setup.sync_fixture(i);
|
lighting_setup.sync_fixture(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event_loop.run(move |event, elwt| {
|
event_loop.run(move |event, elwt| {
|
||||||
let tcur = std::time::Instant::now();
|
let tcur = std::time::Instant::now();
|
||||||
|
@ -107,12 +111,16 @@ async fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update animation
|
// update animation
|
||||||
|
let active = {
|
||||||
|
let mut inputs = inputs.write().unwrap();
|
||||||
inputs.t = tcur - controller.tbegin;
|
inputs.t = tcur - controller.tbegin;
|
||||||
inputs.transition_time = tcur - controller.transition_begin;
|
inputs.transition_time = tcur - controller.transition_begin;
|
||||||
lighting_setup.advance( &inputs );
|
lighting_setup.advance( &inputs );
|
||||||
|
inputs.active
|
||||||
|
};
|
||||||
|
|
||||||
// refresh fixture outputs
|
// refresh fixture outputs
|
||||||
if inputs.active {
|
if active {
|
||||||
// sync
|
// sync
|
||||||
let mut rbuf = [0 as u8; 8];
|
let mut rbuf = [0 as u8; 8];
|
||||||
|
|
||||||
|
@ -125,15 +133,17 @@ async fn main() {
|
||||||
if src_addr == "192.168.0.112:4210".parse().expect("parse socketaddr") {
|
if src_addr == "192.168.0.112:4210".parse().expect("parse socketaddr") {
|
||||||
lighting_setup.sync_fixture(2);
|
lighting_setup.sync_fixture(2);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if src_addr == "192.168.0.113:4210".parse().expect("parse socketaddr") {
|
if src_addr == "192.168.0.113:4210".parse().expect("parse socketaddr") {
|
||||||
lighting_setup.sync_fixture(3);
|
lighting_setup.sync_fixture(3);
|
||||||
}
|
}
|
||||||
if src_addr == "192.168.0.114:4210".parse().expect("parse socketaddr") {
|
if src_addr == "192.168.0.114:4210".parse().expect("parse socketaddr") {
|
||||||
lighting_setup.sync_fixture(4);
|
lighting_setup.sync_fixture(4);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 1 .. 5 {
|
for i in 1 .. 3 {
|
||||||
lighting_setup.update_outputs(i);
|
lighting_setup.update_outputs(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,8 +169,9 @@ async fn main() {
|
||||||
event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic }
|
event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic }
|
||||||
} => {
|
} => {
|
||||||
controller.handle_key(
|
controller.handle_key(
|
||||||
event, &mut inputs, &mut lighting_setup
|
event, &mut lighting_setup
|
||||||
);
|
);
|
||||||
|
controller.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -19,6 +19,9 @@ pub struct Alternate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for Alternate {
|
impl Animation for Alternate {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Alternate".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ use {
|
||||||
pub struct ArcticRain { pub inputs: Inputs }
|
pub struct ArcticRain { pub inputs: Inputs }
|
||||||
|
|
||||||
impl Animation for ArcticRain {
|
impl Animation for ArcticRain {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Arctic Rain".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ use {
|
||||||
pub struct Breathing { pub inputs: Inputs }
|
pub struct Breathing { pub inputs: Inputs }
|
||||||
|
|
||||||
impl Animation for Breathing {
|
impl Animation for Breathing {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Breathing".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,23 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::ColorGrid, util::get_angle}
|
crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GastelFade { pub inputs: Arc<RwLock< Inputs >> }
|
pub struct GastelFade { pub inputs:Inputs }
|
||||||
|
|
||||||
|
impl Animation for GastelFade {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Gastel Fade".into()
|
||||||
|
}
|
||||||
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
|
self.inputs = inputs.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ColorGrid for GastelFade {
|
impl ColorGrid for GastelFade {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let inputs = self.inputs.read().unwrap().clone();
|
let inputs = self.inputs.clone();
|
||||||
|
|
||||||
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
let w = (inputs.t.as_millis() as f32 / (inputs.wheel as f32*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
let w = (inputs.t.as_millis() as f32 / (inputs.wheel as f32*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
||||||
|
|
|
@ -22,6 +22,9 @@ pub struct OneShotMan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for OneShotMan {
|
impl Animation for OneShotMan {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"OneShotMan".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
self.velocity = (inputs.wheel as f32) / 16.0;
|
self.velocity = (inputs.wheel as f32) / 16.0;
|
||||||
|
|
|
@ -17,6 +17,9 @@ use {
|
||||||
pub struct PastelFade { pub inputs: Inputs }
|
pub struct PastelFade { pub inputs: Inputs }
|
||||||
|
|
||||||
impl Animation for PastelFade {
|
impl Animation for PastelFade {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Pastel Fade".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ pub struct Strobe {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for Strobe {
|
impl Animation for Strobe {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Strobe".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ use {
|
||||||
pub struct UbootPrüfstandFade { pub inputs: Inputs }
|
pub struct UbootPrüfstandFade { pub inputs: Inputs }
|
||||||
|
|
||||||
impl Animation for UbootPrüfstandFade {
|
impl Animation for UbootPrüfstandFade {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"UbootPrüstand Fade".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,9 @@ pub struct WaveFade { pub inputs: Inputs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for WaveFade {
|
impl Animation for WaveFade {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Wave Fade".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ use {
|
||||||
pub struct Wheel { pub inputs: Inputs }
|
pub struct Wheel { pub inputs: Inputs }
|
||||||
|
|
||||||
impl Animation for Wheel {
|
impl Animation for Wheel {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"Wheel".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,12 @@ pub struct SceneLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SceneLibrary {
|
impl SceneLibrary {
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.library.len()
|
||||||
|
}
|
||||||
|
pub fn get(&self, idx: usize) -> Option<&Box<dyn Animation>> {
|
||||||
|
self.library.get(idx)
|
||||||
|
}
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
SceneLibrary {
|
SceneLibrary {
|
||||||
library: vec![
|
library: vec![
|
||||||
|
@ -55,6 +61,9 @@ impl SceneLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for SceneLibrary {
|
impl Animation for SceneLibrary {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"master".into()
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.inputs = inputs.clone();
|
self.inputs = inputs.clone();
|
||||||
|
|
||||||
|
|
11
src/setup.rs
11
src/setup.rs
|
@ -13,11 +13,11 @@ pub struct LightingSetup {
|
||||||
pub fixtures: Vec<Fixture>,
|
pub fixtures: Vec<Fixture>,
|
||||||
t: Arc<RwLock<Duration>>,
|
t: Arc<RwLock<Duration>>,
|
||||||
|
|
||||||
animation: Box<dyn Animation>
|
animation: Arc<RwLock<dyn Animation>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LightingSetup {
|
impl LightingSetup {
|
||||||
pub fn new(fixtures: Vec<Fixture>, animation: Box<dyn Animation>) -> Self {
|
pub fn new(fixtures: Vec<Fixture>, animation: Arc<RwLock<dyn Animation>>) -> Self {
|
||||||
let t = Arc::new(RwLock::new(Duration::from_millis(0)));
|
let t = Arc::new(RwLock::new(Duration::from_millis(0)));
|
||||||
LightingSetup {
|
LightingSetup {
|
||||||
fixtures,
|
fixtures,
|
||||||
|
@ -28,7 +28,8 @@ impl LightingSetup {
|
||||||
|
|
||||||
pub fn update_buffers(&mut self) {
|
pub fn update_buffers(&mut self) {
|
||||||
for fixture in self.fixtures.iter_mut() {
|
for fixture in self.fixtures.iter_mut() {
|
||||||
fixture.update_buffer( self.animation.as_ref() );
|
let anim = self.animation.read().unwrap();
|
||||||
|
fixture.update_buffer( &*anim );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ impl LightingSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance(&mut self, inputs: &Inputs) {
|
pub fn advance(&mut self, inputs: &Inputs) {
|
||||||
self.animation.advance(inputs);
|
self.animation.write().unwrap().advance(inputs);
|
||||||
self.update_buffers();
|
self.update_buffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ impl LightingSetup {
|
||||||
let xf = (x as f32 - width as f32/2.0) / mindim as f32;
|
let xf = (x as f32 - width as f32/2.0) / mindim as f32;
|
||||||
let yf = -(y as f32 - height as f32/2.0) / mindim as f32;
|
let yf = -(y as f32 - height as f32/2.0) / mindim as f32;
|
||||||
|
|
||||||
let color = self.animation.get(&Vector2::new(xf, yf));
|
let color = self.animation.read().unwrap().get(&Vector2::new(xf, yf));
|
||||||
|
|
||||||
|
|
||||||
let red = (color.red() * 16.0) as u32;
|
let red = (color.red() * 16.0) as u32;
|
||||||
|
|
|
@ -14,11 +14,22 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub struct UbootPrüfstandFade { inputs: Arc<RwLock< Inputs >> }
|
pub struct UbootPrüfstandFade { inputs: Inputs }
|
||||||
|
|
||||||
|
impl Animation for UbootPrüfstandFade {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"UbootPrüfstand Fade".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn advance(&mut self, inputs: &Inputs) {
|
||||||
|
self.inputs = inputs.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ColorGrid for UbootPrüfstandFade {
|
impl ColorGrid for UbootPrüfstandFade {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let inputs = self.inputs.read().unwrap().clone();
|
|
||||||
// let millis = self
|
let inputs = self.inputs.clone();
|
||||||
|
|
||||||
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ pub trait ColorGrid {
|
||||||
fn get(&self, pos: &Vector2<f32>) -> Rgb<f32>;
|
fn get(&self, pos: &Vector2<f32>) -> Rgb<f32>;
|
||||||
}
|
}
|
||||||
pub trait Animation : ColorGrid {
|
pub trait Animation : ColorGrid {
|
||||||
|
fn name(&self) -> String {
|
||||||
|
String::from("unnamed")
|
||||||
|
}
|
||||||
fn advance(&mut self, inputs: &Inputs);
|
fn advance(&mut self, inputs: &Inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue