bevy_mod_chroma_api/
lib.rs

1use std::time::Duration;
2
3use api::Effect;
4use bevy::{
5    ecs::system::SystemParam,
6    prelude::{Commands, Entity, Resource},
7    utils::Instant,
8};
9use plugin::ApplyEffectRequest;
10use reqwest::Url;
11use serde::{Deserialize, Serialize};
12
13pub mod api;
14pub mod bgr_color;
15pub mod key_color;
16
17mod heartbeat;
18mod plugin;
19
20pub use bgr_color::BGRColor;
21pub use key_color::KeyColor;
22
23pub struct ChromaPlugin {
24    settings: ChromaRunnerInitializationSettings,
25}
26
27impl ChromaPlugin {
28    #[must_use]
29    pub fn new(settings: ChromaRunnerInitializationSettings) -> Self {
30        Self { settings }
31    }
32}
33
34#[derive(SystemParam)]
35pub struct Chroma<'w, 's> {
36    commands: Commands<'w, 's>,
37}
38
39impl<'w, 's> Chroma<'w, 's> {
40    #[must_use]
41    pub fn create_effect(&mut self, effect: Effect) -> EffectHandle {
42        EffectHandle {
43            entity: self.commands.spawn(effect).id(),
44        }
45    }
46
47    pub fn apply_effect_with_deadline(&mut self, effect_handle: &EffectHandle, deadline: Instant) {
48        self.commands.spawn(ApplyEffectRequest {
49            effect_entity: effect_handle.entity,
50            deadline,
51        });
52    }
53
54    pub fn apply_effect(&mut self, effect_handle: &EffectHandle) {
55        self.apply_effect_with_deadline(effect_handle, Instant::now() + Duration::from_secs(60));
56    }
57}
58
59#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
60pub struct EffectHandle {
61    entity: Entity,
62}
63
64#[derive(Resource)]
65pub struct ChromaRunner {
66    pub(crate) root_url: Url,
67}
68
69impl ChromaRunner {
70    #[must_use]
71    pub(crate) fn get_session_url(&self, relative_path: &'static str) -> Url {
72        // SAFETY: This is internal to the crate, so we assume that we aren't
73        // going to be passing in bad URLs
74        self.root_url.join(relative_path).unwrap()
75    }
76}
77
78#[derive(Resource, Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
79pub struct ChromaRunnerInitializationSettings {
80    init_url: &'static str,
81    init_request: InitRequest,
82}
83
84impl ChromaRunnerInitializationSettings {
85    #[must_use]
86    pub fn new(init_request: InitRequest) -> Self {
87        Self::new_with_init_url("http://localhost:54235/razer/chromasdk", init_request)
88    }
89
90    #[must_use]
91    pub fn new_with_init_url(init_url: &'static str, init_request: InitRequest) -> Self {
92        Self {
93            init_url,
94            init_request,
95        }
96    }
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
100pub struct InitRequest {
101    pub title: &'static str,
102    pub description: &'static str,
103    pub author: Author,
104    pub device_supported: Vec<SupportedDevice>,
105    pub category: Category,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
109pub struct Author {
110    pub name: &'static str,
111    pub contact: &'static str,
112}
113
114#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
115#[serde(rename_all = "lowercase")]
116pub enum SupportedDevice {
117    Keyboard,
118    Mouse,
119    Mousepad,
120    Headset,
121    Keypad,
122    ChromaLink,
123}
124
125#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash)]
126#[serde(rename_all = "lowercase")]
127pub enum Category {
128    Application,
129    Game,
130}