Update subsystems; add hid sandbox.
This commit is contained in:
parent
b275dc9a98
commit
2594d20bcf
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
|
1736
Cargo.lock
generated
1736
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -7,3 +7,10 @@ edition = "2021"
|
||||
winit = "0.30.5"
|
||||
rayon = "1.10.0"
|
||||
crossbeam = "0.8.4"
|
||||
|
||||
hidapi = "2.6.3"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows = "0.58.0"
|
||||
|
||||
[target.'cfg(linux)'.dependencies]
|
||||
|
133
src/bin/test-hid.rs
Normal file
133
src/bin/test-hid.rs
Normal file
@ -0,0 +1,133 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use hidapi::HidApi;
|
||||
|
||||
//use donten::hid;
|
||||
|
||||
struct Report {
|
||||
device:usize,
|
||||
interface:usize,
|
||||
data:Vec<u8>,
|
||||
}
|
||||
|
||||
struct Usage {
|
||||
usage_page:u16,
|
||||
usage:u16,
|
||||
|
||||
offset:usize,
|
||||
bit_length:usize,
|
||||
|
||||
minimum:u32,
|
||||
maximum:u32,
|
||||
}
|
||||
|
||||
struct ReportDescriptor {
|
||||
id:usize,
|
||||
usages:Vec<Usage>,
|
||||
data:Vec<u8>,
|
||||
}
|
||||
|
||||
struct DeviceInterface {
|
||||
reports:Vec<ReportDescriptor>,
|
||||
}
|
||||
|
||||
struct Device {
|
||||
product:String,
|
||||
manufacturer:String,
|
||||
serial:String,
|
||||
|
||||
interfaces:Vec<DeviceInterface>,
|
||||
}
|
||||
|
||||
fn main()
|
||||
{
|
||||
let (_tx, _rx) = crossbeam::channel::bounded::<Vec<u8>>(100);
|
||||
|
||||
if let Ok(hid) = HidApi::new() {
|
||||
|
||||
let mut devices = Vec::<Device>::new();
|
||||
|
||||
println!("[Device List]");
|
||||
for device_info in hid.device_list() {
|
||||
|
||||
let product = if let Some(s) = device_info.product_string() { s } else { "" }.to_string();
|
||||
let manufacturer = if let Some(s) = device_info.manufacturer_string() { s } else { "" }.to_string();
|
||||
let serial = if let Some(s) = device_info.serial_number() { s } else { "" }.to_string();
|
||||
|
||||
let mut index = 0;
|
||||
while index < devices.len() {
|
||||
if devices[index].product == product
|
||||
&& devices[index].manufacturer == manufacturer
|
||||
&& devices[index].serial == serial
|
||||
{
|
||||
break;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if index == devices.len() {
|
||||
// Insert new device
|
||||
|
||||
let device = Device {
|
||||
product,
|
||||
manufacturer,
|
||||
serial,
|
||||
|
||||
interfaces:Vec::new(),
|
||||
};
|
||||
|
||||
println!(" - {} ({})",
|
||||
device.product,
|
||||
device.manufacturer,
|
||||
);
|
||||
|
||||
devices.push(device);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// Add usage to device.
|
||||
let mut desc_bytes = [0u8; hidapi::MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
|
||||
if let Ok(hwd) = device_info.open_device(&hid) {
|
||||
if let Ok(desc_size) = hwd.get_report_descriptor(&mut desc_bytes) {
|
||||
|
||||
if let Ok(descriptor) = hid::ReportDescriptor::parse(&desc_bytes[0..desc_size]) {
|
||||
let interface = DeviceInterface {
|
||||
reports:Vec::new(),
|
||||
};
|
||||
let mut buffer_length = 0;
|
||||
|
||||
// Push interface to device.
|
||||
let interface_index = devices[index].interfaces.len();
|
||||
devices[index].interfaces.push(interface);
|
||||
|
||||
// Listen for input reports from device.
|
||||
let _ttx = tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
let _device_index = index;
|
||||
let _interface_index = interface_index;
|
||||
let buffer_length = buffer_length;
|
||||
|
||||
let hwd = hwd;
|
||||
|
||||
let mut buffer = vec![0u8; buffer_length];
|
||||
while let Ok(_size) = hwd.read(&mut buffer) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
// Process input reports.
|
||||
/*while let Ok(_msg) = rx.recv() {
|
||||
|
||||
}*/
|
||||
} else {
|
||||
println!("failed to init hidapi.");
|
||||
}
|
||||
}
|
0
src/hid/consts.rs
Normal file
0
src/hid/consts.rs
Normal file
341
src/hid/mod.rs
Normal file
341
src/hid/mod.rs
Normal file
@ -0,0 +1,341 @@
|
||||
/*
|
||||
enum ByteCode {
|
||||
Report = 0x00,
|
||||
Collection = 0xA1,
|
||||
UsagePage = 0x05,
|
||||
Usage = 0x09,
|
||||
UsageMin = 0x19,
|
||||
UsageMax = 0x29,
|
||||
LogicalMin = 0x15,
|
||||
LogicalMax = 0x25,
|
||||
PhysicalMin = 0x100,
|
||||
PhysicalMax = 0x101,
|
||||
ReportSize = 0x75,
|
||||
ReportCount = 0x95,
|
||||
}
|
||||
|
||||
const F_TYPE :u16 = 0x03;
|
||||
const TYPE_INPUT :u16 = 0x01;
|
||||
const TYPE_OUTPUT :u16 = 0x02;
|
||||
const TYPE_FEATURE :u16 = 0x03;
|
||||
const F_DC :u16 = 0x40; // Data / Const
|
||||
const F_RA :u16 = 0x80; // Relative / Absolute
|
||||
|
||||
struct _Usage {
|
||||
usage_page:u16,
|
||||
usage:u16,
|
||||
offset:u16,
|
||||
size:u16,
|
||||
fields:u16,
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Main Items
|
||||
const MN_INPUT :u8 = 0b1000_00_00;
|
||||
const MN_OUTPUT :u8 = 0b1001_00_00;
|
||||
const MN_FEATURE :u8 = 0b1011_00_00;
|
||||
const MN_COLLECTION_BEGIN :u8 = 0b1010_00_00;
|
||||
const MN_COLLECTION_END :u8 = 0b1100_00_00;
|
||||
const MN_EXTENDED :u8 = 0b1111_11_00;
|
||||
|
||||
// Global Items
|
||||
const GB_USAGE_PAGE :u8 = 0b0000_01_00;
|
||||
const GB_LOGICAL_MIN :u8 = 0b0001_01_00;
|
||||
const GB_LOGICAL_MAX :u8 = 0b0010_01_00;
|
||||
const GB_PHYSICAL_MIN :u8 = 0b0011_01_00;
|
||||
const GB_PHYSICAL_MAX :u8 = 0b0100_01_00;
|
||||
const GB_UNIT_EXPONENT :u8 = 0b0101_01_00;
|
||||
const GB_UNIT :u8 = 0b0110_01_00;
|
||||
const GB_REPORT_SIZE :u8 = 0b0111_01_00;
|
||||
const GB_REPORT_ID :u8 = 0b1000_01_00;
|
||||
const GB_REPORT_COUNT :u8 = 0b1001_01_00;
|
||||
const GB_PUSH :u8 = 0b1010_01_00;
|
||||
const GB_POP :u8 = 0b1011_01_00;
|
||||
|
||||
// Local Items
|
||||
const LC_USAGE :u8 = 0b0000_10_00;
|
||||
const LC_USAGE_MIN :u8 = 0b0001_10_00;
|
||||
const LC_USAGE_MAX :u8 = 0b0010_10_00;
|
||||
const LC_DESIGNATOR_INDEX :u8 = 0b0011_10_00;
|
||||
const LC_DESIGNATOR_MIN :u8 = 0b0100_10_00;
|
||||
const LC_DESIGNATOR_MAX :u8 = 0b0101_10_00;
|
||||
const LC_STRING_INDEX :u8 = 0b0111_10_00;
|
||||
const LC_STRING_MIN :u8 = 0b1000_10_00;
|
||||
const LC_STRING_MAX :u8 = 0b1001_10_00;
|
||||
const LC_DELIMITER :u8 = 0b1010_10_00;
|
||||
|
||||
struct Context {
|
||||
usage_page:u16,
|
||||
usages:Vec<u16>,
|
||||
logical_min:i32,
|
||||
logical_max:i32,
|
||||
physical_min:Option<i32>,
|
||||
physical_max:Option<i32>,
|
||||
report_count:u16,
|
||||
report_size:u16,
|
||||
}
|
||||
|
||||
struct GlobalState {
|
||||
usage_page:u32,
|
||||
logical_min:i32,
|
||||
logical_max:i32,
|
||||
physical_min:i32,
|
||||
physical_max:i32,
|
||||
unit_exponent:i32,
|
||||
unit:u32,
|
||||
report_id:u32,
|
||||
report_size:u32,
|
||||
report_count:u32,
|
||||
}
|
||||
impl GlobalState {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
usage_page:0,
|
||||
logical_min:0,
|
||||
logical_max:0,
|
||||
physical_min:0,
|
||||
physical_max:0,
|
||||
unit_exponent:0,
|
||||
unit:0,
|
||||
report_id:0,
|
||||
report_size:0,
|
||||
report_count:0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct ReportDescriptor {
|
||||
|
||||
}
|
||||
impl ReportDescriptor {
|
||||
pub fn parse(bytes:&[u8]) -> Result<Self,()>
|
||||
{
|
||||
// Output
|
||||
let mut descriptor = Self {
|
||||
|
||||
};
|
||||
|
||||
// Global State
|
||||
let mut global_state = Vec::<GlobalState>::new();
|
||||
global_state.push(GlobalState::new());
|
||||
|
||||
// Local State
|
||||
let usages = Vec::<[u16;2]>::new();
|
||||
|
||||
// Tracking
|
||||
let mut collection_index = 0;
|
||||
let mut offset = 0;
|
||||
let mut report_id = 0;
|
||||
|
||||
let mut index = 0;
|
||||
while index < bytes.len() {
|
||||
let mut sz = bytes[index] & 0x03;
|
||||
let mut tg = bytes[index] & 0xFC;
|
||||
|
||||
// Get byte size from index
|
||||
sz = [ 0, 1, 2, 4 ][sz as usize];
|
||||
|
||||
index += 1;
|
||||
|
||||
if bytes.len() - index >= sz as usize {
|
||||
|
||||
// Handle long tag
|
||||
if sz == 2 && tg == MN_EXTENDED {
|
||||
sz = bytes[index + 1];
|
||||
tg = bytes[index + 2];
|
||||
|
||||
if bytes.len() - index < sz as usize {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
|
||||
if sz <= 4 {
|
||||
match tg {
|
||||
MN_INPUT => {
|
||||
/*
|
||||
** 0: Data(0), Constant(1)
|
||||
** 1: Array(0), Variable(1)
|
||||
** 2: Absolute(0), Relative(1)
|
||||
** 3: NoWrap(0), Wrap(1)
|
||||
** 4: Linear(0), NonLinear(1)
|
||||
** 5: PreferredState(0), NoPreferred(1)
|
||||
** 6: NoNull(0), NullState(1)
|
||||
** 7: reserved
|
||||
** 8: BitField(0), BufferedBytes(1)
|
||||
** _: reserved
|
||||
*/
|
||||
|
||||
let mut is_const = false;
|
||||
let mut is_var = false;
|
||||
let mut is_rel = false;
|
||||
let mut is_wrap = false;
|
||||
let mut is_linear = false;
|
||||
let mut is_pref = false;
|
||||
let mut has_null = false;
|
||||
let mut is_volatile = false;
|
||||
let mut is_buffered = false;
|
||||
|
||||
if sz >= 1 {
|
||||
is_const = (bytes[index + 1] & 0x01) != 0;
|
||||
is_var = (bytes[index + 1] & 0x02) != 0;
|
||||
is_rel = (bytes[index + 1] & 0x04) != 0;
|
||||
}
|
||||
|
||||
if sz >= 2 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MN_OUTPUT => {
|
||||
/*
|
||||
** 0: Data(0), Constant(1)
|
||||
** 1: Array(0), Variable(1)
|
||||
** 2: Absolute(0), Relative(1)
|
||||
** 3: NoWrap(0), Wrap(1)
|
||||
** 4: Linear(0), NonLinear(1)
|
||||
** 5: PreferredState(0), NoPreferred(1)
|
||||
** 6: NoNull(0), NullState(1)
|
||||
** 7: NonVolatile(0), Volatile(1)
|
||||
** 8: BitField(0), BufferedBytes(1)
|
||||
** _: reserved
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
MN_FEATURE => {
|
||||
/*
|
||||
** 0: Data(0), Constant(1)
|
||||
** 1: Array(0), Variable(1)
|
||||
** 2: Absolute(0), Relative(1)
|
||||
** 3: NoWrap(0), Wrap(1)
|
||||
** 4: Linear(0), NonLinear(1)
|
||||
** 5: PreferredState(0), NoPreferred(1)
|
||||
** 6: NoNull(0), NullState(1)
|
||||
** 7: NonVolatile(0), Volatile(1)
|
||||
** 8: BitField(0), BufferedBytes(1)
|
||||
** _: reserved
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
MN_COLLECTION_BEGIN => {
|
||||
/*
|
||||
** 00: Physical
|
||||
** 01: Application
|
||||
** 02: Logical
|
||||
** 03: Report
|
||||
** 04: NamedArray
|
||||
** 05: UsageSwitch
|
||||
** 06: UsageModifier
|
||||
** 07-7F: reserved
|
||||
** 80-FF: vendor-defined
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
MN_COLLECTION_END => {
|
||||
|
||||
}
|
||||
|
||||
GB_USAGE_PAGE => {
|
||||
|
||||
}
|
||||
|
||||
GB_LOGICAL_MIN => {
|
||||
|
||||
}
|
||||
|
||||
GB_LOGICAL_MAX => {
|
||||
|
||||
}
|
||||
|
||||
GB_PHYSICAL_MIN => {
|
||||
|
||||
}
|
||||
|
||||
GB_PHYSICAL_MAX => {
|
||||
|
||||
}
|
||||
|
||||
GB_UNIT_EXPONENT => {
|
||||
|
||||
}
|
||||
|
||||
GB_UNIT => {
|
||||
|
||||
}
|
||||
|
||||
GB_REPORT_SIZE => {
|
||||
|
||||
}
|
||||
|
||||
GB_REPORT_ID => {
|
||||
|
||||
}
|
||||
|
||||
GB_REPORT_COUNT => {
|
||||
|
||||
}
|
||||
|
||||
GB_PUSH => {
|
||||
|
||||
}
|
||||
|
||||
GB_POP => {
|
||||
|
||||
}
|
||||
|
||||
LC_USAGE => {
|
||||
|
||||
}
|
||||
|
||||
LC_USAGE_MIN => {
|
||||
|
||||
}
|
||||
|
||||
LC_USAGE_MAX => {
|
||||
|
||||
}
|
||||
|
||||
LC_DESIGNATOR_INDEX => {
|
||||
|
||||
}
|
||||
|
||||
LC_DESIGNATOR_MIN => {
|
||||
|
||||
}
|
||||
|
||||
LC_DESIGNATOR_MAX => {
|
||||
|
||||
}
|
||||
|
||||
LC_STRING_INDEX => {
|
||||
|
||||
}
|
||||
|
||||
LC_STRING_MIN => {
|
||||
|
||||
}
|
||||
|
||||
LC_STRING_MAX => {
|
||||
|
||||
}
|
||||
|
||||
LC_DELIMITER => {
|
||||
|
||||
}
|
||||
|
||||
_ => { return Err(()); }
|
||||
}
|
||||
}
|
||||
|
||||
index += sz as usize;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(descriptor)
|
||||
}
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
#![allow(dead_code, unused_imports)]
|
||||
use crossbeam::channel::Sender;
|
||||
|
||||
mod util;
|
||||
mod error; pub use error::Error;
|
||||
mod config; pub use config::Config;
|
||||
use system::{Subsystem, Query};
|
||||
mod system;
|
||||
mod platform;
|
||||
|
||||
pub mod hid;
|
||||
|
||||
pub struct Donten {
|
||||
channel:Sender<Query>,
|
||||
}
|
||||
@ -14,7 +17,7 @@ impl Donten {
|
||||
pub fn init(_config:Config) -> Result<Self, Error>
|
||||
{
|
||||
// Initialize supervisor.
|
||||
let channel = system::Supervisor::start()?;
|
||||
let channel = system::Supervisor::start(None)?;
|
||||
|
||||
// Parse config and push instructions to supervisor.
|
||||
|
||||
|
@ -9,5 +9,8 @@ impl APIManager {
|
||||
}
|
||||
|
||||
impl Subsystem for APIManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,8 @@ impl AudioManager {
|
||||
}
|
||||
|
||||
impl Subsystem for AudioManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,8 @@ impl ControlManager {
|
||||
}
|
||||
|
||||
impl Subsystem for ControlManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
51
src/system/input/internal/mod.rs
Normal file
51
src/system/input/internal/mod.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::system::*;
|
||||
|
||||
mod platform;
|
||||
mod xinput;
|
||||
|
||||
pub struct Internal {
|
||||
supervisor:Sender<Query>,
|
||||
sys_window:Option<Sender<Query>>,
|
||||
}
|
||||
impl Internal {
|
||||
pub fn thread(supervisor:Sender<Query>, _tx:Sender<Query>, rx:Receiver<Query>)
|
||||
{
|
||||
let _sv = Internal {
|
||||
supervisor,
|
||||
sys_window:None,
|
||||
};
|
||||
|
||||
// Request interested subsystem status.
|
||||
|
||||
|
||||
// Handle messages.
|
||||
while let Ok(msg) = rx.recv() {
|
||||
match msg.data {
|
||||
QueryData::Supervisor(request) => match request {
|
||||
SupervisorQuery::Stop {
|
||||
system: _,
|
||||
} => {
|
||||
|
||||
// Perform shutdown operations and terminate thread.
|
||||
return;
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
|
||||
QueryData::Window(request) => match request {
|
||||
WindowQuery::Create {
|
||||
|
||||
} => {
|
||||
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
0
src/system/input/internal/platform/linux.rs
Normal file
0
src/system/input/internal/platform/linux.rs
Normal file
13
src/system/input/internal/platform/mod.rs
Normal file
13
src/system/input/internal/platform/mod.rs
Normal file
@ -0,0 +1,13 @@
|
||||
pub trait Platform {
|
||||
fn register_devices() -> Result<(),()>;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
mod windows;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use windows::*;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
mod linux;
|
||||
#[cfg(target_os = "linux")]
|
||||
pub use linux::*;
|
0
src/system/input/internal/platform/windows.rs
Normal file
0
src/system/input/internal/platform/windows.rs
Normal file
28
src/system/input/internal/xinput/mod.rs
Normal file
28
src/system/input/internal/xinput/mod.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::system::*;
|
||||
|
||||
|
||||
|
||||
pub struct XInputSystem {
|
||||
running:bool,
|
||||
}
|
||||
impl XInputSystem {
|
||||
pub fn thread(_tx:Sender<Query>, rx:Receiver<Query>)
|
||||
{
|
||||
let sv = XInputSystem {
|
||||
running:true,
|
||||
};
|
||||
|
||||
while sv.running {
|
||||
// Handle system queries
|
||||
while let Ok(_msg) = rx.try_recv() {
|
||||
|
||||
}
|
||||
|
||||
// Poll xinput devices
|
||||
|
||||
|
||||
// Sleep until next step
|
||||
std::thread::sleep(std::time::Duration::from_millis(4));
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ use super::*;
|
||||
|
||||
mod usage; use usage::Usage;
|
||||
mod device; use device::Device;
|
||||
mod internal; use internal::Internal;
|
||||
|
||||
pub struct InputManager {
|
||||
channel:Sender<Query>,
|
||||
@ -12,5 +13,19 @@ impl InputManager {
|
||||
}
|
||||
|
||||
impl Subsystem for InputManager {
|
||||
|
||||
fn start(supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
if let Some(supervisor) = supervisor {
|
||||
let (tx, rx) = channel::bounded::<Query>(24);
|
||||
|
||||
let sys_tx = tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
Internal::thread(supervisor, sys_tx, rx);
|
||||
});
|
||||
|
||||
Ok(tx)
|
||||
} else {
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ pub(crate) mod storage; pub(crate) use storage::*;
|
||||
pub(crate) mod api; pub(crate) use api::*;
|
||||
|
||||
pub(crate) trait Subsystem {
|
||||
fn start() -> Result<Sender<Query>, Error> { Err(Error::new()) }
|
||||
fn start(supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>;
|
||||
fn shutdown() -> Result<(), Error> { Ok(()) }
|
||||
}
|
||||
|
||||
|
@ -9,5 +9,8 @@ impl NetworkManager {
|
||||
}
|
||||
|
||||
impl Subsystem for NetworkManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,8 @@ impl SceneManager {
|
||||
}
|
||||
|
||||
impl Subsystem for SceneManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -9,5 +9,8 @@ impl StorageManager {
|
||||
}
|
||||
|
||||
impl Subsystem for StorageManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,11 @@ impl Internal {
|
||||
SupervisorQuery::Start {
|
||||
system,
|
||||
} => if sv.subsystems[system as usize].is_none() {
|
||||
let sv_channel = sv.subsystems[System::Supervisor as usize].clone();
|
||||
|
||||
if let Ok(channel) = match system {
|
||||
|
||||
System::Window => WindowManager::start(),
|
||||
System::Window => WindowManager::start(sv_channel),
|
||||
|
||||
_ => { Err(Error::new()) }
|
||||
} {
|
||||
@ -36,6 +38,9 @@ impl Internal {
|
||||
))).ok();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Log subsystem startup error
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ impl Supervisor {
|
||||
}
|
||||
|
||||
impl Subsystem for Supervisor {
|
||||
fn start() -> Result<Sender<Query>, crate::Error>
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, crate::Error>
|
||||
{
|
||||
let (tx, rx) = channel::bounded::<Query>(24);
|
||||
|
||||
|
@ -9,5 +9,8 @@ impl VideoManager {
|
||||
}
|
||||
|
||||
impl Subsystem for VideoManager {
|
||||
|
||||
fn start(_supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, Error>
|
||||
{
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
|
@ -32,4 +32,19 @@ impl ApplicationHandler for Handler {
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
fn device_event(
|
||||
&mut self,
|
||||
_event_loop: &ActiveEventLoop,
|
||||
_device_id: winit::event::DeviceId,
|
||||
event: winit::event::DeviceEvent,
|
||||
) {
|
||||
use winit::event::DeviceEvent;
|
||||
|
||||
match event {
|
||||
DeviceEvent::Added => { println!(" - added"); }
|
||||
DeviceEvent::Removed => { println!(" - removed"); }
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ use winit::{
|
||||
mod handler; use handler::Handler;
|
||||
|
||||
pub struct Internal {
|
||||
|
||||
supervisor:Sender<Query>,
|
||||
}
|
||||
impl Internal {
|
||||
pub fn thread(tx:Sender<Query>, rx:Receiver<Query>)
|
||||
pub fn thread(supervisor:Sender<Query>, tx:Sender<Query>, rx:Receiver<Query>)
|
||||
{
|
||||
let _sv = Internal {
|
||||
|
||||
supervisor,
|
||||
};
|
||||
|
||||
// Initialize event loop.
|
||||
|
@ -25,16 +25,20 @@ impl WindowManager {
|
||||
|
||||
impl Subsystem for WindowManager {
|
||||
|
||||
fn start() -> Result<Sender<Query>, crate::Error>
|
||||
fn start(supervisor:Option<Sender<Query>>) -> Result<Sender<Query>, crate::Error>
|
||||
{
|
||||
let (tx, rx) = channel::bounded::<Query>(24);
|
||||
if let Some(supervisor) = supervisor {
|
||||
let (tx, rx) = channel::bounded::<Query>(24);
|
||||
|
||||
let sys_tx = tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
Internal::thread(sys_tx, rx);
|
||||
});
|
||||
let sys_tx = tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
Internal::thread(supervisor, sys_tx, rx);
|
||||
});
|
||||
|
||||
Ok(tx)
|
||||
Ok(tx)
|
||||
} else {
|
||||
Err(Error::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
1
src/util/mod.rs
Normal file
1
src/util/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod pack;
|
6
src/util/pack.rs
Normal file
6
src/util/pack.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use std::ops::{BitOr, ShlAssign};
|
||||
|
||||
fn unpack<T:ShlAssign + BitOr>()
|
||||
{
|
||||
|
||||
}
|
Reference in New Issue
Block a user