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 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}