Compare commits

..

62 commits

Author SHA1 Message Date
9d61ad5fbd added shell.nix to test 2023-05-06 10:50:07 -07:00
Nickiel12
2dd94631ff should I toss these tests out? 2022-07-16 22:19:24 -07:00
Nickiel12
970eabdda8 removed the unused hotkey_stop flag 2022-07-16 22:18:51 -07:00
Nickiel12
3962a48843 changed tray-message handler to be stateless 2022-07-16 17:56:22 -07:00
Nickiel12
06333b7fe2 ran rustfmt 2022-07-16 21:16:56 -07:00
Nickiel12
a3e675def6 set to non-blocking 2022-07-16 21:14:00 -07:00
Nickiel12
fdb60f6e00 working version of tray_icon events 2022-07-16 21:08:52 -07:00
Nickiel12
1d97546bbe thread start and stop debug statements 2022-07-16 19:32:48 -07:00
Nickiel12
7e97255acb added some closing thread debug prints 2022-07-16 19:28:09 -07:00
Nickiel12
e5e50e5422 fixed bug when disabling default features 2022-07-16 19:15:02 -07:00
Nickiel12
eb37513a4b test windows build now use localhost 2022-07-16 18:58:05 -07:00
Nickiel12
ed38b4aa73 added demo tray_icon. has a bug where clicks get "stuck" in the queue 2022-07-13 22:29:25 -07:00
Nickiel12
cce730a57f fixed and implemented #8 2022-06-29 21:10:20 -07:00
Nickiel12
21c38e275a moved an if statement into the switch statement 2022-06-29 20:43:47 -07:00
Nickiel12
b04d93b96a just some formatting spaces 2022-06-29 20:42:39 -07:00
Nickiel12
db866b4b8d "timer can run" button now unpauses when timer is paused 2022-06-29 20:33:31 -07:00
Nickiel12
9a867e0735 added pause_timer to update_all 2022-06-29 20:33:12 -07:00
Nickiel12
7a216c36b2 set up decoding of pause timer events 2022-06-29 19:54:07 -07:00
Nickiel12
c43c1a8edd last track 2022-06-29 19:12:11 -07:00
Nickiel12
68b2eb97be why is this tracked 2022-06-29 19:12:02 -07:00
Nickiel12
063895d06f re-added the default feature flag 2022-06-29 18:54:22 -07:00
Nickiel12
655b19a5c9 removed extra feature flags 2022-06-29 18:52:49 -07:00
Nickiel12
584491a854 added feature flags to disable hotkey-hooks 2022-06-29 18:07:24 -07:00
Nickiel12
1feaca41b3 addresses issue #2 2022-06-29 18:04:27 -07:00
Nickiel12
014adade68 added feature flag to disable hotkey-hooking 2022-06-29 18:00:30 -07:00
Nickiel12
625014bcfd debug message 2022-06-28 20:35:55 -07:00
Nickiel12
b974bc5b59 renamed stream_states_class -> stream_state 2022-06-24 19:19:30 -07:00
Nickiel12
81fd3bc2ce added pause_timer 2022-06-24 19:19:03 -07:00
Nickiel12
81b09b7e42 added timer pause length
cleaned match statement
2022-06-24 11:32:58 -07:00
Nickiel12
8576b6f126 renamed enums -> senes 2022-06-24 10:02:31 -07:00
Nickiel12
d5061bf674 testing on linux 2022-06-19 22:03:58 -07:00
Nickiel12
cdb3666ad7 swapped type checks with convenience function 2022-06-19 20:37:11 -07:00
Nickiel12
b3a39afa12 added convenience function for getting basic type 2022-06-19 20:33:13 -07:00
Nickiel12
dd9ceb6bc3 renamed change_scene_on_hotkey 2022-06-19 20:21:10 -07:00
Nickiel12
230614b626 removed print statement 2022-06-19 19:55:27 -07:00
Nickiel12
74cedc3b08 fixed timer starting when clicker auto off 2022-01-09 13:40:24 -08:00
Nickiel12
5915c5406f Revert "switched from strange function to as_bool"
This reverts commit a33a6f7b37.
2022-01-05 17:44:26 -08:00
Nickiel12
849d73d4a8 Merge branch 'master' of https://github.com/Nickiel12/church_controller_rust 2022-01-02 21:55:14 -08:00
Nickiel12
c8737d64a2 removed unused function 2022-01-02 21:50:53 -08:00
Nickiel12
a33a6f7b37 switched from strange function to as_bool 2022-01-02 21:50:07 -08:00
Nickiel12
16554e409e removed extra step and variable 2022-01-02 21:46:55 -08:00
Nickiel12
24730ee3da removed step 2022-01-02 21:45:21 -08:00
Nickiel12
b3ce6858e9 only one socket handler thread 2022-01-02 21:37:01 -08:00
Nickiel12
6c8f5c44f7 a bit of condensing 2022-01-02 20:31:57 -08:00
Nickiel12
1f132c8863 timer tick now uses instruction flow 2022-01-02 20:13:11 -08:00
Nickiel12
2d2147f799 chnaged tick to return instructions array 2022-01-02 20:08:57 -08:00
Nickiel12
bab92d3327 some refactoring 2022-01-02 19:50:36 -08:00
Nickiel12
18633890f2 fixed control_c flag call 2022-01-02 19:45:29 -08:00
Nickiel12
55921ca08f added new() constructor 2022-01-02 19:39:20 -08:00
Nickiel12
6a1f512db4 error catching for sockets 2022-01-02 19:02:26 -08:00
Nickiel12
23dceaf2ba got rid of delayed sending 2021-12-31 19:54:52 -08:00
Nickiel12
6b7edb7ce8 added from hotkey checks 2021-12-31 19:35:04 -08:00
Nickiel12
b158b9068e bug fixes 2021-12-31 19:34:48 -08:00
Nickiel12
1738a030c4 bug fixes 2021-12-31 19:34:40 -08:00
Nickiel12
480f5b0c11 added differentiation of hotkey and app 2021-12-31 19:34:24 -08:00
Nickiel12
686d7b8237 added delays so commands don't overlap 2021-12-31 10:44:50 -08:00
Nickiel12
47d47f0819 made delay smaller 2021-12-31 10:44:39 -08:00
Nickiel12
39a5b9d6e3 shouldn't try to double send things now 2021-12-31 10:42:31 -08:00
Nickiel12
ba59e749d7 added thread_closing message 2021-12-31 10:42:18 -08:00
Nickiel12
a8fae93858 fixed incorrect autohotkey call 2021-12-31 09:52:07 -08:00
Nickiel12
686ef3c8a2 added more delay for hotkey 2021-12-31 09:51:51 -08:00
Nickiel12
97a2bf9744
Merge pull request #1 from Nickiel12/windows
Windows
2021-12-31 09:45:11 -08:00
25 changed files with 1319 additions and 615 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/target
Cargo.lock
*.exe

106
Cargo.lock generated
View file

@ -4,15 +4,15 @@ version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "byteorder"
@ -32,9 +32,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.72"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
@ -61,9 +61,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
@ -71,21 +71,21 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if 1.0.0",
"lazy_static",
"once_cell",
]
[[package]]
name = "ctrlc"
version = "3.2.1"
version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
dependencies = [
"nix 0.23.1",
"nix 0.24.1",
"winapi",
]
@ -143,7 +143,7 @@ version = "0.5.0"
dependencies = [
"input",
"libc",
"nix 0.22.2",
"nix 0.22.3",
"once_cell",
"strum",
"strum_macros",
@ -170,21 +170,15 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "libc"
version = "0.2.112"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libudev-sys"
@ -221,9 +215,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.22.2"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3bb9a13fa32bc5aeb64150cd3f32d6cf4c748f8f8a417cce5d2eb976a8370ba"
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
dependencies = [
"bitflags",
"cc",
@ -234,64 +228,62 @@ dependencies = [
[[package]]
name = "nix"
version = "0.23.1"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
dependencies = [
"bitflags",
"cc",
"cfg-if 1.0.0",
"libc",
"memoffset",
]
[[package]]
name = "once_cell"
version = "1.9.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
name = "pkg-config"
version = "0.3.24"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "proc-macro2"
version = "1.0.36"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.14"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "serde"
version = "1.0.132"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
[[package]]
name = "serde_json"
version = "1.0.73"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [
"itoa",
"ryu",
@ -321,20 +313,20 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.84"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "udev"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3193363f52bb34c6708ac2ffedcb5f7e5874f0329ef68e1315f27d8d768eb568"
checksum = "1c960764f7e816eed851a96c364745d37f9fe71a2e7dba79fbd40104530b5dd0"
dependencies = [
"libc",
"libudev-sys",
@ -365,16 +357,16 @@ dependencies = [
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
[[package]]
name = "unicode-xid"
version = "0.2.2"
name = "unicode-segmentation"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
[[package]]
name = "void"

View file

@ -10,4 +10,11 @@ workctl = "0.2.0"
ctrlc = "3.2.1"
serde_json = "1.0"
crossbeam-channel = "0.5"
inputbot = {path = "D:\\InputBot"}
inputbot = {path = "D:\\Inputbot"}
winit = "0.25"
winapi = { version = "0.3.9", features = ["winuser", "windef", "minwindef", "shellapi", "libloaderapi", "commctrl", "basetsd"] }
trayicon = { version="0.1.3", features = ["crossbeam-channel"] }
[features]
default = []
no_hotkeys = []

View file

@ -15,7 +15,7 @@ if WinExist("ahk_exe Dopamine.exe"){
}
If WinExist(A_Args[1]) ; propresenter
{ ; if propresenter isn't active, switch and send clicker forward
{ ; if propresenter isn't active, switch to it
if !WinActive(A_Args[1]){
WinActivate
}

View file

@ -8,10 +8,19 @@ SetTitleMatchMode, Fast
If WinExist(A_Args[1]) ; propresenter
{ ; if propresenter isn't active, switch and send clicker forward
if !WinActive(A_Args[1]){
WinActivate
sleep 200
if (A_Args[3]) { ; 1 for from_hotkey 0 for from app
if !WinActive(A_Args[1]){
WinActivate
sleep 200
arg := A_Args[2]
Send {%arg%}
}
} else {
if !WinActive(A_Args[1]){
WinActivate
sleep 200
}
arg := A_Args[2]
Send {%arg%}
}
arg := A_Args[2]
Send {%arg%}
}

View file

@ -16,7 +16,7 @@ If WinExist(A_Args[2]) ;OBS
Send {%arg%}
}
sleep 100
sleep 200
If WinExist(A_Args[1]) ; Propresenter
{ ; switch back to propresenter

19
shell.nix Normal file
View file

@ -0,0 +1,19 @@
# <shell.nix>
{ pkgs ? import <nixpkgs> {}}:
let
rust_overlay = import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz");
pkgs = import <nixpkgs> { overlays = [ rust_overlay ]; };
ruststable = (pkgs.rust-bin.stable.latest.default.override {
extensions = [
"rust-src"
];
});
in
pkgs.mkShell {
buildInputs = with pkgs; [
ruststable
rust-analyzer
bacon
];
}

BIN
src/icon1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
src/icon2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -1,16 +1,28 @@
use std::{time::Duration, thread, io::Read};
use crossbeam_channel::unbounded;
use tray_icon::TrayIcon;
use std::{io::Read, thread, time::Duration};
use modules::{socket_handler::Socket, stream_states::stream_states_class::StreamState, message_handler::{MessageHandler}, external_interface::{Hotkeys, OPTIONS_PATH}};
use modules::{
external_interface::{Hotkeys, OPTIONS_PATH},
message_handler::MessageHandler,
socket_handler::Socket,
stream_states::stream_state::StreamState,
};
use workctl::sync_flag;
use crate::modules::stream_states::state_update::StateUpdate;
#[cfg(target_os = "windows")]
use modules::tray_icon;
mod modules;
#[cfg(test)]
mod tests;
mod modules;
#[cfg(target_os = "windows")]
const SERVER_ADDRESS: &str = "localhost:5000";
#[cfg(release)]
#[cfg(target_os = "windows")]
const SERVER_ADDRESS: &str = "10.0.0.209:5000";
@ -18,77 +30,74 @@ const SERVER_ADDRESS: &str = "10.0.0.209:5000";
const SERVER_ADDRESS: &str = "10.0.0.168:5000";
fn main() {
let settings_json: serde_json::Value;
{
let mut settings_file = std::fs::File::open(OPTIONS_PATH).unwrap();
let mut settings_str = String::new();
settings_file.read_to_string(&mut settings_str).unwrap();
settings_json = serde_json::from_str(settings_str.as_str()).unwrap();
drop(settings_file);
}
let hotkeys = Hotkeys {
hotkeys: settings_json,
};
let mut state = StreamState::new();
let icon = include_bytes!("icon1.ico");
let tray_icon = tray_icon::TrayIcon::setup(icon);
let settings_json = load_json();
let hotkeys = Hotkeys::new(settings_json);
let (control_c_flag_tx, control_c_called_flag_rx) = sync_flag::new_syncflag(false);
let (from_socket_tx, from_socket_rx) = unbounded::<String>();
let hotkey_channel_tx = from_socket_tx.clone();
let socket_listener = Socket::make_listener(SERVER_ADDRESS);
let mut socket = Socket::handle_connections(socket_listener, from_socket_tx);
let (hotkey_close_flag_tx, hotkey_close_flag_rx) = sync_flag::new_syncflag(true);
setup_control_c(control_c_flag_tx, hotkey_close_flag_tx);
let mut socket =
Socket::handle_connections(Socket::make_listener(SERVER_ADDRESS), from_socket_tx);
let control_c_called_flag_rx = setup_control_c();
let hotkey_handle = thread::spawn(move || {
modules::external_interface::create_keyboard_hooks(hotkey_channel_tx, hotkey_close_flag_rx);
println!("starting hotkey thread");
modules::external_interface::create_keyboard_hooks(hotkey_channel_tx);
println!("closing hotkey thread");
});
let mut state = StreamState::new();
//until control_c is caught, check the queue of incoming
//requests from the socket handler.
while !control_c_called_flag_rx.get() {
match from_socket_rx.recv_timeout(Duration::from_millis(100)) {
Ok(message) => {
println!("main recieved: {}", message);
let json = serde_json::from_str(&message).unwrap();
let update = StateUpdate::json_to_state_update(json);
if update == StateUpdate::UpdateClient {
update_all(&state, &socket);
let stop_flag = control_c_called_flag_rx.clone();
let messages = tray_icon.message_channel.clone();
std::thread::spawn(move || {
while !control_c_called_flag_rx.get() {
match from_socket_rx.recv_timeout(Duration::from_millis(100)) {
Ok(message) => {
println!("main recieved: {}", message);
let update =
StateUpdate::json_to_state_update(serde_json::from_str(&message).unwrap());
if update == StateUpdate::UpdateClient {
update_all(&state, &socket);
} else {
handle_instructions(vec![update], &mut state, &socket, &hotkeys);
}
}
let updates = state.handle_update(update, &hotkeys);
if updates.0.is_some() {
socket.send(updates.0.unwrap().to_json().to_string());
}
if updates.1.is_some() {
handle_instructions(updates.1.unwrap(), &mut state, &socket, &hotkeys);
}
},
Err(_) => {},
}
let tick_update = state.tick();
if tick_update.0.is_some() {
let update = state.handle_update(tick_update.0.unwrap(), &hotkeys);
if update.0.is_some() {socket.send(update.0.unwrap().to_json().to_string());}
if update.1.is_some() {handle_instructions(update.1.unwrap(), &mut state, &socket, &hotkeys);}
}
if tick_update.1.is_some() {
let update = state.handle_update(tick_update.1.unwrap(), &hotkeys);
if update.0.is_some() {socket.send(update.0.unwrap().to_json().to_string());}
if update.1.is_some() {handle_instructions(update.1.unwrap(), &mut state, &socket, &hotkeys);}
Err(_) => {}
}
let tick_update = state.tick();
handle_instructions(tick_update, &mut state, &socket, &hotkeys);
TrayIcon::handle_tray_messages(&messages);
}
socket.close();
});
while !stop_flag.get() {
tray_icon.check_tray_icon_messages();
//tray_icon.check_tray_messages();
}
socket.close();
println!("closing main thread");
hotkey_handle.join().unwrap();
}
fn handle_instructions(mut instructions: Vec<StateUpdate>, state: &mut StreamState, socket: &Socket, hotkeys: &Hotkeys) {
fn handle_instructions(
mut instructions: Vec<StateUpdate>,
state: &mut StreamState,
socket: &Socket,
hotkeys: &Hotkeys,
) {
for i in instructions.iter_mut() {
let updates = state.handle_update(i.to_owned(), &hotkeys);
if updates.0.is_some() {
socket.send(updates.0.unwrap().to_json().to_string());
let output = updates.0.unwrap().to_json().to_string();
println!("sending: {}", output);
socket.send(output);
}
if updates.1.is_some() {
handle_instructions(updates.1.unwrap(), state, socket, hotkeys);
@ -96,26 +105,84 @@ fn handle_instructions(mut instructions: Vec<StateUpdate>, state: &mut StreamSta
}
}
fn setup_control_c(mut control_c_flag_tx: sync_flag::SyncFlagTx, mut hotkey_close_flag_tx: sync_flag::SyncFlagTx) {
fn setup_control_c() -> sync_flag::SyncFlagRx {
let (mut control_c_flag_tx, control_c_called_flag_rx) = sync_flag::new_syncflag(false);
ctrlc::set_handler(move || {
println!("ctrl c caught");
control_c_flag_tx.set(true);
hotkey_close_flag_tx.set(false);
}).expect("control C handler failed!");
})
.expect("control C handler failed!");
control_c_called_flag_rx
}
fn load_json() -> serde_json::Value {
let mut settings_file = std::fs::File::open(OPTIONS_PATH).unwrap();
let mut settings_str = String::new();
settings_file.read_to_string(&mut settings_str).unwrap();
drop(settings_file);
serde_json::from_str(settings_str.as_str()).unwrap()
}
fn update_all(state: &StreamState, socket: &Socket) {
println!("updating all");
socket.send(StateUpdate::StreamRunning(state.stream_running).to_json().to_string());
socket.send(StateUpdate::StreamSoundToggleOn(state.stream_is_muted).to_json().to_string());
socket.send(StateUpdate::ToggleComputerSoundOn(state.computer_sound_is_on).to_json().to_string());
socket.send(StateUpdate::ChangeSceneOnChangeSlide(state.change_scene_on_change_slide_hotkey).to_json().to_string());
socket.send(StateUpdate::SceneIsAugmented(state.scene_is_augmented).to_json().to_string());
socket.send(StateUpdate::TimerCanRun(state.timer_can_run).to_json().to_string());
socket.send(StateUpdate::TimerLength(state.timer_length).to_json().to_string());
socket.send(StateUpdate::TimerText(state.timer_text.clone()).to_json().to_string());
socket.send(StateUpdate::SubScene(state.camera_sub_scene).to_json().to_string());
socket.send(StateUpdate::SubScene(state.screen_sub_scene).to_json().to_string());
socket.send(StateUpdate::Scene(state.current_scene).to_json().to_string());
socket.send(
StateUpdate::StreamRunning(state.stream_running)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::StreamSoundToggleOn(state.stream_is_muted)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::ToggleComputerSoundOn(state.computer_sound_is_on)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::ChangeSceneOnChangeSlide(state.change_scene_on_slide_hotkey)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::SceneIsAugmented(state.scene_is_augmented)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::TimerCanRun(state.timer_can_run)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::TimerLength(state.timer_length)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::TimerText(state.timer_text.clone())
.to_json()
.to_string(),
);
socket.send(
StateUpdate::SubScene(state.camera_sub_scene)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::SubScene(state.screen_sub_scene)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::Scene(state.current_scene)
.to_json()
.to_string(),
);
socket.send(
StateUpdate::PauseTimer(state.timer_paused_length.is_some())
.to_json()
.to_string(),
);
}

View file

@ -1,27 +1,57 @@
use super::stream_states::{
scenes::{Scenes, SlideChange, SubScenes},
state_update::StateUpdate,
};
use std::process::Command;
use super::stream_states::{state_update::StateUpdate, enums::{SlideChange, SubScenes, Scenes}};
#[cfg(target_os = "windows")]
const AHK_FILES_FOLDER: &str = ".\\ahk_files\\";
#[cfg(target_os = "windows")]
pub const OPTIONS_PATH: &str = ".\\options.json";
/*
const AHK_FILES_FOLDER: &str = "./src/ahk_files/";
pub const OPTIONS_PATH: &str = "./options.json";
*/
#[cfg(target_os = "linux")]
const AHK_FILES_FOLDER: &str = "./ahk_files/";
#[cfg(target_os = "linux")]
pub const OPTIONS_PATH: &str = "./options.json";
pub fn create_keyboard_hooks(channel_tx: crossbeam_channel::Sender<String>, close_flag: workctl::sync_flag::SyncFlagRx) {
/*
const AHK_FILES_FOLDER: &str = "./src/ahk_files/";
pub const OPTIONS_PATH: &str = "./options.json";
*/
pub fn create_keyboard_hooks(
channel_tx: crossbeam_channel::Sender<String>,
) {
let tx_1 = channel_tx.clone();
inputbot::KeybdKey::PageUpKey.bind(move || {
tx_1.send(StateUpdate::ChangeSlide(SlideChange::Next).to_json().to_string()).unwrap();
tx_1.send(
StateUpdate::ChangeSlide(SlideChange::PreviousHotkey)
.to_json()
.to_string(),
)
.unwrap();
});
let tx_2 = channel_tx.clone();
inputbot::KeybdKey::PageDownKey.bind(move || {
tx_2.send(StateUpdate::ChangeSlide(SlideChange::Previous).to_json().to_string()).unwrap();
tx_2.send(
StateUpdate::ChangeSlide(SlideChange::NextHotkey)
.to_json()
.to_string(),
)
.unwrap();
});
inputbot::handle_input_events(close_flag);
#[cfg(feature = "default")]
inputbot::handle_input_events();
}
#[cfg(feature = "no_hotkeys")]
pub fn create_keyboard_hooks(
channel_tx: crossbeam_channel::Sender<String>,
close_flag: workctl::sync_flag::SyncFlagRx,
) {
return;
}
pub struct Hotkeys {
@ -29,101 +59,164 @@ pub struct Hotkeys {
}
impl Hotkeys {
pub fn new(hotkeys: serde_json::Value) -> Self {
Hotkeys { hotkeys }
}
pub fn get_hotkey_from_scene(&self, scene: SubScenes) -> &str {
match scene {
SubScenes::CameraDefault => {self.hotkeys["hotkeys"]["obs"]["camera_scene_hotkey"].as_str().unwrap()},
SubScenes::CameraWithUpperRight => {self.hotkeys["hotkeys"]["obs"]["Camera_Top_Right"].as_str().unwrap()},
SubScenes::CameraWithLargeUpperRight => {self.hotkeys["hotkeys"]["obs"]["Camera_Large_Top_Right"].as_str().unwrap()},
SubScenes::CameraWithLowerRight => {self.hotkeys["hotkeys"]["obs"]["Camera_Bottom_Right"].as_str().unwrap()},
SubScenes::ScreenDefault => {self.hotkeys["hotkeys"]["obs"]["screen_scene_hotkey"].as_str().unwrap()},
SubScenes::ScreenWithUpperRight => {self.hotkeys["hotkeys"]["obs"]["Screen_Top_Right"].as_str().unwrap()},
SubScenes::ScreenWithLowerRight => {self.hotkeys["hotkeys"]["obs"]["Screen_Bottom_Right"].as_str().unwrap()},
SubScenes::CameraDefault => self.hotkeys["hotkeys"]["obs"]["camera_scene_hotkey"]
.as_str()
.unwrap(),
SubScenes::CameraWithUpperRight => self.hotkeys["hotkeys"]["obs"]["Camera_Top_Right"]
.as_str()
.unwrap(),
SubScenes::CameraWithLargeUpperRight => self.hotkeys["hotkeys"]["obs"]
["Camera_Large_Top_Right"]
.as_str()
.unwrap(),
SubScenes::CameraWithLowerRight => self.hotkeys["hotkeys"]["obs"]
["Camera_Bottom_Right"]
.as_str()
.unwrap(),
SubScenes::ScreenDefault => self.hotkeys["hotkeys"]["obs"]["screen_scene_hotkey"]
.as_str()
.unwrap(),
SubScenes::ScreenWithUpperRight => self.hotkeys["hotkeys"]["obs"]["Screen_Top_Right"]
.as_str()
.unwrap(),
SubScenes::ScreenWithLowerRight => self.hotkeys["hotkeys"]["obs"]
["Screen_Bottom_Right"]
.as_str()
.unwrap(),
}
}
pub fn send_obs(&self, hotkey: &str) {
if cfg!(target_family = "windows") {
println!("sending to obs");
Command::new(String::from(AHK_FILES_FOLDER) + "send_obs_back_to_propre.exe")
.args([self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["windows"]["obs_re"].as_str().unwrap(),
hotkey])
.args([
self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["windows"]["obs_re"].as_str().unwrap(),
hotkey,
])
.spawn()
.expect("next_slide process call failed");
std::thread::sleep(std::time::Duration::from_millis(400));
} else {
println!("pretend linux is sending obs send: {}", hotkey)
};
}
pub fn next_slide(&self) {
pub fn next_slide(&self, from_hotkey: bool) {
let from_hotkey_str = {
if from_hotkey {
"1"
} else {
"0"
}
};
if cfg!(target_family = "windows") {
Command::new(String::from(AHK_FILES_FOLDER) + "switch_and_send.exe")
.args([self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["general"]["clicker_forward"].as_str().unwrap()])
Command::new(String::from(AHK_FILES_FOLDER) + "propre_send.exe")
.args([
self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["general"]["clicker_forward"].as_str().unwrap(),
from_hotkey_str,
])
.spawn()
.expect("next_slide process call failed");
std::thread::sleep(std::time::Duration::from_millis(200));
} else {
println!("pretend linux is sending prosenter next: {}", self.hotkeys["general"]["clicker_forward"].as_str().unwrap())
println!(
"pretend linux is sending prosenter next: {}",
self.hotkeys["general"]["clicker_forward"].as_str().unwrap()
)
};
}
pub fn prev_slide(&self) {
pub fn prev_slide(&self, from_hotkey: bool) {
let from_hotkey_str = {
if from_hotkey {
"1"
} else {
"0"
}
};
if cfg!(target_family = "windows") {
Command::new(String::from(AHK_FILES_FOLDER) + "switch_and_send.exe")
.args([self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["general"]["clicker_backward"].as_str().unwrap()])
Command::new(String::from(AHK_FILES_FOLDER) + "propre_send.exe")
.args([
self.hotkeys["windows"]["propresenter_re"].as_str().unwrap(),
self.hotkeys["general"]["clicker_backward"]
.as_str()
.unwrap(),
from_hotkey_str,
])
.spawn()
.expect("next_slide process call failed");
std::thread::sleep(std::time::Duration::from_millis(200));
} else {
println!("pretend linux is sending prosenter next: {}", self.hotkeys["general"]["clicker_backward"].as_str().unwrap())
println!(
"pretend linux is sending prosenter next: {}",
self.hotkeys["general"]["clicker_backward"]
.as_str()
.unwrap()
)
};
}
pub fn change_scene(&self, scene: Scenes, sub_scene: Option<SubScenes>) {
println!("sending: {:?} : {:?}", scene, sub_scene);
let hotkey: &str;
if scene == Scenes::Augmented {
hotkey = self.hotkeys["hotkeys"]["obs"]["camera_scene_augmented"].as_str().unwrap()
hotkey = self.hotkeys["hotkeys"]["obs"]["camera_scene_augmented"]
.as_str()
.unwrap()
} else {
hotkey = self.get_hotkey_from_scene(sub_scene.unwrap())
};
self.send_obs(hotkey);
}
pub fn toggle_stream_sound(&self, turn_on: bool) {
let hotkey: &str;
if turn_on {
hotkey = self.hotkeys["hotkeys"]["obs"]["unmute_stream"].as_str().unwrap();
hotkey = self.hotkeys["hotkeys"]["obs"]["unmute_stream"]
.as_str()
.unwrap();
} else {
hotkey = self.hotkeys["hotkeys"]["obs"]["mute_stream"].as_str().unwrap();
hotkey = self.hotkeys["hotkeys"]["obs"]["mute_stream"]
.as_str()
.unwrap();
}
self.send_obs(hotkey);
}
pub fn toggle_computer_sound(&self, value: bool) {
let direction: u8 = if value {1} else {0};
let time_delay = self.hotkeys["general"]["music_fade_time"].as_i64().unwrap();
if cfg!(target_family = "windows") {
Command::new(String::from(AHK_FILES_FOLDER) + "music_toggle.exe")
.arg(direction.to_string())
.arg((value as u8).to_string())
.arg(time_delay.to_string())
.spawn()
.expect("next_slide process call failed");
} else {
println!("pretend linux is sending prosenter next: {}", self.hotkeys["general"]["clicker_backward"].as_str().unwrap())
println!("pretend linux is sending media: {}", value)
};
}
pub fn toggle_media_play_pause(&self) {
if cfg!(target_family = "windows") {
Command::new(String::from(AHK_FILES_FOLDER) + "music_toggle.exe")
.arg(self.hotkeys["windows"]["propresenter_re"].as_str().unwrap())
Command::new(String::from(AHK_FILES_FOLDER) + "pause_play_global.exe")
.arg(self.hotkeys["windows"]["propresenter_re"].as_str().unwrap())
.spawn()
.expect("next_slide process call failed");
} else {
println!("pretend linux is sending prosenter next: {}", self.hotkeys["general"]["clicker_backward"].as_str().unwrap())
println!("pretend linux is sending media pause")
};
}
}
}
#[test]
fn hotkeys() {
use std::io::Read;
@ -139,10 +232,10 @@ fn hotkeys() {
hotkeys: settings_json,
};
hk.change_scene(Scenes::Augmented, Some(SubScenes::CameraDefault));
hk.next_slide();
hk.prev_slide();
hk.next_slide(false);
hk.prev_slide(false);
hk.send_obs("a hotkey");
hk.toggle_computer_sound(true);
hk.toggle_stream_sound(true);
hk.toggle_media_play_pause();
}
}

View file

@ -1,56 +1,86 @@
use std::time::{SystemTime};
use std::time::SystemTime;
use super::{stream_states::{state_update::StateUpdate, stream_states_class::StreamState, enums::{SlideChange, Scenes}}, external_interface::{Hotkeys}};
use super::{
external_interface::Hotkeys,
stream_states::{
scenes::{Scenes, SlideChange},
state_update::StateUpdate,
stream_state::StreamState,
},
};
pub trait MessageHandler { //the first one goes to socket, the second propogates
fn handle_update(&mut self, update: StateUpdate, hotkey_handler: &Hotkeys)
-> (Option<StateUpdate>, Option<Vec<StateUpdate>>);
pub trait MessageHandler {
//the first one goes to socket, the second propogates
fn handle_update(
&mut self,
update: StateUpdate,
hotkey_handler: &Hotkeys,
) -> (Option<StateUpdate>, Option<Vec<StateUpdate>>);
fn get_states(&self) -> StreamState;
fn tick(&mut self) -> (Option<StateUpdate>, Option<StateUpdate>);
fn pause_timer(&mut self, do_pause: bool) -> (Option<StateUpdate>, Option<Vec<StateUpdate>>);
fn tick(&mut self) -> Vec<StateUpdate>;
}
impl MessageHandler for StreamState {
fn handle_update(&mut self, update: StateUpdate, hotkey_handler: &Hotkeys)
-> (Option<StateUpdate>, Option<Vec<StateUpdate>>) {
if update != StateUpdate::UpdateClient && update != StateUpdate::ChangeSlide(SlideChange::Next) &&
update != StateUpdate::ChangeSlide(SlideChange::Previous){
fn handle_update(
&mut self,
update: StateUpdate,
hotkey_handler: &Hotkeys,
) -> (Option<StateUpdate>, Option<Vec<StateUpdate>>) {
if update != StateUpdate::UpdateClient
&& update != StateUpdate::ChangeSlide(SlideChange::NextApp)
&& update != StateUpdate::ChangeSlide(SlideChange::PreviousApp)
&& update != StateUpdate::ChangeSlide(SlideChange::PreviousHotkey)
&& update != StateUpdate::ChangeSlide(SlideChange::NextHotkey)
{
self.update(update.clone());
}
if self.debug_mode {
return (None, None)
return (None, None);
}
match update {
StateUpdate::ChangeSlide(direction) => {
if self.timer_can_run {
self.timer_finished = false;
self.timer_start = SystemTime::now();
}
match direction {
SlideChange::Next => {
hotkey_handler.next_slide();
},
SlideChange::Previous => {
hotkey_handler.prev_slide();
SlideChange::NextHotkey => {
hotkey_handler.next_slide(true);
}
SlideChange::NextApp => {
hotkey_handler.next_slide(false);
}
SlideChange::PreviousHotkey => {
hotkey_handler.prev_slide(true);
}
SlideChange::PreviousApp => {
hotkey_handler.prev_slide(false);
}
}
if self.change_scene_on_change_slide_hotkey {
if self.change_scene_on_slide_hotkey {
if self.timer_can_run {
self.timer_finished = false;
self.timer_start = SystemTime::now();
}
let mut instructions = Vec::new();
instructions.push(StateUpdate::Scene(Scenes::Screen));
return (None, Some(instructions))
} else {return (None, None)}
return (None, Some(instructions));
} else {
return (None, None);
}
}
StateUpdate::ChangeSceneOnChangeSlide(value) => {
self.change_scene_on_slide_hotkey = value;
return (Some(update), None);
}
StateUpdate::ChangeSceneOnChangeSlide(value) => {self.change_scene_on_change_slide_hotkey = value; return (Some(update), None)},
StateUpdate::SceneIsAugmented(value) => {
if value {
let mut instructions = Vec::new();
instructions.push(StateUpdate::ChangeSceneOnChangeSlide(false));
instructions.push(StateUpdate::Scene(Scenes::Augmented));
instructions.push(StateUpdate::TimerCanRun(false));
return (Some(update), Some(instructions))
return (Some(update), Some(instructions));
} else {
let mut instructions = Vec::new();
instructions.push(StateUpdate::Scene(Scenes::Camera));
@ -58,95 +88,195 @@ impl MessageHandler for StreamState {
instructions.push(StateUpdate::TimerCanRun(true));
return (Some(update), Some(instructions));
}
},
}
StateUpdate::TimerCanRun(value) => {
if self.timer_paused_length.is_some() {
return (None, Some(vec![StateUpdate::PauseTimer(false)]));
}
self.timer_can_run = value;
self.timer_start = SystemTime::now();
if value {
let mut instruction = Vec::new();
instruction.push(StateUpdate::TimerText(String::from("0.0")));
return (Some(update), Some(instruction))
return (Some(update), Some(instruction));
} else {
return (Some(update), None);
}
}
StateUpdate::TimerLength(value) => {self.timer_length = value; return (Some(update), None)},
StateUpdate::TimerText(value) => {self.timer_text = value.clone(); return (Some(StateUpdate::TimerText(value)), None)},
StateUpdate::SubScene(value) => {
if value.get_type() == Scenes::Camera {
self.camera_sub_scene = value;
if self.current_scene == Scenes::Camera {
hotkey_handler.change_scene(Scenes::Camera, Some(self.camera_sub_scene));
}
return (Some(update), None)
} else if value.get_type() == Scenes::Screen {
self.screen_sub_scene = value;
if self.current_scene == Scenes::Screen {
hotkey_handler.change_scene(Scenes::Screen, Some(self.screen_sub_scene));
}
return (Some(update), None)
}
},
StateUpdate::Scene(value) => {
self.current_scene = value;
if value == Scenes::Screen {
self.timer_start = SystemTime::now();
self.timer_finished = false;
} else {
self.timer_finished = true;
}
match self.current_scene {
Scenes::Camera => {
hotkey_handler.change_scene(Scenes::Camera, Some(self.camera_sub_scene));
},
Scenes::Screen => {
hotkey_handler.change_scene(Scenes::Screen, Some(self.screen_sub_scene));
},
Scenes::Augmented => {
hotkey_handler.change_scene(Scenes::Augmented, None);
}
}
StateUpdate::PauseTimer(value) => return self.pause_timer(value),
StateUpdate::TimerLength(value) => {
self.timer_length = value;
return (Some(update), None);
},
StateUpdate::StreamSoundToggleOn(value) => {hotkey_handler.toggle_stream_sound(value); return (Some(update), None)},
StateUpdate::ToggleComputerSoundOn(value) => {hotkey_handler.toggle_computer_sound(!value); return (Some(StateUpdate::ToggleComputerSoundOn(!value)), None)},
StateUpdate::ComputerMediaDoPause => {hotkey_handler.toggle_media_play_pause(); return (Some(update), None)},
StateUpdate::UpdateClient => {},
StateUpdate::StreamRunning(_) => {},
}
StateUpdate::TimerText(value) => {
self.timer_text = value.clone();
return (Some(StateUpdate::TimerText(value)), None);
}
StateUpdate::SubScene(value) => {
if value.get_type().is_camera() {
if self.current_scene.is_camera() {
hotkey_handler.change_scene(Scenes::Camera, Some(value));
}
self.camera_sub_scene = value;
return (Some(update), None);
} else if value.get_type().is_screen() {
if self.current_scene.is_screen() {
hotkey_handler.change_scene(Scenes::Screen, Some(value));
}
self.screen_sub_scene = value;
return (Some(update), None);
}
}
StateUpdate::Scene(value) => {
println!("handling scene: {:?}", value);
let mut instruction = None;
if self.current_scene != value {
match value {
Scenes::Camera => {
hotkey_handler
.change_scene(Scenes::Camera, Some(self.camera_sub_scene));
if self.timer_paused_length.is_none() {
instruction = Some(vec![StateUpdate::TimerText("0.0".to_string())]);
}
self.timer_finished = true;
}
Scenes::Screen => {
hotkey_handler
.change_scene(Scenes::Screen, Some(self.screen_sub_scene));
self.timer_start = SystemTime::now();
self.timer_finished = false;
}
Scenes::Augmented => {
hotkey_handler.change_scene(Scenes::Augmented, None);
self.timer_finished = true;
}
}
}
// if the current scene was tapped again
else {
// current scene can only be the same as value, and timer is paused
if value.is_screen() && self.timer_paused_length.is_some() {
instruction = Some(vec![StateUpdate::PauseTimer(false)]);
}
}
self.current_scene = value;
return (Some(update), instruction);
}
StateUpdate::StreamSoundToggleOn(value) => {
hotkey_handler.toggle_stream_sound(value);
return (Some(update), None);
}
StateUpdate::ToggleComputerSoundOn(value) => {
hotkey_handler.toggle_computer_sound(!value);
return (Some(StateUpdate::ToggleComputerSoundOn(!value)), None);
}
StateUpdate::ComputerMediaDoPause => {
hotkey_handler.toggle_media_play_pause();
return (Some(update), None);
}
StateUpdate::UpdateClient => {}
StateUpdate::StreamRunning(_) => {}
//_ => {}
}
(None, None)
}
fn tick(&mut self) -> (Option<StateUpdate>, Option<StateUpdate>) {
fn pause_timer(&mut self, do_pause: bool) -> (Option<StateUpdate>, Option<Vec<StateUpdate>>) {
let output: StateUpdate;
let mut instruction: Option<Vec<StateUpdate>> = None;
// if do pause,
if do_pause {
// if camera scene, don't allow it!
if self.current_scene.is_camera() {
return (None, None);
}
// stop tick from running,
self.timer_can_run = false;
// get the amount of time left on the clock
let time_left: u16;
match self.timer_start.elapsed() {
Err(_) => time_left = 0,
Ok(change) => {
// take the duration left, multiply it by 10 to save the last decimal,
// then drop the rest of the digits with .round()
time_left = ((self.timer_length - change.as_secs_f32()) * 10.0).round() as u16;
}
}
self.timer_paused_length = Some(time_left);
// (Send to socket, process another instruction)
// send the pause singal to the socket, and update the timer text (dividing by 10 to return the last digit)
return (
Some(StateUpdate::PauseTimer(true)),
Some(vec![StateUpdate::TimerText(format!(
"{:.1}",
time_left as f32 / 10.0
))]),
);
} else {
// if start timer from pause
// enable tick()
self.timer_can_run = true;
// Some fancy check to not have to use a match statement. The 'expect' should never be called, worry if it does
let timer_paused_length: u16 = self
.timer_paused_length
.or(Some(0))
.expect("timer_paused 'Some' unwrap somehow failed");
// if camera scene, don't reset the time_start
if self.current_scene.is_camera() {
instruction = Some(vec![StateUpdate::TimerText("0.0".to_string())]);
self.timer_start += std::time::Duration::from_secs(self.timer_length as u64);
} else {
// update timer_start, taking into account the amount of time already run
self.timer_start = SystemTime::now()
- std::time::Duration::from_millis(
// first get the decimal back from timer_paused_length, get the amount of time already run
// then convert that to milliseconds, then from f32 to u64
((self.timer_length - (timer_paused_length as f32 / 10.0)) * 1000.0) as u64,
);
}
// Clear the paused time
self.timer_paused_length = None;
output = StateUpdate::PauseTimer(false);
}
return (Some(output), instruction);
}
fn tick(&mut self) -> Vec<StateUpdate> {
let mut instructions = Vec::new();
if self.timer_finished == false && self.timer_can_run == true {
let change = self.timer_start.elapsed();
match change {
Err(_) => {(None, None)},
match self.timer_start.elapsed() {
Err(_) => {}
Ok(change) => {
if change.as_secs_f32() >= self.timer_length {
self.timer_finished = true;
(Some(StateUpdate::TimerText(String::from("0.0"))),
Some(StateUpdate::Scene(Scenes::Camera)))
instructions.push(StateUpdate::TimerText(String::from("0.0")));
instructions.push(StateUpdate::Scene(Scenes::Camera));
} else {
(Some(StateUpdate::TimerText(
format!("{:.1}", self.timer_length - ((change.as_secs_f32() * 10.0).round() / 10.0))
)), None)
instructions.push(StateUpdate::TimerText(format!(
"{:.1}",
self.timer_length - ((change.as_secs_f32() * 10.0).round() / 10.0)
)));
}
}
}
} else {
(None, None)
}
instructions
}
fn get_states(&self) -> StreamState{
fn get_states(&self) -> StreamState {
self.clone()
}
}
#[test]
@ -155,8 +285,8 @@ fn test_tick_1() {
state.timer_finished = false;
state.tick();
std::thread::sleep(std::time::Duration::from_millis(1000));
let update = state.tick();
state.update(update.0.unwrap());
let mut update = state.tick();
state.update(update.pop().unwrap());
assert_eq!(state.timer_text, "14.0");
}
@ -166,8 +296,8 @@ fn test_tick_one_half() {
state.timer_finished = false;
state.tick();
std::thread::sleep(std::time::Duration::from_millis(500));
let update = state.tick();
state.update(update.0.unwrap());
let mut update = state.tick();
state.update(update.pop().unwrap());
assert_eq!(state.timer_text, "14.5");
}
@ -178,7 +308,7 @@ fn test_tick_10() {
state.timer_finished = false;
state.tick();
std::thread::sleep(std::time::Duration::from_millis(10000));
let update = state.tick();
state.update(update.0.unwrap());
let mut update = state.tick();
state.update(update.pop().unwrap());
assert_eq!(state.timer_text, "5.0");
}
}

View file

@ -1,10 +1,10 @@
pub mod external_interface;
pub mod message_handler;
pub mod socket_handler;
pub mod external_interface;
pub mod tray_icon;
pub mod stream_states {
pub mod stream_states_class;
pub mod scenes;
pub mod state_update;
pub mod enums;
}
pub mod stream_state;
}

View file

@ -1,96 +1,111 @@
use workctl::sync_flag;
use std::net::{TcpListener, TcpStream, Shutdown};
use crossbeam_channel::Sender;
use std::io::{Read, Write};
use std::sync::{Mutex, Arc};
use crossbeam_channel::{Sender};
use std::net::{Shutdown, TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Duration;
use workctl::sync_flag;
pub struct Socket{
pub struct Socket {
socket_txs: Arc<Mutex<Vec<Arc<TcpStream>>>>,
stop_listener_flag: sync_flag::SyncFlagTx,
handle_connections_join_handle: Option<JoinHandle<()>>,
pub has_closed: workctl::sync_flag::SyncFlagRx,
}
impl Socket {
pub fn make_listener(address: &str) -> TcpListener {
TcpListener::bind(address).unwrap()
}
pub fn handle_connections(listener: TcpListener, messenger_tx: Sender<String>) -> Self {
let (mut has_closed_tx, has_closed_rx) = sync_flag::new_syncflag(false);
let (tx, thread_stop_flag) = sync_flag::new_syncflag(true);
let socket_streams = Arc::new(Mutex::new(vec![]));
let thread_owned_streams = Arc::clone(&socket_streams);
println!("initializing socket connection handling thread");
let handle = thread::spawn(move || {
listener.set_nonblocking(true).unwrap();
let mut service_sockets: Vec<Arc<TcpStream>> = Vec::new();
while thread_stop_flag.get() {
for (strm, _addr) in listener.accept() {
//create thread-passable pointer of current socket stream
let stream = Arc::new(strm);
//get lock on list of thread-passable pointers
for (s, _addr) in listener.accept() {
s.set_nonblocking(true).unwrap();
let stream = Arc::new(s);
let mut streams = thread_owned_streams.lock().unwrap();
streams.push(Arc::clone(&stream));
//pass off a clone of the thread-passable pointer
service_sockets.push(Arc::clone(&stream));
drop(streams);
Socket::handle_client(Arc::clone(&stream), messenger_tx.clone(), thread_stop_flag.clone());
}
Socket::service_clients(&mut service_sockets, messenger_tx.clone());
thread::sleep(Duration::from_millis(100));
}
has_closed_tx.set(true);
println!("closed socket connection handling thread");
drop(listener);
});
Socket {
socket_txs: socket_streams,
stop_listener_flag: tx,
handle_connections_join_handle: Some(handle),
has_closed: has_closed_rx
}
}
pub fn handle_client(stream: Arc<TcpStream>, update_tx: Sender<String>, program_shutdown_flag: sync_flag::SyncFlagRx) {
pub fn service_clients(streams: &mut Vec<Arc<TcpStream>>, update_tx: Sender<String>) {
let mut buffer = [0; 1024];
stream.set_read_timeout(Some(Duration::from_millis(10))).expect("Could not set a read timeout");
while program_shutdown_flag.get() {
match stream.as_ref().read(&mut buffer) {
Err(_) => {},
Ok(read_size) => {
//Tcp is supposed to have a 0 byte read if closed by client
if read_size == 0 || !program_shutdown_flag.get() {
break;
} else {
let output = String::from_utf8_lossy(&buffer[0..read_size]);
update_tx.send(output.into_owned()).unwrap();
}
let mut remove = Vec::new();
for i in 0..streams.len() {
let resp = streams.get(i).as_ref().unwrap().as_ref().read(&mut buffer);
if resp.is_ok() {
let msg_len = resp.unwrap();
if msg_len == 0 {
remove.push(i);
} else {
update_tx
.send(String::from_utf8_lossy(&buffer[0..msg_len]).into_owned())
.unwrap();
}
}
}
stream.shutdown(Shutdown::Both).unwrap();
for i in remove.iter() {
streams.get(*i).unwrap().shutdown(Shutdown::Both).unwrap();
streams.remove(*i);
}
}
pub fn close(&mut self) {
self.stop_listener_flag.set(false);
self.handle_connections_join_handle
.take().expect("Called on not running thread")
.join().expect("Could not join thread");
.take()
.expect("Called on not running thread")
.join()
.expect("Could not join thread");
}
pub fn send(&self, message: String) {
let mut streams = self.socket_txs.lock().unwrap();
if streams.len() == 0 {return}
for i in 0..streams.len(){
let mut tx = streams.get(i).unwrap().as_ref();
match tx.write(message.clone().as_bytes()) {
Err(_) => {streams.remove(i); println!("removed a socket"); continue;},
Ok(_) => {},
let mut removes = Vec::<usize>::new();
if streams.len() == 0 {
return;
}
for i in 0..streams.len() {
match streams.get(i) {
None => {
removes.push(i);
}
Some(strm) => {
let mut tx = strm.as_ref();
match tx.write(message.clone().as_bytes()) {
Err(_) => removes.push(i),
Ok(_) => {
tx.write(b"\n").unwrap();
tx.flush().unwrap();
}
}
}
}
tx.write(b"\n").unwrap();
tx.flush().unwrap();
}
for i in removes.iter() {
streams.remove(*i);
}
}
}
}

View file

@ -56,20 +56,24 @@ impl Scenes {
Scenes::Augmented => {String::from_str("Augmented").unwrap()},
}
}
pub fn is_camera(&self) -> bool {
match self { Scenes::Camera => true, _ => false }
}
pub fn is_screen(&self) -> bool {
match self { Scenes::Screen => true, _ => false }
}
pub fn is_augmeted(&self) -> bool {
match self {Scenes::Augmented => true, _ => false }
}
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum SlideChange {
Next,
Previous,
NextApp,
PreviousApp,
NextHotkey,
PreviousHotkey,
}
impl SlideChange {
pub fn to_string(&self) -> String {
match self {
SlideChange::Next => {String::from_str("Next_Slide").unwrap()},
SlideChange::Previous => {String::from_str("Prev_Slide").unwrap()},
}
}
}

View file

@ -1,5 +1,5 @@
use super::enums::{SubScenes, Scenes, SlideChange};
use super::scenes::{SubScenes, Scenes, SlideChange};
use serde_json::Value;
@ -12,6 +12,7 @@ pub enum StateUpdate {
ChangeSceneOnChangeSlide(bool),
SceneIsAugmented(bool),
TimerCanRun(bool),
PauseTimer(bool),
TimerLength(f32),
TimerText(String),
SubScene(SubScenes),
@ -22,9 +23,8 @@ pub enum StateUpdate {
impl StateUpdate {
pub fn json_to_state_update(incoming_json: Value) -> Self {
let message_type = &incoming_json["type"];
match message_type.as_str().unwrap() {
match incoming_json["type"].as_str().unwrap() {
"update" => {
let value = &incoming_json["update"];
match value.as_str().unwrap() {
@ -73,9 +73,17 @@ impl StateUpdate {
"Stream_Running" => {StateUpdate::StreamRunning(string_to_bool(incoming_json["data"].as_str().unwrap()))}
"Next_Slide" => {StateUpdate::ChangeSlide(SlideChange::Next)},
"Prev_Slide" => {StateUpdate::ChangeSlide(SlideChange::Previous)}
"Next_Slide" => {
if incoming_json["data"] == "hotkey" {StateUpdate::ChangeSlide(SlideChange::NextHotkey)}
else {StateUpdate::ChangeSlide(SlideChange::NextApp)}},
"Prev_Slide" => {
if incoming_json["data"] == "hotkey" {StateUpdate::ChangeSlide(SlideChange::PreviousHotkey)}
else {StateUpdate::ChangeSlide(SlideChange::PreviousApp)}}
//Unimplemented
"Pause_Timer" => {
if incoming_json["data"] == "true" {StateUpdate::PauseTimer(true)}
else {StateUpdate::PauseTimer(false)}
}
_ => {panic!("trying to use a button type I don't know!: {}", value)}
}
},
@ -111,10 +119,14 @@ impl StateUpdate {
("Toggle_Computer_Volume", "".to_string())},
StateUpdate::ChangeSlide(value) => {
match value {
SlideChange::Next => {("Next_Slide", "".to_string())},
SlideChange::Previous => {("Prev_Slide", "".to_string())},
SlideChange::NextApp => {("Next_Slide", "".to_string())},
SlideChange::NextHotkey => {("Next_Slide", "hotkey".to_string())},
SlideChange::PreviousApp => {("Prev_Slide", "".to_string())},
SlideChange::PreviousHotkey => {("Prev_Slide", "hotkey".to_string())},
}
},
StateUpdate::PauseTimer(value) => {
("Pause_Timer", value.to_string())}
StateUpdate::UpdateClient => {
("all", "".to_string())
},

View file

@ -0,0 +1,74 @@
use std::time::SystemTime;
use super::scenes::{SubScenes, Scenes};
use super::state_update::StateUpdate;
#[derive(Debug, Clone)]
pub struct StreamState {
pub stream_running: bool,
pub stream_is_muted: bool,
pub computer_sound_is_on: bool,
pub change_scene_on_slide_hotkey: bool,
pub scene_is_augmented: bool,
pub timer_can_run: bool,
pub timer_length: f32,
pub timer_text: String,
pub timer_start: SystemTime,
pub timer_finished: bool,
pub timer_paused_length: Option<u16>,
pub current_scene: Scenes,
pub camera_sub_scene: SubScenes,
pub screen_sub_scene: SubScenes,
pub debug_mode: bool,
}
impl Default for StreamState {
fn default() -> Self {
StreamState {
stream_running: false,
stream_is_muted: false,
computer_sound_is_on: true,
change_scene_on_slide_hotkey: true,
scene_is_augmented: false,
timer_can_run: true,
timer_length: 15.0,
timer_text: String::from("0.0"),
timer_start: SystemTime::now(),
timer_finished: true,
timer_paused_length: None,
current_scene: Scenes::Camera,
camera_sub_scene: SubScenes::CameraDefault,
screen_sub_scene: SubScenes::ScreenDefault,
debug_mode: false,
}
}
}
impl StreamState {
pub fn new() -> Self {
StreamState{..Default::default()}
}
pub fn update(&mut self, update: StateUpdate) {
match update {
StateUpdate::StreamRunning(new_val) => self.stream_running = new_val,
StateUpdate::StreamSoundToggleOn(new_val) => self.stream_is_muted = new_val,
StateUpdate::ToggleComputerSoundOn(new_val) => self.computer_sound_is_on = new_val,
StateUpdate::ChangeSceneOnChangeSlide(new_val) => self.change_scene_on_slide_hotkey = new_val,
StateUpdate::TimerCanRun(new_val) => self.timer_can_run = new_val,
StateUpdate::TimerLength(new_val) => self.timer_length = new_val,
StateUpdate::TimerText(new_val) => self.timer_text = new_val,
StateUpdate::SceneIsAugmented(new_val) => self.scene_is_augmented = new_val,
StateUpdate::ChangeSlide(_value) => panic!("Stream_states_class is not supposed to get this update type"),
_ => {}
}
}
}

View file

@ -1,106 +0,0 @@
use std::time::SystemTime;
use super::enums::{SubScenes, Scenes};
use super::state_update::StateUpdate;
#[derive(Debug, Clone)]
pub struct StreamState {
pub stream_running: bool,
pub stream_is_muted: bool,
pub computer_sound_is_on: bool,
pub change_scene_on_change_slide_hotkey: bool,
pub scene_is_augmented: bool,
pub timer_can_run: bool,
pub timer_length: f32,
pub timer_text: String,
pub timer_start: SystemTime,
pub timer_finished: bool,
pub current_scene: Scenes,
pub camera_sub_scene: SubScenes,
pub screen_sub_scene: SubScenes,
pub debug_mode: bool,
}
impl Default for StreamState {
fn default() -> Self {
StreamState {
stream_running: false,
stream_is_muted: false,
computer_sound_is_on: true,
change_scene_on_change_slide_hotkey: true,
scene_is_augmented: false,
timer_can_run: true,
timer_length: 15.0,
timer_text: String::from("0.0"),
timer_start: SystemTime::now(),
timer_finished: true,
current_scene: Scenes::Camera,
camera_sub_scene: SubScenes::CameraDefault,
screen_sub_scene: SubScenes::ScreenDefault,
debug_mode: false,
}
}
}
impl StreamState {
pub fn new() -> Self {
StreamState{..Default::default()}
}
pub fn update(&mut self, update: StateUpdate) {
match update {
StateUpdate::StreamRunning(new_val) => {self.stream_running = new_val;},
StateUpdate::StreamSoundToggleOn(new_val) => {self.stream_is_muted = new_val;},
StateUpdate::ToggleComputerSoundOn(new_val) => {self.computer_sound_is_on = new_val;},
StateUpdate::ChangeSceneOnChangeSlide(new_val) => {self.change_scene_on_change_slide_hotkey = new_val;},
StateUpdate::TimerCanRun(new_val) => {self.timer_can_run = new_val;},
StateUpdate::TimerLength(new_val) => {self.timer_length = new_val;},
StateUpdate::TimerText(new_val) => {self.timer_text = new_val;},
StateUpdate::Scene(new_val) => {self.change_scene(&new_val)},
StateUpdate::SubScene(new_val) => {self.change_sub_scene(&new_val)},
StateUpdate::SceneIsAugmented(new_val) => {
self.scene_is_augmented = new_val;
self.change_scene(&Scenes::Augmented)},
StateUpdate::ComputerMediaDoPause => {},
StateUpdate::ChangeSlide(_value) => {panic!("Stream_states_class is not supposed to get this update type");},
StateUpdate::UpdateClient => {},
}
}
pub fn change_scene(&mut self, scene: &Scenes) {
match scene {
Scenes::Augmented => {self.current_scene = *scene;}
Scenes::Camera => {self.current_scene = *scene},
Scenes::Screen => {self.current_scene = *scene},
}
}
pub fn change_sub_scene(&mut self, scene: &SubScenes) {
match scene {
SubScenes::CameraDefault | SubScenes::CameraWithUpperRight |
SubScenes::CameraWithLargeUpperRight | SubScenes::CameraWithLowerRight
=> {StreamState::set_camera_scene(self, scene)},
SubScenes::ScreenDefault | SubScenes::ScreenWithUpperRight |
SubScenes::ScreenWithLowerRight
=> {StreamState::set_screen_scene(self, scene)},
}
}
fn set_camera_scene(&mut self, scene: &SubScenes) {
self.camera_sub_scene = scene.clone();
self.current_scene = Scenes::Camera;
}
fn set_screen_scene(&mut self, scene: &SubScenes) {
self.screen_sub_scene = scene.clone();
self.current_scene = Scenes::Screen;
}
}

131
src/modules/tray_icon.rs Normal file
View file

@ -0,0 +1,131 @@
use core::mem::MaybeUninit;
use std::time::Duration;
use crossbeam_channel::Receiver;
use trayicon::*;
use winapi::um::winuser;
use workctl::sync_flag::SyncFlagRx;
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Events {
ClickTrayIcon,
DoubleClickTrayIcon,
Exit,
Item1,
Item2,
Item3,
Item4,
CheckItem1,
SubItem1,
SubItem2,
SubItem3,
}
pub struct TrayIcon {
tray_icon: trayicon::TrayIcon<Events>,
pub message_channel: crossbeam_channel::Receiver<Events>,
}
impl TrayIcon {
pub fn setup(icon: &[u8]) -> TrayIcon {
let (s, r) = crossbeam_channel::unbounded();
let icon1 = include_bytes!("./../icon1.ico");
let icon2 = include_bytes!("./../icon2.ico");
let second_icon = Icon::from_buffer(icon2, None, None).unwrap();
let first_icon = Icon::from_buffer(icon1, None, None).unwrap();
// Needlessly complicated tray icon with all the whistles and bells
let tray_icon = TrayIconBuilder::new()
.sender_crossbeam(s)
.icon_from_buffer(icon1)
.tooltip("Cool Tray 👀 Icon")
.on_click(Events::ClickTrayIcon)
.on_double_click(Events::DoubleClickTrayIcon)
.menu(
MenuBuilder::new()
.item("Item 3 Replace Menu 👍", Events::Item3)
.item("Item 2 Change Icon Green", Events::Item2)
.item("Item 1 Change Icon Red", Events::Item1)
.separator()
.checkable("This is checkable", true, Events::CheckItem1)
.submenu(
"Sub Menu",
MenuBuilder::new()
.item("Sub item 1", Events::SubItem1)
.item("Sub Item 2", Events::SubItem2)
.item("Sub Item 3", Events::SubItem3),
)
.with(MenuItem::Item {
name: "Item Disabled".into(),
disabled: true, // Disabled entry example
id: Events::Item4,
icon: None,
})
.separator()
.item("E&xit", Events::Exit),
)
.build()
.unwrap();
TrayIcon {
tray_icon,
message_channel: r,
}
}
pub fn check_tray_icon_messages(&self) {
unsafe {
let mut msg = MaybeUninit::uninit();
let bret = winuser::PeekMessageA(msg.as_mut_ptr(), 0 as _, 0, 0, 1);
if bret > 0 {
winuser::TranslateMessage(msg.as_ptr());
winuser::DispatchMessageA(msg.as_ptr());
} else {
return;
}
}
}
pub fn handle_tray_messages(message_channel: &Receiver<Events>) {
let message = message_channel.recv_timeout(Duration::from_millis(10));
match message {
Err(_) => return,
Ok(message) => {
match message {
Events::DoubleClickTrayIcon => {
println!("Double click");
}
Events::ClickTrayIcon => {
println!("Single click");
}
Events::Exit => {
println!("Please exit");
todo!()
}
Events::Item1 => {
println!("item1");
//tray_icon.set_icon(&second_icon).unwrap();
}
Events::Item2 => {
println!("item2");
//tray_icon.set_icon(&first_icon).unwrap();
}
Events::Item3 => {
println!("item3");
/*tray_icon
.set_menu(
&MenuBuilder::new()
.item("New menu item", Events::Item1)
.item("Exit", Events::Exit),
)
.unwrap();*/
}
e => {
println!("{:?}", e);
}
}
}
}
}
}

View file

@ -1,7 +1,8 @@
use workctl::sync_flag;
use crate::modules::{stream_states::{ stream_states_class::StreamState, enums::Scenes, state_update::StateUpdate}};
use crate::modules::stream_states::{
scenes::Scenes, state_update::StateUpdate, stream_state::StreamState,
};
#[test]
fn it_works() {
@ -11,13 +12,11 @@ fn it_works() {
#[test]
fn can_make_ctrl_c_handler() {
let (control_c_flag_tx_1, _control_c_called_flag_rx_1) = sync_flag::new_syncflag(false);
let (control_c_flag_tx, _control_c_called_flag_rx) = sync_flag::new_syncflag(false);
crate::setup_control_c(control_c_flag_tx, control_c_flag_tx_1);
crate::setup_control_c();
drop(_control_c_called_flag_rx);
}
#[test]
fn test_updating_state_from_state_update() {
let mut state = StreamState::new();

View file

@ -1,10 +1,13 @@
use crate::modules::{message_handler::{MessageHandler}, stream_states::{state_update::StateUpdate, stream_states_class::StreamState}, external_interface::Hotkeys};
use crate::modules::{
external_interface::Hotkeys,
message_handler::MessageHandler,
stream_states::{state_update::StateUpdate, stream_state::StreamState},
};
#[test]
fn does_stream_state_implement_message_handler() {
let hotkeys = Hotkeys {
hotkeys: serde_json::Value::Null
hotkeys: serde_json::Value::Null,
};
let mut state = StreamState::new();
state.debug_mode = true;

View file

@ -1,12 +1,11 @@
#[cfg(test)]
pub mod main_tests;
#[cfg(test)]
pub mod stream_states_tests;
#[cfg(test)]
pub mod message_handler_tests;
#[cfg(test)]
pub mod socket_handler_tests;
#[cfg(test)]
pub mod state_update_tests;
pub mod state_update_tests;
#[cfg(test)]
pub mod stream_states_tests;

View file

@ -1,12 +1,12 @@
use crossbeam_channel::unbounded;
use std::io::{Write};
use std::io::Write;
use std::thread;
use std::time::Duration;
use crate::modules::socket_handler::Socket;
#[test]
fn can_make_socket_listener(){
fn can_make_socket_listener() {
let listener = Socket::make_listener("localhost:5001");
drop(listener);
}
@ -45,7 +45,7 @@ fn can_handle_messages() {
let message = rx_1.recv().unwrap();
assert_eq!(message, String::from("this is a test"));
socket.close();
}
@ -66,11 +66,10 @@ fn can_handle_delayed_messages() {
let message = rx_1.recv().unwrap();
println!("{}", message);
assert_eq!(message, String::from("this is a test1\n"));
let message = rx_1.recv().unwrap();
println!("{}", message);
assert_eq!(message, String::from("this is a test3\n"));
socket.close();
}

View file

@ -1,36 +1,79 @@
use crate::modules::stream_states::{state_update::StateUpdate, enums::{Scenes, SubScenes, SlideChange}};
use crate::modules::stream_states::{
scenes::{Scenes, SlideChange, SubScenes},
state_update::StateUpdate,
};
#[test]
fn test_json_to_state_update() {
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene\", \"data\": \"Scene_Camera\"}"
).unwrap()), StateUpdate::Scene(Scenes::Camera));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene\", \"data\": \"Scene_Camera\"}"
)
.unwrap()
),
StateUpdate::Scene(Scenes::Camera)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene\", \"data\": \"Scene_Screen\"}"
).unwrap()), StateUpdate::Scene(Scenes::Screen));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene\", \"data\": \"Scene_Screen\"}"
)
.unwrap()
),
StateUpdate::Scene(Scenes::Screen)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene_Is_Augmented\", \"data\": \"true\"}"
).unwrap()), StateUpdate::SceneIsAugmented(true));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Scene_Is_Augmented\", \"data\": \"true\"}"
)
.unwrap()
),
StateUpdate::SceneIsAugmented(true)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Can_Run\", \"data\": \"true\"}"
).unwrap()), StateUpdate::TimerCanRun(true));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Can_Run\", \"data\": \"true\"}"
)
.unwrap()
),
StateUpdate::TimerCanRun(true)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Can_Run\", \"data\": \"false\"}"
).unwrap()), StateUpdate::TimerCanRun(false));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Change_With_Clicker\", \"data\": \"true\"}"
).unwrap()), StateUpdate::ChangeSceneOnChangeSlide(true));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Can_Run\", \"data\": \"false\"}"
)
.unwrap()
),
StateUpdate::TimerCanRun(false)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Change_With_Clicker\", \"data\": \"false\"}"
).unwrap()), StateUpdate::ChangeSceneOnChangeSlide(false));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Change_With_Clicker\", \"data\": \"true\"}"
)
.unwrap()
),
StateUpdate::ChangeSceneOnChangeSlide(true)
);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Change_With_Clicker\", \"data\": \"false\"}"
)
.unwrap()
),
StateUpdate::ChangeSceneOnChangeSlide(false)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Computer_Volume\", \"data\": \"true\"}"
@ -39,100 +82,252 @@ fn test_json_to_state_update() {
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Computer_Volume\", \"data\": \"false\"}"
).unwrap()), StateUpdate::ToggleComputerSoundOn(false));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Stream_Volume\", \"data\": \"true\"}"
).unwrap()), StateUpdate::StreamSoundToggleOn(true));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Stream_Volume\", \"data\": \"false\"}"
).unwrap()), StateUpdate::StreamSoundToggleOn(false));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Stream_Volume\", \"data\": \"true\"}"
)
.unwrap()
),
StateUpdate::StreamSoundToggleOn(true)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Media_Pause_Play\", \"data\": \"true\"}"
).unwrap()), StateUpdate::ComputerMediaDoPause);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Toggle_Stream_Volume\", \"data\": \"false\"}"
)
.unwrap()
),
StateUpdate::StreamSoundToggleOn(false)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_None\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::CameraDefault));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_Top_Right\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::CameraWithUpperRight));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Media_Pause_Play\", \"data\": \"true\"}"
)
.unwrap()
),
StateUpdate::ComputerMediaDoPause
);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_None\"}"
)
.unwrap()
),
StateUpdate::SubScene(SubScenes::CameraDefault)
);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_Top_Right\"}"
)
.unwrap()
),
StateUpdate::SubScene(SubScenes::CameraWithUpperRight)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_Bottom_Right\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::CameraWithLowerRight));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Camera_Bottom_Left\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::CameraWithLargeUpperRight));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Screen_None\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::ScreenDefault));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Screen_None\"}"
)
.unwrap()
),
StateUpdate::SubScene(SubScenes::ScreenDefault)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Screen_Top_Right\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::ScreenWithUpperRight));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\": \"Screen_Top_Right\"}"
)
.unwrap()
),
StateUpdate::SubScene(SubScenes::ScreenWithUpperRight)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"SubScene\", \"data\":\"Screen_Bottom_Right\"}"
).unwrap()), StateUpdate::SubScene(SubScenes::ScreenWithLowerRight));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Length\", \"data\": \"5.5\"}"
).unwrap()), StateUpdate::TimerLength(5.5));
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Next_Slide\"}"
).unwrap()), StateUpdate::ChangeSlide(SlideChange::Next));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Timer_Length\", \"data\": \"5.5\"}"
)
.unwrap()
),
StateUpdate::TimerLength(5.5)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\": \"Prev_Slide\"}"
).unwrap()), StateUpdate::ChangeSlide(SlideChange::Previous));
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str("{\"type\": \"update\", \"update\": \"Next_Slide\"}").unwrap()
),
StateUpdate::ChangeSlide(SlideChange::NextHotkey)
);
assert_eq!(StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"update\", \"update\":\"all\"}"
).unwrap()), StateUpdate::UpdateClient);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str("{\"type\": \"update\", \"update\": \"Prev_Slide\"}").unwrap()
),
StateUpdate::ChangeSlide(SlideChange::PreviousHotkey)
);
assert_eq!(
StateUpdate::json_to_state_update(
serde_json::from_str("{\"type\": \"update\", \"update\":\"all\"}").unwrap()
),
StateUpdate::UpdateClient
);
}
#[test]
#[should_panic]
fn test_json_to_state_update_fails() {
StateUpdate::json_to_state_update(serde_json::from_str(
"{\"type\": \"AnUnknownType\"}"
).unwrap());
StateUpdate::json_to_state_update(
serde_json::from_str("{\"type\": \"AnUnknownType\"}").unwrap(),
);
}
#[test]
fn test_state_update_to_json() {
//Note, this one needs to is dependant on test_json_to_update for correctedness
assert_eq!(StateUpdate::StreamRunning(true), (StateUpdate::json_to_state_update(StateUpdate::StreamRunning(true).to_json())));
assert_eq!(StateUpdate::StreamRunning(false), StateUpdate::json_to_state_update(StateUpdate::StreamRunning(false).to_json()));
assert_eq!(StateUpdate::StreamSoundToggleOn(true), StateUpdate::json_to_state_update(StateUpdate::StreamSoundToggleOn(true).to_json()));
assert_eq!(StateUpdate::StreamSoundToggleOn(false), StateUpdate::json_to_state_update(StateUpdate::StreamSoundToggleOn(false).to_json()));
assert_eq!(StateUpdate::ToggleComputerSoundOn(true), StateUpdate::json_to_state_update(StateUpdate::ToggleComputerSoundOn(true).to_json()));
assert_eq!(StateUpdate::ToggleComputerSoundOn(false), StateUpdate::json_to_state_update(StateUpdate::ToggleComputerSoundOn(false).to_json()));
assert_eq!(StateUpdate::ChangeSceneOnChangeSlide(true), StateUpdate::json_to_state_update(StateUpdate::ChangeSceneOnChangeSlide(true).to_json()));
assert_eq!(StateUpdate::ChangeSceneOnChangeSlide(false), StateUpdate::json_to_state_update(StateUpdate::ChangeSceneOnChangeSlide(false).to_json()));
assert_eq!(StateUpdate::SceneIsAugmented(true), StateUpdate::json_to_state_update(StateUpdate::SceneIsAugmented(true).to_json()));
assert_eq!(StateUpdate::SceneIsAugmented(false), StateUpdate::json_to_state_update(StateUpdate::SceneIsAugmented(false).to_json()));
assert_eq!(StateUpdate::TimerCanRun(true), StateUpdate::json_to_state_update(StateUpdate::TimerCanRun(true).to_json()));
assert_eq!(StateUpdate::TimerCanRun(false), StateUpdate::json_to_state_update(StateUpdate::TimerCanRun(false).to_json()));
assert_eq!(StateUpdate::TimerLength(17.5), StateUpdate::json_to_state_update(StateUpdate::TimerLength(17.5).to_json()));
assert_eq!(StateUpdate::TimerText(String::from("15.6")), StateUpdate::json_to_state_update(StateUpdate::TimerText(String::from("15.6")).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::CameraDefault), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::CameraDefault).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::CameraWithUpperRight), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::CameraWithUpperRight).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::CameraWithLowerRight), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::CameraWithLowerRight).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::CameraWithLargeUpperRight), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::CameraWithLargeUpperRight).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::ScreenDefault), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::ScreenDefault).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::ScreenWithUpperRight), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::ScreenWithUpperRight).to_json()));
assert_eq!(StateUpdate::SubScene(SubScenes::ScreenWithLowerRight), StateUpdate::json_to_state_update(StateUpdate::SubScene(SubScenes::ScreenWithLowerRight).to_json()));
assert_eq!(StateUpdate::Scene(Scenes::Camera), StateUpdate::json_to_state_update(StateUpdate::Scene(Scenes::Camera).to_json()));
assert_eq!(StateUpdate::Scene(Scenes::Screen), StateUpdate::json_to_state_update(StateUpdate::Scene(Scenes::Screen).to_json()));
assert_eq!(StateUpdate::ChangeSlide(SlideChange::Next), StateUpdate::json_to_state_update(StateUpdate::ChangeSlide(SlideChange::Next).to_json()));
assert_eq!(StateUpdate::ChangeSlide(SlideChange::Previous), StateUpdate::json_to_state_update(StateUpdate::ChangeSlide(SlideChange::Previous).to_json()));
assert_eq!(StateUpdate::UpdateClient, StateUpdate::json_to_state_update(StateUpdate::UpdateClient.to_json()));
}
assert_eq!(
StateUpdate::StreamRunning(true),
(StateUpdate::json_to_state_update(StateUpdate::StreamRunning(true).to_json()))
);
assert_eq!(
StateUpdate::StreamRunning(false),
StateUpdate::json_to_state_update(StateUpdate::StreamRunning(false).to_json())
);
assert_eq!(
StateUpdate::StreamSoundToggleOn(true),
StateUpdate::json_to_state_update(StateUpdate::StreamSoundToggleOn(true).to_json())
);
assert_eq!(
StateUpdate::StreamSoundToggleOn(false),
StateUpdate::json_to_state_update(StateUpdate::StreamSoundToggleOn(false).to_json())
);
assert_eq!(
StateUpdate::ToggleComputerSoundOn(true),
StateUpdate::json_to_state_update(StateUpdate::ToggleComputerSoundOn(true).to_json())
);
assert_eq!(
StateUpdate::ToggleComputerSoundOn(false),
StateUpdate::json_to_state_update(StateUpdate::ToggleComputerSoundOn(false).to_json())
);
assert_eq!(
StateUpdate::ChangeSceneOnChangeSlide(true),
StateUpdate::json_to_state_update(StateUpdate::ChangeSceneOnChangeSlide(true).to_json())
);
assert_eq!(
StateUpdate::ChangeSceneOnChangeSlide(false),
StateUpdate::json_to_state_update(StateUpdate::ChangeSceneOnChangeSlide(false).to_json())
);
assert_eq!(
StateUpdate::SceneIsAugmented(true),
StateUpdate::json_to_state_update(StateUpdate::SceneIsAugmented(true).to_json())
);
assert_eq!(
StateUpdate::SceneIsAugmented(false),
StateUpdate::json_to_state_update(StateUpdate::SceneIsAugmented(false).to_json())
);
assert_eq!(
StateUpdate::TimerCanRun(true),
StateUpdate::json_to_state_update(StateUpdate::TimerCanRun(true).to_json())
);
assert_eq!(
StateUpdate::TimerCanRun(false),
StateUpdate::json_to_state_update(StateUpdate::TimerCanRun(false).to_json())
);
assert_eq!(
StateUpdate::TimerLength(17.5),
StateUpdate::json_to_state_update(StateUpdate::TimerLength(17.5).to_json())
);
assert_eq!(
StateUpdate::TimerText(String::from("15.6")),
StateUpdate::json_to_state_update(StateUpdate::TimerText(String::from("15.6")).to_json())
);
assert_eq!(
StateUpdate::SubScene(SubScenes::CameraDefault),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::CameraDefault).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::CameraWithUpperRight),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::CameraWithUpperRight).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::CameraWithLowerRight),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::CameraWithLowerRight).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::CameraWithLargeUpperRight),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::CameraWithLargeUpperRight).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::ScreenDefault),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::ScreenDefault).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::ScreenWithUpperRight),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::ScreenWithUpperRight).to_json()
)
);
assert_eq!(
StateUpdate::SubScene(SubScenes::ScreenWithLowerRight),
StateUpdate::json_to_state_update(
StateUpdate::SubScene(SubScenes::ScreenWithLowerRight).to_json()
)
);
assert_eq!(
StateUpdate::Scene(Scenes::Camera),
StateUpdate::json_to_state_update(StateUpdate::Scene(Scenes::Camera).to_json())
);
assert_eq!(
StateUpdate::Scene(Scenes::Screen),
StateUpdate::json_to_state_update(StateUpdate::Scene(Scenes::Screen).to_json())
);
assert_eq!(
StateUpdate::ChangeSlide(SlideChange::NextHotkey),
StateUpdate::json_to_state_update(
StateUpdate::ChangeSlide(SlideChange::NextHotkey).to_json()
)
);
assert_eq!(
StateUpdate::ChangeSlide(SlideChange::PreviousHotkey),
StateUpdate::json_to_state_update(
StateUpdate::ChangeSlide(SlideChange::PreviousHotkey).to_json()
)
);
assert_eq!(
StateUpdate::UpdateClient,
StateUpdate::json_to_state_update(StateUpdate::UpdateClient.to_json())
);
}

View file

@ -8,18 +8,18 @@ use crate::modules::stream_states::state_update::StateUpdate;
fn has_all_enums() {
{
let members = [
s_s::enums::SubScenes::CameraDefault,
s_s::enums::SubScenes::CameraWithUpperRight,
s_s::enums::SubScenes::CameraWithLowerRight,
s_s::enums::SubScenes::CameraWithLargeUpperRight,
s_s::scenes::SubScenes::CameraDefault,
s_s::scenes::SubScenes::CameraWithUpperRight,
s_s::scenes::SubScenes::CameraWithLowerRight,
s_s::scenes::SubScenes::CameraWithLargeUpperRight,
];
assert_eq!(members.len(), 4);
}
{
let members = [
s_s::enums::SubScenes::ScreenDefault,
s_s::enums::SubScenes::ScreenWithUpperRight,
s_s::enums::SubScenes::ScreenWithLowerRight,
s_s::scenes::SubScenes::ScreenDefault,
s_s::scenes::SubScenes::ScreenWithUpperRight,
s_s::scenes::SubScenes::ScreenWithLowerRight,
];
assert_eq!(members.len(), 3);
}
@ -27,74 +27,136 @@ fn has_all_enums() {
#[test]
fn create_stream_states_class() {
let stream_state = s_s::stream_states_class::StreamState::new();
let stream_state = s_s::stream_state::StreamState::new();
assert_eq!(stream_state.stream_running, false);
assert_eq!(stream_state.stream_is_muted, false);
assert_eq!(stream_state.computer_sound_is_on, true);
assert_eq!(stream_state.change_scene_on_change_slide_hotkey, true);
assert_eq!(stream_state.change_scene_on_slide_hotkey, true);
assert_eq!(stream_state.scene_is_augmented, false);
assert_eq!(stream_state.timer_text, "0.0");
assert_eq!(stream_state.timer_length, 15.0);
assert_eq!(stream_state.timer_can_run, true);
assert_eq!(stream_state.current_scene, s_s::enums::Scenes::Camera);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraDefault);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
assert_eq!(stream_state.current_scene, s_s::scenes::Scenes::Camera);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraDefault
);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
}
#[test]
fn scene_correctness(){
let mut stream_state = s_s::stream_states_class::StreamState::new();
assert_eq!(stream_state.current_scene, s_s::enums::Scenes::Camera);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraDefault);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
fn scene_correctness() {
let mut stream_state = s_s::stream_state::StreamState::new();
assert_eq!(stream_state.current_scene, s_s::scenes::Scenes::Camera);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraDefault
);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::CameraWithUpperRight));
stream_state.update(StateUpdate::SubScene(
s_s::scenes::SubScenes::CameraWithUpperRight,
));
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithUpperRight);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithUpperRight
);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::CameraWithLargeUpperRight));
stream_state.update(StateUpdate::SubScene(
s_s::scenes::SubScenes::CameraWithLargeUpperRight,
));
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLargeUpperRight);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLargeUpperRight
);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::CameraWithLowerRight));
stream_state.update(StateUpdate::SubScene(
s_s::scenes::SubScenes::CameraWithLowerRight,
));
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLowerRight);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLowerRight
);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::ScreenDefault));
stream_state.update(StateUpdate::Scene(s_s::enums::Scenes::Screen));
assert_eq!(stream_state.current_scene, s_s::enums::Scenes::Screen);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenDefault);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLowerRight);
stream_state.update(StateUpdate::SubScene(s_s::scenes::SubScenes::ScreenDefault));
stream_state.update(StateUpdate::Scene(s_s::scenes::Scenes::Screen));
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::ScreenWithLowerRight));
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenWithLowerRight);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLowerRight);
assert_eq!(stream_state.current_scene, s_s::scenes::Scenes::Screen);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenDefault
);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLowerRight
);
stream_state.update(StateUpdate::SubScene(s_s::enums::SubScenes::ScreenWithUpperRight));
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenWithUpperRight);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLowerRight);
stream_state.update(StateUpdate::SubScene(
s_s::scenes::SubScenes::ScreenWithLowerRight,
));
stream_state.update(StateUpdate::Scene(s_s::enums::Scenes::Augmented));
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenWithLowerRight
);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLowerRight
);
assert_eq!(stream_state.current_scene, s_s::enums::Scenes::Augmented);
assert_eq!(stream_state.screen_sub_scene, s_s::enums::SubScenes::ScreenWithUpperRight);
assert_eq!(stream_state.camera_sub_scene, s_s::enums::SubScenes::CameraWithLowerRight);
stream_state.update(StateUpdate::SubScene(
s_s::scenes::SubScenes::ScreenWithUpperRight,
));
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenWithUpperRight
);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLowerRight
);
stream_state.update(StateUpdate::Scene(s_s::scenes::Scenes::Augmented));
assert_eq!(stream_state.current_scene, s_s::scenes::Scenes::Augmented);
assert_eq!(
stream_state.screen_sub_scene,
s_s::scenes::SubScenes::ScreenWithUpperRight
);
assert_eq!(
stream_state.camera_sub_scene,
s_s::scenes::SubScenes::CameraWithLowerRight
);
}
#[test]
fn test_updating() {
let mut stream_state = s_s::stream_states_class::StreamState::new();
let mut stream_state = s_s::stream_state::StreamState::new();
assert_eq!(stream_state.timer_can_run, true);
stream_state.update(StateUpdate::TimerCanRun(false));
assert_eq!(stream_state.timer_can_run, false);
@ -119,22 +181,21 @@ fn test_updating() {
stream_state.update(StateUpdate::ToggleComputerSoundOn(false));
assert_eq!(stream_state.computer_sound_is_on, false);
assert_eq!(stream_state.change_scene_on_change_slide_hotkey, true);
assert_eq!(stream_state.change_scene_on_slide_hotkey, true);
stream_state.update(StateUpdate::ChangeSceneOnChangeSlide(false));
assert_eq!(stream_state.change_scene_on_change_slide_hotkey, false);
assert_eq!(stream_state.change_scene_on_slide_hotkey, false);
assert_eq!(stream_state.scene_is_augmented, false);
stream_state.update(StateUpdate::SceneIsAugmented(true));
assert_eq!(stream_state.scene_is_augmented, true);
}
#[test]
fn can_run_in_thread() {
let (tx, rx) = mpsc::channel();
let rx_thread = thread::spawn(move || {
let mut stream_state = s_s::stream_states_class::StreamState::new();
let mut stream_state = s_s::stream_state::StreamState::new();
for received in rx {
assert_eq!(received, StateUpdate::StreamRunning(true));
stream_state.update(received);
@ -149,4 +210,4 @@ fn can_run_in_thread() {
Ok(_) => return,
Err(_) => panic!(),
}
}
}