-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge: prepare for coin/bill hardware
- Loading branch information
Showing
27 changed files
with
639 additions
and
178 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "bidrum-controller-lib" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
bidrum-data-struct-lib = { path = "../data-struct-lib" } | ||
serialport = "4.3.0" | ||
device_query = "2.0.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod coin_device; | ||
pub mod janggu_device; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use std::{ | ||
sync::{ | ||
atomic::{AtomicBool, AtomicU32, Ordering}, | ||
Arc, | ||
}, | ||
time::Duration, | ||
}; | ||
|
||
use device_query::{DeviceQuery, DeviceState, Keycode}; | ||
|
||
use crate::CoinInputDevice; | ||
|
||
/// United bidrum controller of Janggu and Coin/Bill acceptor | ||
pub struct KeyboardCoinDevice { | ||
unconsumed_coins: Arc<AtomicU32>, | ||
stopping: Arc<AtomicBool>, | ||
} | ||
|
||
impl Drop for KeyboardCoinDevice { | ||
fn drop(&mut self) { | ||
self.stopping.store(true, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl CoinInputDevice for KeyboardCoinDevice { | ||
fn get_unconsumed_coins(&self) -> u32 { | ||
self.unconsumed_coins.load(Ordering::Relaxed) | ||
} | ||
|
||
fn consume_coins(&mut self, coins: u32) { | ||
self.unconsumed_coins.fetch_sub(coins, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl KeyboardCoinDevice { | ||
pub fn new() -> KeyboardCoinDevice { | ||
let unconsumed_coins = Arc::new(AtomicU32::new(0)); | ||
let stopping = Arc::new(AtomicBool::new(false)); | ||
|
||
{ | ||
let unconsumed_coins = unconsumed_coins.clone(); | ||
|
||
let _stopping = stopping.clone(); | ||
|
||
std::thread::spawn(move || { | ||
let mut pressed = false; | ||
let device_state = DeviceState::new(); | ||
loop { | ||
let new_pressed = device_state.get_keys().contains(&Keycode::C); | ||
if new_pressed && !pressed { | ||
// increase one on keydown | ||
unconsumed_coins.fetch_add(1, std::sync::atomic::Ordering::Relaxed); | ||
} | ||
|
||
pressed = new_pressed; | ||
std::thread::sleep(Duration::from_millis(10)); | ||
} | ||
}); | ||
} | ||
|
||
KeyboardCoinDevice { | ||
unconsumed_coins: unconsumed_coins, | ||
stopping: stopping, | ||
} | ||
} | ||
} | ||
|
||
fn has_coin_bit(bits: u8) -> bool { | ||
bits & 16 != 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use std::{ | ||
sync::{ | ||
atomic::{AtomicBool, AtomicU8, Ordering}, | ||
Arc, RwLock, | ||
}, | ||
thread, | ||
}; | ||
|
||
use bidrum_data_struct_lib::janggu::{JangguFace, JangguInputState}; | ||
use device_query::{DeviceQuery, DeviceState, Keycode}; | ||
|
||
use crate::JangguDevice; | ||
|
||
pub struct KeyboardJangguDevice { | ||
stopping: Arc<AtomicBool>, | ||
// Using RwLock<JangguInputState> is too slow | ||
state: Arc<AtomicU8>, | ||
} | ||
|
||
impl KeyboardJangguDevice { | ||
pub fn new() -> KeyboardJangguDevice { | ||
let stopping = Arc::new(AtomicBool::new(false)); | ||
let state = Arc::new(AtomicU8::new(0)); | ||
|
||
{ | ||
let stopping = stopping.clone(); | ||
let state = state.clone(); | ||
|
||
thread::spawn(move || { | ||
let mut device_states = DeviceState::new(); | ||
loop { | ||
if stopping.load(Ordering::Relaxed) { | ||
break; | ||
} | ||
|
||
state.store(keyboard_to_bits(&mut device_states), Ordering::Relaxed); | ||
} | ||
}); | ||
} | ||
|
||
KeyboardJangguDevice { | ||
state: state, | ||
stopping: stopping, | ||
} | ||
} | ||
} | ||
|
||
impl Drop for KeyboardJangguDevice { | ||
fn drop(&mut self) { | ||
self.stopping.store(true, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl JangguDevice for KeyboardJangguDevice { | ||
fn read_janggu_input_state(&self) -> JangguInputState { | ||
bits_to_janggu_input_state(self.state.load(Ordering::Relaxed)) | ||
} | ||
} | ||
|
||
fn bits_to_janggu_input_state(bits: u8) -> JangguInputState { | ||
JangguInputState { | ||
궁채: if bits & 1 != 0 { | ||
Some(JangguFace::궁편) | ||
} else if bits & 2 != 0 { | ||
Some(JangguFace::열편) | ||
} else { | ||
None | ||
}, | ||
열채: if bits & 4 != 0 { | ||
Some(JangguFace::궁편) | ||
} else if bits & 8 != 0 { | ||
Some(JangguFace::열편) | ||
} else { | ||
None | ||
}, | ||
} | ||
} | ||
|
||
fn keyboard_to_bits(device_states: &mut DeviceState) -> u8 { | ||
let keys = device_states.get_keys(); | ||
let mut bits = 0; | ||
if keys.contains(&Keycode::D) { | ||
bits |= 1; | ||
} else if keys.contains(&Keycode::F) { | ||
bits |= 2; | ||
} | ||
if keys.contains(&Keycode::J) { | ||
bits |= 4; | ||
} else if keys.contains(&Keycode::K) { | ||
bits |= 8; | ||
} | ||
|
||
return bits; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
pub mod keyboard; | ||
pub mod serial; | ||
|
||
use bidrum_data_struct_lib::janggu::JangguInputState; | ||
|
||
/// Bidrum Janggu Controller | ||
pub trait JangguDevice { | ||
/// Reads janggu controller input state | ||
fn read_janggu_input_state(&self) -> JangguInputState; | ||
} | ||
|
||
/// Bidrum Coin/Bill Acceptor | ||
pub trait CoinInputDevice { | ||
/// Reads unconsumed coin count | ||
fn get_unconsumed_coins(&self) -> u32; | ||
fn consume_coins(&mut self, coins: u32); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
mod coin_device; | ||
mod janggu_device; | ||
mod serial_reader; | ||
|
||
use coin_device::SerialCoinDevice; | ||
use janggu_device::SerialJangguDevice; | ||
use serial_reader::BidrumSerialReader; | ||
|
||
pub fn new(serial_port: String) -> (SerialJangguDevice, SerialCoinDevice) { | ||
let serial_reader = BidrumSerialReader::new(serial_port); | ||
return ( | ||
SerialJangguDevice::new(serial_reader.clone()), | ||
SerialCoinDevice::new(serial_reader.clone()), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use std::{ | ||
sync::{ | ||
atomic::{AtomicBool, AtomicU32, Ordering}, | ||
Arc, | ||
}, | ||
thread::{self}, | ||
}; | ||
|
||
use crate::CoinInputDevice; | ||
|
||
use super::serial_reader::BidrumSerialReader; | ||
|
||
/// United bidrum controller of Janggu and Coin/Bill acceptor | ||
pub struct SerialCoinDevice { | ||
serial_reader: BidrumSerialReader, | ||
unconsumed_coins: Arc<AtomicU32>, | ||
stopping: Arc<AtomicBool>, | ||
} | ||
|
||
impl Drop for SerialCoinDevice { | ||
fn drop(&mut self) { | ||
self.stopping.store(true, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl CoinInputDevice for SerialCoinDevice { | ||
fn get_unconsumed_coins(&self) -> u32 { | ||
self.unconsumed_coins.load(Ordering::Relaxed) | ||
} | ||
|
||
fn consume_coins(&mut self, coins: u32) { | ||
self.unconsumed_coins.fetch_sub(coins, Ordering::Relaxed); | ||
} | ||
} | ||
|
||
impl SerialCoinDevice { | ||
pub(super) fn new(serial_reader: BidrumSerialReader) -> SerialCoinDevice { | ||
let unconsumed_coins = Arc::new(AtomicU32::new(0)); | ||
let stopping = Arc::new(AtomicBool::new(false)); | ||
|
||
{ | ||
let unconsumed_coins = unconsumed_coins.clone(); | ||
let bits = serial_reader.bits.clone(); | ||
let stopping = stopping.clone(); | ||
thread::spawn(move || { | ||
let mut prev = false; | ||
loop { | ||
if stopping.load(Ordering::Relaxed) { | ||
break; | ||
} | ||
|
||
let current = has_coin_bit(bits.load(Ordering::Relaxed)); | ||
if !prev && current { | ||
unconsumed_coins.fetch_add(1, Ordering::Relaxed); | ||
} | ||
|
||
prev = current; | ||
} | ||
}); | ||
} | ||
|
||
SerialCoinDevice { | ||
serial_reader: serial_reader, | ||
unconsumed_coins: unconsumed_coins, | ||
stopping: stopping, | ||
} | ||
} | ||
} | ||
|
||
fn has_coin_bit(bits: u8) -> bool { | ||
bits & 16 != 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use std::sync::atomic::Ordering; | ||
|
||
use bidrum_data_struct_lib::janggu::{JangguFace, JangguInputState}; | ||
|
||
use crate::JangguDevice; | ||
|
||
use super::serial_reader::BidrumSerialReader; | ||
|
||
pub struct SerialJangguDevice { | ||
serial_reader: BidrumSerialReader, | ||
} | ||
|
||
impl SerialJangguDevice { | ||
pub(super) fn new(serial_reader: BidrumSerialReader) -> SerialJangguDevice { | ||
SerialJangguDevice { | ||
serial_reader: serial_reader, | ||
} | ||
} | ||
} | ||
|
||
impl JangguDevice for SerialJangguDevice { | ||
fn read_janggu_input_state(&self) -> JangguInputState { | ||
return parse_janggu_bits(self.serial_reader.bits.load(Ordering::Relaxed)); | ||
} | ||
} | ||
|
||
fn parse_janggu_bits(bits: u8) -> JangguInputState { | ||
return JangguInputState { | ||
궁채: if bits & 1 != 0 { | ||
Some(JangguFace::궁편) | ||
} else if bits & 2 != 0 { | ||
Some(JangguFace::열편) | ||
} else { | ||
None | ||
}, | ||
열채: if bits & 4 != 0 { | ||
Some(JangguFace::궁편) | ||
} else if bits & 8 != 0 { | ||
Some(JangguFace::열편) | ||
} else { | ||
None | ||
}, | ||
}; | ||
} |
Oops, something went wrong.