@@ -4,7 +4,10 @@ use anyhow::anyhow;
44use caw_viz_udp_app_lib:: oscilloscope;
55use clap:: { Parser , Subcommand } ;
66use line_2d:: Coord ;
7- use sdl2:: { event:: Event , pixels:: Color , rect:: Rect } ;
7+ use sdl2:: {
8+ EventPump , event:: Event , pixels:: Color , rect:: Rect , render:: Canvas ,
9+ video:: Window ,
10+ } ;
811use std:: collections:: VecDeque ;
912
1013#[ derive( Parser ) ]
@@ -29,9 +32,43 @@ struct OscilloscopeCommand {
2932 blue : u8 ,
3033}
3134
35+ #[ derive( Parser ) ]
36+ struct BlinkCommand {
37+ #[ arg( long, default_value_t = 100 ) ]
38+ width : u32 ,
39+ #[ arg( long, default_value_t = 100 ) ]
40+ height : u32 ,
41+ #[ arg( long, short, default_value_t = 0 ) ]
42+ red : u8 ,
43+ #[ arg( long, short, default_value_t = 255 ) ]
44+ green : u8 ,
45+ #[ arg( long, short, default_value_t = 0 ) ]
46+ blue : u8 ,
47+ }
48+
3249#[ derive( Subcommand ) ]
3350enum Command {
3451 Oscilloscope ( OscilloscopeCommand ) ,
52+ Blink ( BlinkCommand ) ,
53+ }
54+
55+ impl Command {
56+ fn width ( & self ) -> u32 {
57+ match self {
58+ Self :: Oscilloscope ( oscilloscope_command) => {
59+ oscilloscope_command. width
60+ }
61+ Self :: Blink ( blink_command) => blink_command. width ,
62+ }
63+ }
64+ fn height ( & self ) -> u32 {
65+ match self {
66+ Self :: Oscilloscope ( oscilloscope_command) => {
67+ oscilloscope_command. height
68+ }
69+ Self :: Blink ( blink_command) => blink_command. height ,
70+ }
71+ }
3572}
3673
3774#[ derive( Parser ) ]
@@ -53,17 +90,108 @@ struct ScopeState {
5390 samples : VecDeque < ( f32 , f32 ) > ,
5491}
5592
93+ struct App {
94+ server : String ,
95+ canvas : Canvas < Window > ,
96+ event_pump : EventPump ,
97+ }
98+
99+ impl App {
100+ fn run_oscilloscope (
101+ mut self ,
102+ mut args : OscilloscopeCommand ,
103+ ) -> anyhow:: Result < ( ) > {
104+ let mut viz_udp_client = oscilloscope:: Client :: new ( self . server ) ?;
105+ let mut scope_state = ScopeState :: default ( ) ;
106+ loop {
107+ for event in self . event_pump . poll_iter ( ) {
108+ match event {
109+ Event :: Quit { .. } => std:: process:: exit ( 0 ) ,
110+ Event :: MouseWheel { y, .. } => {
111+ let ratio = 1.1 ;
112+ if y > 0 {
113+ args. scale *= ratio;
114+ } else {
115+ args. scale /= ratio;
116+ }
117+ }
118+ Event :: MouseMotion {
119+ mousestate, xrel, ..
120+ } => {
121+ if mousestate. left ( ) {
122+ args. line_width = ( ( args. line_width as i32 ) + xrel)
123+ . clamp ( 1 , 20 )
124+ as u32 ;
125+ }
126+ if mousestate. right ( ) {
127+ args. alpha_scale = ( args. alpha_scale as i32 + xrel)
128+ . clamp ( 1 , 255 )
129+ as u8 ;
130+ }
131+ }
132+ _ => ( ) ,
133+ }
134+ }
135+ while let Ok ( true ) = viz_udp_client. recv_sample ( ) {
136+ for sample_pair in viz_udp_client. pairs ( ) {
137+ scope_state. samples . push_back ( sample_pair) ;
138+ }
139+ while scope_state. samples . len ( ) > args. max_num_samples {
140+ scope_state. samples . pop_front ( ) ;
141+ }
142+ }
143+ self . canvas . set_draw_color ( Color :: RGB ( 0 , 0 , 0 ) ) ;
144+ self . canvas . clear ( ) ;
145+ let screen_size = Coord {
146+ x : args. width as i32 ,
147+ y : args. height as i32 ,
148+ } ;
149+ let mut coord_iter =
150+ scope_state. samples . iter ( ) . map ( |( left, right) | {
151+ Coord {
152+ x : ( left * args. scale ) as i32 ,
153+ y : ( right * args. scale ) as i32 ,
154+ } + screen_size / 2
155+ } ) ;
156+ let mut prev = if let Some ( first) = coord_iter. next ( ) {
157+ first
158+ } else {
159+ Coord :: new ( 0 , 0 )
160+ } ;
161+ for ( i, coord) in coord_iter. enumerate ( ) {
162+ let alpha = ( ( args. alpha_scale as usize * i)
163+ / args. max_num_samples )
164+ . min ( 255 ) as u8 ;
165+ self . canvas . set_draw_color ( Color :: RGBA (
166+ args. red , args. green , args. blue , alpha,
167+ ) ) ;
168+ for Coord { x, y } in line_2d:: coords_between ( prev, coord) {
169+ let rect =
170+ Rect :: new ( x, y, args. line_width , args. line_width ) ;
171+ let _ = self . canvas . fill_rect ( rect) ;
172+ }
173+ prev = coord;
174+ }
175+ self . canvas . present ( ) ;
176+ }
177+ }
178+
179+ fn run_blink ( mut self , mut args : BlinkCommand ) -> anyhow:: Result < ( ) > {
180+ println ! ( "xxxxxx" ) ;
181+ loop { }
182+ }
183+ }
184+
56185fn main ( ) -> anyhow:: Result < ( ) > {
57186 let Cli {
58187 command,
59188 server,
60189 title,
61190 } = Cli :: parse ( ) ;
62- let Command :: Oscilloscope ( mut args) = command;
63191 let sdl_context = sdl2:: init ( ) . map_err ( |e| anyhow ! ( e) ) ?;
64192 let video_subsystem = sdl_context. video ( ) . map_err ( |e| anyhow ! ( e) ) ?;
65193 let window = video_subsystem
66- . window ( title. as_str ( ) , args . width , args . height )
194+ . window ( title. as_str ( ) , command . width ( ) , command . height ( ) )
67195 . always_on_top ( )
68196 . build ( ) ?;
69197 let mut canvas = window
@@ -72,75 +200,16 @@ fn main() -> anyhow::Result<()> {
72200 . present_vsync ( )
73201 . build ( ) ?;
74202 canvas. set_blend_mode ( sdl2:: render:: BlendMode :: Blend ) ;
75- let mut event_pump = sdl_context. event_pump ( ) . map_err ( |e| anyhow ! ( e) ) ?;
76- let mut viz_udp_client = oscilloscope:: Client :: new ( server) ?;
77- let mut scope_state = ScopeState :: default ( ) ;
78- loop {
79- for event in event_pump. poll_iter ( ) {
80- match event {
81- Event :: Quit { .. } => std:: process:: exit ( 0 ) ,
82- Event :: MouseWheel { y, .. } => {
83- let ratio = 1.1 ;
84- if y > 0 {
85- args. scale *= ratio;
86- } else {
87- args. scale /= ratio;
88- }
89- }
90- Event :: MouseMotion {
91- mousestate, xrel, ..
92- } => {
93- if mousestate. left ( ) {
94- args. line_width = ( ( args. line_width as i32 ) + xrel)
95- . clamp ( 1 , 20 )
96- as u32 ;
97- }
98- if mousestate. right ( ) {
99- args. alpha_scale = ( args. alpha_scale as i32 + xrel)
100- . clamp ( 1 , 255 )
101- as u8 ;
102- }
103- }
104- _ => ( ) ,
105- }
106- }
107- while let Ok ( true ) = viz_udp_client. recv_sample ( ) {
108- for sample_pair in viz_udp_client. pairs ( ) {
109- scope_state. samples . push_back ( sample_pair) ;
110- }
111- while scope_state. samples . len ( ) > args. max_num_samples {
112- scope_state. samples . pop_front ( ) ;
113- }
114- }
115- canvas. set_draw_color ( Color :: RGB ( 0 , 0 , 0 ) ) ;
116- canvas. clear ( ) ;
117- let screen_size = Coord {
118- x : args. width as i32 ,
119- y : args. height as i32 ,
120- } ;
121- let mut coord_iter = scope_state. samples . iter ( ) . map ( |( left, right) | {
122- Coord {
123- x : ( left * args. scale ) as i32 ,
124- y : ( right * args. scale ) as i32 ,
125- } + screen_size / 2
126- } ) ;
127- let mut prev = if let Some ( first) = coord_iter. next ( ) {
128- first
129- } else {
130- Coord :: new ( 0 , 0 )
131- } ;
132- for ( i, coord) in coord_iter. enumerate ( ) {
133- let alpha = ( ( args. alpha_scale as usize * i) / args. max_num_samples )
134- . min ( 255 ) as u8 ;
135- canvas. set_draw_color ( Color :: RGBA (
136- args. red , args. green , args. blue , alpha,
137- ) ) ;
138- for Coord { x, y } in line_2d:: coords_between ( prev, coord) {
139- let rect = Rect :: new ( x, y, args. line_width , args. line_width ) ;
140- let _ = canvas. fill_rect ( rect) ;
141- }
142- prev = coord;
203+ let event_pump = sdl_context. event_pump ( ) . map_err ( |e| anyhow ! ( e) ) ?;
204+ let app = App {
205+ server,
206+ event_pump,
207+ canvas,
208+ } ;
209+ match command {
210+ Command :: Oscilloscope ( oscilloscope_command) => {
211+ app. run_oscilloscope ( oscilloscope_command)
143212 }
144- canvas . present ( ) ;
213+ Command :: Blink ( blink_command ) => app . run_blink ( blink_command ) ,
145214 }
146215}
0 commit comments