Skip to content

Commit

Permalink
feat(server): add bounce effect
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgomesdev committed Jun 9, 2024
1 parent 9dd3d46 commit e62ab83
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 60 deletions.
30 changes: 25 additions & 5 deletions server/src/graphql/schema_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(super) struct StaticLedEffectInput {
pub duration: Option<i32>,
#[graphql(description = "Name of the effect.")]
pub name: Option<String>,
#[graphql(description = "Hue/color (min 0.0, max 360.0)")]
#[graphql(description = "Hue/color (min 0, max 360)")]
pub hue: i32,
#[graphql(description = "Saturation (min 0.0, max 1.0)")]
pub saturation: f64,
Expand All @@ -44,7 +44,7 @@ pub(super) struct BreathingLedEffectInput {
pub duration: Option<i32>,
#[graphql(description = "Name of the effect.")]
pub name: Option<String>,
#[graphql(description = "Hue/color (min 0.0, max 360.0)")]
#[graphql(description = "Hue/color (min 0, max 360)")]
pub hue: i32,
#[graphql(description = "Saturation (min 0.0, max 1.0)")]
pub saturation: f64,
Expand Down Expand Up @@ -88,7 +88,7 @@ pub(super) struct BlinkLedEffectInput {
pub duration: Option<i32>,
#[graphql(description = "Name of the effect.")]
pub name: Option<String>,
#[graphql(description = "Hue/color (min 0.0, max 360.0)")]
#[graphql(description = "Hue/color (min 0, max 360)")]
pub hue: i32,
#[graphql(description = "Saturation (min 0.0, max 1.0)")]
pub saturation: f64,
Expand All @@ -101,14 +101,14 @@ pub(super) struct BlinkLedEffectInput {
#[derive(GraphQLInputObject, Debug)]
pub(super) struct CandleLedEffectInput {
#[graphql(
description = "If specified, must not be empty, and applies the effect only on these controller addresses."
description = "If specified, must not be empty, and applies the effect only on these controller addresses."
)]
pub controllers: Option<Vec<String>>,
#[graphql(description = "Duration of effect, in milliseconds, if specified.")]
pub duration: Option<i32>,
#[graphql(description = "Name of the effect.")]
pub name: Option<String>,
#[graphql(description = "Hue/color (min 0.0, max 360.0)")]
#[graphql(description = "Hue/color (min 0, max 360)")]
pub hue: i32,
#[graphql(description = "Saturation (min 0.0, max 1.0)")]
pub saturation: f64,
Expand All @@ -122,6 +122,26 @@ pub(super) struct CandleLedEffectInput {
pub interval: Option<i32>,
}

#[derive(GraphQLInputObject, Debug)]
pub(super) struct BounceLedEffectInput {
#[graphql(
description = "If specified, must not be empty, and applies the effect only on these controller addresses."
)]
pub controllers: Option<Vec<String>>,
#[graphql(description = "Duration of effect, in milliseconds, if specified.")]
pub duration: Option<i32>,
#[graphql(description = "Name of the effect.")]
pub name: Option<String>,
#[graphql(description = "Hue colors to bounce (each min 0, max 360)")]
pub hues: Vec<i32>,
#[graphql(description = "To Saturation (min 0.0, max 1.0)")]
pub saturation: f64,
#[graphql(description = "To value (min 0.0, max 1.0)")]
pub value: f64,
#[graphql(description = "Step ratio, percentage of change from one color to the other. (min 0.0=stay in from, max 1.0=stay in to)")]
pub step: f64
}

#[derive(GraphQLInputObject, Debug)]
pub(super) struct StaticRumbleEffectInput {
#[graphql(
Expand Down
49 changes: 48 additions & 1 deletion server/src/graphql/schema_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ impl MutationRoot {
}

#[graphql(
description = "Randomly set brightness between min value and max value, simulating a candle/flame."
description = "Randomly set brightness between min value and max value, simulating a candle/flame."
)]
fn set_led_candle(ctx: &Context, input: CandleLedEffectInput) -> FieldResult<MutationResponse> {
tracing::info!(
Expand Down Expand Up @@ -363,6 +363,53 @@ impl MutationRoot {
)
}

#[graphql(
description = "Bounces from one color to the other."
)]
fn set_led_bounce(ctx: &Context, input: BounceLedEffectInput) -> FieldResult<MutationResponse> {
tracing::info!(
"Received led bounce effect ({})",
input
.name
.clone()
.map_or(String::from("unnamed"), |name| format!("'{name}'"))
);
tracing::debug!("Effect input: {input:?}");

if input.name.map_or(false, |name| name.is_empty()) {
return Err(FieldError::new("Name can't be empty!", Value::Null));
}

if !input.hues.iter().all(|hue| (0..=360).contains(hue)) {
return Err(FieldError::new(
"Hue must be between 0 and 360!",
Value::Null,
));
}

if !(0.0..=1.0).contains(&input.saturation) {
return Err(FieldError::new(
"Saturation must be between 0.0 and 1.0!",
Value::Null,
));
}

if !(0.0..=1.0).contains(&input.value) {
return Err(FieldError::new(
"Min value must between 0.0 and 1.0!",
Value::Null,
));
}

let effect = LedEffectKind::new_bounce(input.hues.iter().map(|hue| *hue as f32).collect(), input.saturation as f32, input.value as f32, input.step as f32);

process_led_effect_mutation(
ctx,
LedEffect::from(effect, input.duration),
input.controllers,
)
}

#[graphql(description = "Turn rumble off.")]
fn set_rumble_off(
ctx: &Context,
Expand Down
1 change: 1 addition & 0 deletions server/src/graphql/schema_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl QueryRoot {
api::LedEffectKind::Rainbow { .. } => { graphql::LedEffectType::Rainbow }
api::LedEffectKind::Blink { .. } => { graphql::LedEffectType::Blink }
api::LedEffectKind::Candle { .. } => { graphql::LedEffectType::Candle }
api::LedEffectKind::Bounce { .. } => { graphql::LedEffectType::Bounce }
},
current_rumble_effect: match ctl.rumble_effect.kind {
api::RumbleEffectKind::Off => { graphql::RumbleEffectType::Off }
Expand Down
1 change: 1 addition & 0 deletions server/src/graphql/schema_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub(super) enum LedEffectType {
Rainbow,
Blink,
Candle,
Bounce,
}

#[derive(GraphQLEnum)]
Expand Down
11 changes: 4 additions & 7 deletions server/src/monitoring/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,10 @@ pub async fn metrics_handler() -> Result<impl Reply, Rejection> {
if let Err(e) = encoder.encode(&prometheus::gather(), &mut buffer) {
eprintln!("could not encode prometheus metrics: {}", e);
};
let result = match String::from_utf8(buffer.clone()) {
Ok(v) => v,
Err(e) => {
eprintln!("prometheus metrics could not be from_utf8'd: {}", e);
String::default()
}
};
let result = String::from_utf8(buffer.clone()).unwrap_or_else(|e| {
eprintln!("prometheus metrics could not be from_utf8'd: {}", e);
String::default()
});
buffer.clear();

Ok(result)
Expand Down
2 changes: 1 addition & 1 deletion server/src/ps_move/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ impl PsMoveApi {
}

if connection_type == ConnectionType::Usb {
usb_path = path.clone();
usb_path.clone_from(&path);
bt_address = if cfg!(windows) {
self.get_bt_address_on_windows(&path)
} else {
Expand Down
18 changes: 8 additions & 10 deletions server/src/ps_move/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ impl PsMoveController {
}

if self.connection_type == ConnectionType::Usb {
self.info.bt_path = other.info.bt_path.clone();
self.info.bt_path.clone_from(&other.info.bt_path);
} else if self.connection_type == ConnectionType::Bluetooth {
self.info.usb_path = other.info.usb_path.clone();
self.info.usb_path.clone_from(&other.info.usb_path);
}
self.connection_type = ConnectionType::UsbAndBluetooth;
}
Expand All @@ -94,10 +94,10 @@ impl PsMoveController {
}

pub fn revert_led_effect(&mut self) {
let current_effect = self.led_effect;
let current_effect = self.led_effect.clone();
let current_led = self.setting.led;

self.led_effect = self.last_led_effect;
self.led_effect = self.last_led_effect.clone();
self.setting.led = self.setting.last_led;

self.last_led_effect = current_effect;
Expand All @@ -110,22 +110,20 @@ impl PsMoveController {
info!("Last led effect '{}' of '{}' has already expired, setting to off", last_led_effect, self.bt_address);
let off_effect = LedEffect::off();

self.led_effect = off_effect;
self.setting.led = off_effect.kind.get_initial_hsv()
self.setting.led = off_effect.kind.get_initial_hsv();
self.led_effect = off_effect
}
}

info!("Reverted '{:?}' to '{}'", self.bt_address, self.led_effect);
}

pub fn set_led_effect(&mut self, effect: LedEffect) {
self.last_led_effect = self.led_effect;
self.last_led_effect = self.led_effect.clone();
self.setting.last_led = self.setting.led;

let kind = effect.kind;

self.setting.led = effect.kind.get_initial_hsv();
self.led_effect = effect;
self.setting.led = kind.get_initial_hsv();
}

pub fn set_led_effect_with_hsv(&mut self, effect: LedEffect, hsv: Hsv) {
Expand Down
Loading

0 comments on commit e62ab83

Please sign in to comment.