Document, improve some API functionality
This commit is contained in:
parent
0a5323c927
commit
d242cb9d70
25 changed files with 183 additions and 56 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -924,20 +924,6 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "usdpl"
|
|
||||||
version = "0.4.0"
|
|
||||||
dependencies = [
|
|
||||||
"console_error_panic_hook",
|
|
||||||
"js-sys",
|
|
||||||
"usdpl-core",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"wasm-bindgen-futures",
|
|
||||||
"wasm-bindgen-test",
|
|
||||||
"web-sys",
|
|
||||||
"wee_alloc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usdpl-back"
|
name = "usdpl-back"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -955,6 +941,20 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "usdpl-front"
|
||||||
|
version = "0.4.0"
|
||||||
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
|
"js-sys",
|
||||||
|
"usdpl-core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"wasm-bindgen-test",
|
||||||
|
"web-sys",
|
||||||
|
"wee_alloc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usdpl-rs"
|
name = "usdpl-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
14
README.md
14
README.md
|
@ -1,3 +1,7 @@
|
||||||
|
[![usdpl-back](https://img.shields.io/crates/v/usdpl-back?label=usdpl-back&style=flat-square)](https://crates.io/crates/usdpl-back)
|
||||||
|
[![usdpl-core](https://img.shields.io/crates/v/usdpl-core?label=usdpl-core&style=flat-square)](https://crates.io/crates/usdpl-core)
|
||||||
|
[![usdpl-front](https://img.shields.io/crates/v/usdpl-front?label=usdpl-front&style=flat-square)](https://crates.io/crates/usdpl-front)
|
||||||
|
|
||||||
# usdpl-rs
|
# usdpl-rs
|
||||||
|
|
||||||
Universal Steam Deck Plugin Library
|
Universal Steam Deck Plugin Library
|
||||||
|
@ -5,11 +9,15 @@ Universal Steam Deck Plugin Library
|
||||||
A faster, lighter way to write plugins
|
A faster, lighter way to write plugins
|
||||||
|
|
||||||
### Goals
|
### Goals
|
||||||
- [ ] Minimum viable plugin
|
- [x] Minimum viable plugin
|
||||||
- [ ] Call back-end API from front-end UI
|
- [x] Call back-end API from front-end UI
|
||||||
- [ ] Async support
|
- [x] External API documentation
|
||||||
|
- [ ] Internal API documentation
|
||||||
|
- [x] Async support
|
||||||
|
- [ ] Sync support
|
||||||
- [ ] PluginLoader/Decky support
|
- [ ] PluginLoader/Decky support
|
||||||
- [ ] Crankshaft support
|
- [ ] Crankshaft support
|
||||||
- [ ] Unnamed plugin system support
|
- [ ] Unnamed plugin system support
|
||||||
- [ ] Cross-framework tooling
|
- [ ] Cross-framework tooling
|
||||||
|
- [ ] Other programming languages support (C bindings)
|
||||||
|
|
||||||
|
|
7
README.tpl
Normal file
7
README.tpl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[![usdpl-back](https://img.shields.io/crates/v/usdpl-back?label=usdpl-back&style=flat-square)](https://crates.io/crates/usdpl-back)
|
||||||
|
[![usdpl-core](https://img.shields.io/crates/v/usdpl-core?label=usdpl-core&style=flat-square)](https://crates.io/crates/usdpl-core)
|
||||||
|
[![usdpl-front](https://img.shields.io/crates/v/usdpl-front?label=usdpl-front&style=flat-square)](https://crates.io/crates/usdpl-front)
|
||||||
|
|
||||||
|
# {{crate}}
|
||||||
|
|
||||||
|
{{readme}}
|
10
src/main.rs
10
src/main.rs
|
@ -3,13 +3,17 @@
|
||||||
//! A faster, lighter way to write plugins
|
//! A faster, lighter way to write plugins
|
||||||
//!
|
//!
|
||||||
//! ## Goals
|
//! ## Goals
|
||||||
//! - [ ] Minimum viable plugin
|
//! - [x] Minimum viable plugin
|
||||||
//! - [ ] Call back-end API from front-end UI
|
//! - [x] Call back-end API from front-end UI
|
||||||
//! - [ ] Async support
|
//! - [x] External API documentation
|
||||||
|
//! - [ ] Internal API documentation
|
||||||
|
//! - [x] Async support
|
||||||
|
//! - [ ] Sync support
|
||||||
//! - [ ] PluginLoader/Decky support
|
//! - [ ] PluginLoader/Decky support
|
||||||
//! - [ ] Crankshaft support
|
//! - [ ] Crankshaft support
|
||||||
//! - [ ] Unnamed plugin system support
|
//! - [ ] Unnamed plugin system support
|
||||||
//! - [ ] Cross-framework tooling
|
//! - [ ] Cross-framework tooling
|
||||||
|
//! - [ ] Other programming languages support (C bindings)
|
||||||
//!
|
//!
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, USDPL!");
|
println!("Hello, USDPL!");
|
||||||
|
|
|
@ -8,9 +8,10 @@ readme = "README.md"
|
||||||
description = "Universal Steam Deck Plugin Library back-end"
|
description = "Universal Steam Deck Plugin Library back-end"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["blocking"]
|
||||||
decky = []
|
decky = ["usdpl-core/decky"]
|
||||||
crankshaft = []
|
crankshaft = ["usdpl-core/crankshaft"]
|
||||||
|
blocking = ["tokio"] # synchronous API for async functionality, using tokio
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
usdpl-core = { version = "0.4.0", path = "../usdpl-core" }
|
usdpl-core = { version = "0.4.0", path = "../usdpl-core" }
|
||||||
|
@ -18,4 +19,4 @@ usdpl-core = { version = "0.4.0", path = "../usdpl-core" }
|
||||||
# HTTP web framework
|
# HTTP web framework
|
||||||
warp = { version = "0.3" }
|
warp = { version = "0.3" }
|
||||||
bytes = { version = "1.1" }
|
bytes = { version = "1.1" }
|
||||||
tokio = { version = "1.19", features = ["rt", "rt-multi-thread"] }
|
tokio = { version = "1.19", features = ["rt", "rt-multi-thread"], optional = true }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-back?style=flat-square)](https://crates.io/crates/usdpl-back)
|
||||||
|
|
||||||
# usdpl-back
|
# usdpl-back
|
||||||
|
|
||||||
Back-end library for plugins.
|
Back-end library for plugins.
|
||||||
Targets x86_64 (native Steam Deck ISA).
|
Targets x86_64 (native Steam Deck ISA).
|
||||||
|
|
||||||
This is a minimalist TCP server for handling events from the front-end.
|
This is a minimalist web server for handling events from the front-end.
|
||||||
|
|
||||||
|
|
||||||
License: GPL-3.0-only
|
|
||||||
|
|
5
usdpl-back/README.tpl
Normal file
5
usdpl-back/README.tpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-back?style=flat-square)](https://crates.io/crates/usdpl-back)
|
||||||
|
|
||||||
|
# {{crate}}
|
||||||
|
|
||||||
|
{{readme}}
|
|
@ -1,5 +1,13 @@
|
||||||
use usdpl_core::serdes::Primitive;
|
use usdpl_core::serdes::Primitive;
|
||||||
|
|
||||||
|
/// A function which can be called from the front-end (remotely)
|
||||||
pub trait Callable: Send + Sync {
|
pub trait Callable: Send + Sync {
|
||||||
|
/// Invoke the function
|
||||||
fn call(&mut self, params: Vec<Primitive>) -> Vec<Primitive>;
|
fn call(&mut self, params: Vec<Primitive>) -> Vec<Primitive>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<F: (FnMut(Vec<Primitive>) -> Vec<Primitive>) + Send + Sync> Callable for F {
|
||||||
|
fn call(&mut self, params: Vec<Primitive>) -> Vec<Primitive> {
|
||||||
|
(self)(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,19 +27,31 @@ impl Instance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a function which can be invoked by the front-end
|
/// Register a function which can be invoked by the front-end, builder style
|
||||||
pub fn register<S: std::convert::Into<String>, F: Callable + 'static>(
|
pub fn register<S: std::convert::Into<String>, F: Callable + 'static>(
|
||||||
&mut self,
|
mut self,
|
||||||
name: S,
|
name: S,
|
||||||
f: F,
|
f: F,
|
||||||
) -> &mut Self {
|
) -> Self {
|
||||||
//CALLS.lock().unwrap().insert(name.into(), Mutex::new(Box::new(f)));
|
|
||||||
self.calls
|
self.calls
|
||||||
.insert(name.into(), Arc::new(Mutex::new(Box::new(f))));
|
.insert(name.into(), Arc::new(Mutex::new(Box::new(f))));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve(&self) -> Result<(), ()> {
|
/// Register a function which can be invoked by the front-end, object style
|
||||||
|
pub fn register_mut<S: std::convert::Into<String>, F: Callable + 'static>(
|
||||||
|
&mut self,
|
||||||
|
name: S,
|
||||||
|
f: F,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.calls
|
||||||
|
.insert(name.into(), Arc::new(Mutex::new(Box::new(f))));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the web server instance forever, blocking this thread
|
||||||
|
#[cfg(feature = "blocking")]
|
||||||
|
pub fn run_blocking(&self) -> Result<(), ()> {
|
||||||
let result = self.serve_internal();
|
let result = self.serve_internal();
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
|
@ -48,6 +60,11 @@ impl Instance {
|
||||||
.block_on(result)
|
.block_on(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run the web server forever, asynchronously
|
||||||
|
pub async fn run(&self) -> Result<(), ()> {
|
||||||
|
self.serve_internal().await
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_call(
|
fn handle_call(
|
||||||
packet: socket::Packet,
|
packet: socket::Packet,
|
||||||
handlers: &HashMap<String, WrappedCallable>,
|
handlers: &HashMap<String, WrappedCallable>,
|
||||||
|
@ -80,7 +97,7 @@ impl Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive and execute callbacks forever
|
/// Receive and execute callbacks forever
|
||||||
pub async fn serve_internal(&self) -> Result<(), ()> {
|
async fn serve_internal(&self) -> Result<(), ()> {
|
||||||
let handlers = self.calls.clone();
|
let handlers = self.calls.clone();
|
||||||
//self.calls = HashMap::new();
|
//self.calls = HashMap::new();
|
||||||
let calls = warp::post()
|
let calls = warp::post()
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
//! Back-end library for plugins.
|
//! Back-end library for plugins.
|
||||||
//! Targets x86_64 (native Steam Deck ISA).
|
//! Targets x86_64 (native Steam Deck ISA).
|
||||||
//!
|
//!
|
||||||
//! This is a minimalist TCP server for handling events from the front-end.
|
//! This is a minimalist web server for handling events from the front-end.
|
||||||
//!
|
//!
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
mod callable;
|
mod callable;
|
||||||
//mod errors;
|
//mod errors;
|
||||||
|
@ -12,6 +13,7 @@ pub use callable::Callable;
|
||||||
pub use instance::Instance;
|
pub use instance::Instance;
|
||||||
//pub use errors::{ServerError, ServerResult};
|
//pub use errors::{ServerError, ServerResult};
|
||||||
|
|
||||||
|
/// usdpl-core re-export
|
||||||
pub mod core {
|
pub mod core {
|
||||||
pub use usdpl_core::*;
|
pub use usdpl_core::*;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,10 @@ repository = "https://github.com/NGnius/usdpl-rs"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "Universal Steam Deck Plugin Library core"
|
description = "Universal Steam Deck Plugin Library core"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[features]
|
||||||
|
default = []
|
||||||
|
decky = []
|
||||||
|
crankshaft = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-core?style=flat-square)](https://crates.io/crates/usdpl-core)
|
||||||
|
|
||||||
# usdpl-core
|
# usdpl-core
|
||||||
|
|
||||||
Datatypes and constants core the back-end and front-end libraries' operation.
|
Datatypes and constants core the back-end and front-end libraries' operation.
|
||||||
This contains serialization functionality and networking datatypes.
|
This contains serialization functionality and networking datatypes.
|
||||||
|
|
||||||
License: GPL-3.0-only
|
|
||||||
|
|
5
usdpl-core/README.tpl
Normal file
5
usdpl-core/README.tpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-core?style=flat-square)](https://crates.io/crates/usdpl-core)
|
||||||
|
|
||||||
|
# {{crate}}
|
||||||
|
|
||||||
|
{{readme}}
|
|
@ -1,10 +1,16 @@
|
||||||
|
/// Supported plugin platforms
|
||||||
pub enum Platform {
|
pub enum Platform {
|
||||||
|
/// Generic platform
|
||||||
Any,
|
Any,
|
||||||
|
/// Decky aka PluginLoader platform
|
||||||
Decky,
|
Decky,
|
||||||
|
/// Crankshaft platform
|
||||||
Crankshaft,
|
Crankshaft,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform {
|
impl Platform {
|
||||||
|
/// The current platform that usdpl-core is configured to target.
|
||||||
|
/// This is determined by feature flags.
|
||||||
pub fn current() -> Self {
|
pub fn current() -> Self {
|
||||||
#[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))]
|
#[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))]
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Datatypes and constants core the back-end and front-end libraries' operation.
|
//! Datatypes and constants core the back-end and front-end libraries' operation.
|
||||||
//! This contains serialization functionality and networking datatypes.
|
//! This contains serialization functionality and networking datatypes.
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
mod remote_call;
|
mod remote_call;
|
||||||
|
|
||||||
#[cfg(not(any(feature = "decky", feature = "crankshaft")))]
|
#[cfg(not(any(feature = "decky", feature = "crankshaft")))]
|
||||||
|
@ -15,6 +17,8 @@ pub mod socket;
|
||||||
|
|
||||||
pub use remote_call::{RemoteCall, RemoteCallResponse};
|
pub use remote_call::{RemoteCall, RemoteCallResponse};
|
||||||
|
|
||||||
|
/// USDPL core API.
|
||||||
|
/// This contains functionality used in both the back-end and front-end.
|
||||||
pub mod api {
|
pub mod api {
|
||||||
#[cfg(not(any(feature = "decky", feature = "crankshaft")))]
|
#[cfg(not(any(feature = "decky", feature = "crankshaft")))]
|
||||||
pub use super::api_any::*;
|
pub use super::api_any::*;
|
||||||
|
|
|
@ -2,8 +2,11 @@ use crate::serdes::{DumpError, Dumpable, LoadError, Loadable, Primitive};
|
||||||
|
|
||||||
/// Remote call packet representing a function to call on the back-end, sent from the front-end
|
/// Remote call packet representing a function to call on the back-end, sent from the front-end
|
||||||
pub struct RemoteCall {
|
pub struct RemoteCall {
|
||||||
|
/// The call id assigned by the front-end
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
|
/// The function's name
|
||||||
pub function: String,
|
pub function: String,
|
||||||
|
/// The function's input parameters
|
||||||
pub parameters: Vec<Primitive>,
|
pub parameters: Vec<Primitive>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +37,9 @@ impl Dumpable for RemoteCall {
|
||||||
|
|
||||||
/// Remote call response packet representing the response from a remote call after the back-end has executed it.
|
/// Remote call response packet representing the response from a remote call after the back-end has executed it.
|
||||||
pub struct RemoteCallResponse {
|
pub struct RemoteCallResponse {
|
||||||
|
/// The call id from the RemoteCall
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
|
/// The function's result
|
||||||
pub response: Vec<Primitive>,
|
pub response: Vec<Primitive>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,30 @@ use super::{DumpError, Dumpable, LoadError, Loadable};
|
||||||
/// Primitive types supported for communication between the USDPL back- and front-end.
|
/// Primitive types supported for communication between the USDPL back- and front-end.
|
||||||
/// These are used for sending over the TCP connection.
|
/// These are used for sending over the TCP connection.
|
||||||
pub enum Primitive {
|
pub enum Primitive {
|
||||||
|
/// Null or unsupported object
|
||||||
Empty,
|
Empty,
|
||||||
|
/// String-like
|
||||||
String(String),
|
String(String),
|
||||||
|
/// f32
|
||||||
F32(f32),
|
F32(f32),
|
||||||
|
/// f64
|
||||||
F64(f64),
|
F64(f64),
|
||||||
|
/// u32
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
/// u64
|
||||||
U64(u64),
|
U64(u64),
|
||||||
|
/// i32
|
||||||
I32(i32),
|
I32(i32),
|
||||||
|
/// i64
|
||||||
I64(i64),
|
I64(i64),
|
||||||
|
/// boolean
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
/// Non-primitive in Json format
|
||||||
Json(String),
|
Json(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Primitive {
|
impl Primitive {
|
||||||
|
/// Discriminant -- first byte of a dumped primitive
|
||||||
const fn discriminant(&self) -> u8 {
|
const fn discriminant(&self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
Self::Empty => 1,
|
Self::Empty => 1,
|
||||||
|
|
|
@ -5,8 +5,11 @@ const B64_CONF: Config = Config::new(base64::CharacterSet::Standard, true);
|
||||||
/// Errors from Loadable::load
|
/// Errors from Loadable::load
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LoadError {
|
pub enum LoadError {
|
||||||
|
/// Buffer smaller than expected
|
||||||
TooSmallBuffer,
|
TooSmallBuffer,
|
||||||
|
/// Unexpected/corrupted data encountered
|
||||||
InvalidData,
|
InvalidData,
|
||||||
|
/// Unimplemented
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
Todo,
|
Todo,
|
||||||
}
|
}
|
||||||
|
@ -28,6 +31,7 @@ pub trait Loadable: Sized {
|
||||||
/// If anything is wrong with the buffer, None should be returned.
|
/// If anything is wrong with the buffer, None should be returned.
|
||||||
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError>;
|
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError>;
|
||||||
|
|
||||||
|
/// Load data from a base64-encoded buffer
|
||||||
fn load_base64(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
|
fn load_base64(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
|
||||||
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
|
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
|
||||||
let len = decode_config_slice(buffer, B64_CONF, &mut buffer2)
|
let len = decode_config_slice(buffer, B64_CONF, &mut buffer2)
|
||||||
|
@ -39,8 +43,11 @@ pub trait Loadable: Sized {
|
||||||
/// Errors from Dumpable::dump
|
/// Errors from Dumpable::dump
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DumpError {
|
pub enum DumpError {
|
||||||
|
/// Buffer not big enough to dump data into
|
||||||
TooSmallBuffer,
|
TooSmallBuffer,
|
||||||
|
/// Data cannot be dumped
|
||||||
Unsupported,
|
Unsupported,
|
||||||
|
/// Unimplemented
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
Todo,
|
Todo,
|
||||||
}
|
}
|
||||||
|
@ -62,6 +69,8 @@ pub trait Dumpable {
|
||||||
/// If anything is wrong, false should be returned.
|
/// If anything is wrong, false should be returned.
|
||||||
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError>;
|
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError>;
|
||||||
|
|
||||||
|
/// Dump data as base64-encoded.
|
||||||
|
/// Useful for transmitting data as text.
|
||||||
fn dump_base64(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
|
fn dump_base64(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
|
||||||
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
|
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
|
||||||
let len = self.dump(&mut buffer2)?;
|
let len = self.dump(&mut buffer2)?;
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
|
//! Web messaging
|
||||||
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||||
|
|
||||||
use crate::serdes::{DumpError, Dumpable, LoadError, Loadable};
|
use crate::serdes::{DumpError, Dumpable, LoadError, Loadable};
|
||||||
use crate::{RemoteCall, RemoteCallResponse};
|
use crate::{RemoteCall, RemoteCallResponse};
|
||||||
|
|
||||||
pub const HOST_STR: &str = "127.0.0.1";
|
/// Host IP address for web browsers
|
||||||
|
pub const HOST_STR: &str = "localhost";
|
||||||
|
/// Host IP address
|
||||||
pub const HOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
|
pub const HOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
|
||||||
|
|
||||||
|
/// Standard max packet size
|
||||||
pub const PACKET_BUFFER_SIZE: usize = 1024;
|
pub const PACKET_BUFFER_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
/// Address and port
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn socket_addr(port: u16) -> SocketAddr {
|
pub fn socket_addr(port: u16) -> SocketAddr {
|
||||||
SocketAddr::V4(SocketAddrV4::new(HOST, port))
|
SocketAddr::V4(SocketAddrV4::new(HOST, port))
|
||||||
|
@ -15,13 +20,21 @@ pub fn socket_addr(port: u16) -> SocketAddr {
|
||||||
|
|
||||||
/// Accepted Packet types and the data they contain
|
/// Accepted Packet types and the data they contain
|
||||||
pub enum Packet {
|
pub enum Packet {
|
||||||
|
/// A remote call
|
||||||
Call(RemoteCall),
|
Call(RemoteCall),
|
||||||
|
/// A reponse to a remote call
|
||||||
CallResponse(RemoteCallResponse),
|
CallResponse(RemoteCallResponse),
|
||||||
|
/// Unused
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
|
/// Invalid
|
||||||
Invalid,
|
Invalid,
|
||||||
|
/// General message
|
||||||
Message(String),
|
Message(String),
|
||||||
|
/// Response to an unsupported packet
|
||||||
Unsupported,
|
Unsupported,
|
||||||
|
/// Broken packet type, useful for testing
|
||||||
Bad,
|
Bad,
|
||||||
|
/// Many packets merged into one
|
||||||
Many(Vec<Packet>),
|
Many(Vec<Packet>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
[package]
|
[package]
|
||||||
name = "usdpl"
|
name = "usdpl-front"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
repository = "https://github.com/NGnius/usdpl-rs"
|
repository = "https://github.com/NGnius/usdpl-rs"
|
||||||
readme = "../README.md"
|
readme = "README.md"
|
||||||
description = "Universal Steam Deck Plugin Library front-end designed for WASM"
|
description = "Universal Steam Deck Plugin Library front-end designed for WASM"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["console_error_panic_hook"]
|
default = []
|
||||||
decky = []
|
decky = ["usdpl-core/decky"]
|
||||||
crankshaft = []
|
crankshaft = ["usdpl-core/crankshaft"]
|
||||||
|
debug = ["console_error_panic_hook"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
|
@ -40,14 +41,10 @@ web-sys = { version = "0.3", features = [
|
||||||
'RequestMode',
|
'RequestMode',
|
||||||
'Response',
|
'Response',
|
||||||
'Window',
|
'Window',
|
||||||
]}#["WebSocket", "MessageEvent", "ErrorEvent", "BinaryType"] }
|
]}
|
||||||
js-sys = { version = "0.3" }
|
js-sys = { version = "0.3" }
|
||||||
|
|
||||||
usdpl-core = { version = "0.4.0", path = "../usdpl-core" }
|
usdpl-core = { version = "0.4.0", path = "../usdpl-core" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "0.3.13"
|
wasm-bindgen-test = { version = "0.3.13" }
|
||||||
|
|
||||||
#[profile.release]
|
|
||||||
# Tell `rustc` to optimize for small code size.
|
|
||||||
#opt-level = "s"
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-front?style=flat-square)](https://crates.io/crates/usdpl-front)
|
||||||
|
|
||||||
|
# usdpl-front-front
|
||||||
|
|
||||||
|
Front-end library to be called from Javascript.
|
||||||
|
Targets WASM.
|
||||||
|
|
||||||
|
In true Javascript tradition, this part of the library does not support error handling.
|
||||||
|
|
5
usdpl-front/README.tpl
Normal file
5
usdpl-front/README.tpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[![Crates.io](https://img.shields.io/crates/v/usdpl-front?style=flat-square)](https://crates.io/crates/usdpl-front)
|
||||||
|
|
||||||
|
# {{crate}}-front
|
||||||
|
|
||||||
|
{{readme}}
|
|
@ -1,11 +1,11 @@
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("Embedding WASM into udspl.js")
|
print("Embedding WASM into udspl_front.js")
|
||||||
# assumption: current working directory (relative to this script) is ../
|
# assumption: current working directory (relative to this script) is ../
|
||||||
# assumption: release wasm binary at ./pkg/usdpl_bg.wasm
|
# assumption: release wasm binary at ./pkg/usdpl_bg.wasm
|
||||||
with open("./pkg/usdpl_bg.wasm", mode="rb") as infile:
|
with open("./pkg/usdpl_front_bg.wasm", mode="rb") as infile:
|
||||||
with open("./pkg/usdpl.js", mode="ab") as outfile:
|
with open("./pkg/usdpl_front.js", mode="ab") as outfile:
|
||||||
outfile.write("\n\n// USDPL customization\nconst encoded = \"".encode())
|
outfile.write("\n\n// USDPL customization\nconst encoded = \"".encode())
|
||||||
encoded = base64.b64encode(infile.read())
|
encoded = base64.b64encode(infile.read())
|
||||||
outfile.write(encoded)
|
outfile.write(encoded)
|
||||||
|
@ -32,6 +32,6 @@ export function init_embedded() {
|
||||||
return init(decode())
|
return init(decode())
|
||||||
}
|
}
|
||||||
""".encode())
|
""".encode())
|
||||||
with open("./pkg/usdpl.d.ts", "a") as outfile:
|
with open("./pkg/usdpl_front.d.ts", "a") as outfile:
|
||||||
outfile.write("\n\n// USDPL customization\nexport function init_embedded();\n")
|
outfile.write("\n\n// USDPL customization\nexport function init_embedded();\n")
|
||||||
print("Done: Embedded WASM into udspl.js")
|
print("Done: Embedded WASM into udspl_front.js")
|
||||||
|
|
|
@ -2,12 +2,15 @@ use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||||
pub fn console_log(s: &str);
|
pub fn console_log(s: &str);
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = warn)]
|
#[wasm_bindgen(js_namespace = console, js_name = warn)]
|
||||||
pub fn console_warn(s: &str);
|
pub fn console_warn(s: &str);
|
||||||
|
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
#[wasm_bindgen(js_namespace = console, js_name = error)]
|
#[wasm_bindgen(js_namespace = console, js_name = error)]
|
||||||
pub fn console_error(s: &str);
|
pub fn console_error(s: &str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//!
|
//!
|
||||||
//! In true Javascript tradition, this part of the library does not support error handling.
|
//! In true Javascript tradition, this part of the library does not support error handling.
|
||||||
//!
|
//!
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
mod connection;
|
mod connection;
|
||||||
mod convert;
|
mod convert;
|
||||||
|
@ -17,9 +18,9 @@ use usdpl_core::{socket::Packet, RemoteCall};
|
||||||
|
|
||||||
static mut CTX: UsdplContext = UsdplContext { port: 31337, id: 1 };
|
static mut CTX: UsdplContext = UsdplContext { port: 31337, id: 1 };
|
||||||
|
|
||||||
#[wasm_bindgen]
|
//#[wasm_bindgen]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UsdplContext {
|
struct UsdplContext {
|
||||||
port: u16,
|
port: u16,
|
||||||
id: u64,
|
id: u64,
|
||||||
}
|
}
|
||||||
|
@ -62,6 +63,7 @@ pub fn target() -> String {
|
||||||
/// Returns null (None) if this fails for any reason.
|
/// Returns null (None) if this fails for any reason.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
imports::console_log(&format!(
|
imports::console_log(&format!(
|
||||||
"call_backend({}, [params; {}])",
|
"call_backend({}, [params; {}])",
|
||||||
name,
|
name,
|
||||||
|
@ -73,6 +75,7 @@ pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
params.push(convert::js_to_primitive(val));
|
params.push(convert::js_to_primitive(val));
|
||||||
}
|
}
|
||||||
let port = get_port();
|
let port = get_port();
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
imports::console_log(&format!("USDPL: Got port {}", port));
|
imports::console_log(&format!("USDPL: Got port {}", port));
|
||||||
let results = connection::send_js(
|
let results = connection::send_js(
|
||||||
Packet::Call(RemoteCall {
|
Packet::Call(RemoteCall {
|
||||||
|
@ -85,7 +88,9 @@ pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
|
||||||
.await;
|
.await;
|
||||||
let results = match results {
|
let results = match results {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
|
#[allow(unused_variables)]
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
imports::console_error(&format!("USDPL: Got error while calling {}: {:?}", name, e));
|
imports::console_error(&format!("USDPL: Got error while calling {}: {:?}", name, e));
|
||||||
return JsValue::NULL;
|
return JsValue::NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue