Improve build scripts and framework to get WASM loaded on Steam Deck
This commit is contained in:
parent
eaf193a1b2
commit
ccd3969185
14 changed files with 291 additions and 93 deletions
|
@ -3,9 +3,16 @@ name = "usdpl-rs"
|
|||
version = "0.1.0"
|
||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/NGnius/usdpl-rs"
|
||||
readme = "README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[profile.release]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"usdpl-core",
|
||||
|
|
45
build.sh
Executable file
45
build.sh
Executable file
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$1" ]; then
|
||||
if [ "$1" == "--help" ]; then
|
||||
echo "Usage:
|
||||
$0 [decky|crankshaft|<nothing>]"
|
||||
exit 0
|
||||
elif [ "$1" == "decky" ]; then
|
||||
echo "Building back & front for decky framework"
|
||||
# usdpl-back
|
||||
cd ./usdpl-back
|
||||
./build.sh decky
|
||||
# usdpl-front
|
||||
cd ../usdpl-front
|
||||
./build.sh decky
|
||||
cd ..
|
||||
echo "Built usdpl back & front for decky"
|
||||
elif [ "$1" == "crankshaft" ]; then
|
||||
echo "WARNING: crankshaft is unimplemented"
|
||||
echo "Building back & front for crankshaft framework"
|
||||
# usdpl-back
|
||||
cd ./usdpl-back
|
||||
./build.sh crankshaft
|
||||
# usdpl-front
|
||||
cd ../usdpl-front
|
||||
./build.sh crankshaft
|
||||
cd ..
|
||||
echo "Built usdpl back & front for crankshaft"
|
||||
else
|
||||
echo "Unsupported plugin framework \`$1\`"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Building for any plugin framework, which may not work for every framework"
|
||||
echo "Building back & front for any framework"
|
||||
# usdpl-back
|
||||
echo "...Running usdpl-back build..."
|
||||
cd ./usdpl-back
|
||||
cargo build --release
|
||||
# usdpl-front
|
||||
echo "...Running usdpl-front build..."
|
||||
cd ../usdpl-front
|
||||
./build.sh crankshaft
|
||||
cd ..
|
||||
echo "Built usdpl back & front for any"
|
||||
fi
|
|
@ -2,8 +2,14 @@
|
|||
name = "usdpl-back"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/NGnius/usdpl-rs"
|
||||
readme = "../README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[features]
|
||||
default = []
|
||||
decky = []
|
||||
crankshaft = []
|
||||
|
||||
[dependencies]
|
||||
usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
||||
|
|
20
usdpl-back/build.sh
Executable file
20
usdpl-back/build.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$1" ]; then
|
||||
if [ "$1" == "--help" ]; then
|
||||
echo "Usage:
|
||||
$0 [decky|crankshaft|<nothing>]"
|
||||
exit 0
|
||||
elif [ "$1" == "decky" ]; then
|
||||
echo "Building back-end module for decky framework"
|
||||
cargo build --release --features decky
|
||||
elif [ "$1" == "crankshaft" ]; then
|
||||
echo "WARNING: crankshaft support is unimplemented"
|
||||
cargo build --release --features crankshaft
|
||||
else
|
||||
echo "Unsupported plugin framework \`$1\`"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Building for any plugin framework, which may not work for every framework"
|
||||
cargo build --release
|
||||
fi
|
|
@ -1,4 +1,4 @@
|
|||
use std::net::TcpListener;
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
|
@ -8,13 +8,15 @@ use usdpl_core::{RemoteCallResponse, socket};
|
|||
/// Instance for interacting with the front-end
|
||||
pub struct Instance<'a> {
|
||||
calls: HashMap<String, &'a mut dyn FnMut(Vec<Primitive>) -> Vec<Primitive>>,
|
||||
port: u16,
|
||||
}
|
||||
|
||||
impl<'a> Instance<'a> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
pub fn new(port_usdpl: u16) -> Self {
|
||||
Instance {
|
||||
calls: HashMap::new(),
|
||||
port: port_usdpl,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,15 +26,7 @@ impl<'a> Instance<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Receive and execute callbacks forever
|
||||
pub fn serve<const ERROR: bool>(&mut self) -> std::io::Result<()> {
|
||||
let listener = TcpListener::bind(socket::socket_addr())?;
|
||||
for incoming in listener.incoming() {
|
||||
let mut incoming = incoming?;
|
||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let len = incoming.read(&mut buffer)?;
|
||||
let (obj_maybe, _) = socket::Packet::load(&buffer[..len]);
|
||||
if let Some(packet) = obj_maybe {
|
||||
fn handle_packet<const ERROR: bool>(&mut self, packet: socket::Packet, buffer: &mut [u8], incoming: &mut TcpStream) -> std::io::Result<()> {
|
||||
match packet {
|
||||
socket::Packet::Call(obj) => {
|
||||
if let Some(target_func) = self.calls.get_mut(&obj.function) {
|
||||
|
@ -42,7 +36,7 @@ impl<'a> Instance<'a> {
|
|||
id: obj.id,
|
||||
response: result,
|
||||
});
|
||||
let (ok, len) = response.dump(&mut buffer);
|
||||
let (ok, len) = response.dump(buffer);
|
||||
if !ok && ERROR {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump return value of function `{}`", &obj.function)));
|
||||
}
|
||||
|
@ -60,8 +54,22 @@ impl<'a> Instance<'a> {
|
|||
|
||||
}
|
||||
},
|
||||
socket::Packet::Many(many) => {
|
||||
for packet in many {
|
||||
if let socket::Packet::Many(_) = packet {
|
||||
// drop nested socket packets (prevents DoS and bad practices)
|
||||
if ERROR {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid nested Many packet received from {}", incoming.peer_addr()?)));
|
||||
} else {
|
||||
eprintln!("Invalid nested Many packet received from {}", incoming.peer_addr()?);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
self.handle_packet::<ERROR>(packet, buffer, incoming)?;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let (ok, len) = socket::Packet::Unsupported.dump(&mut buffer);
|
||||
let (ok, len) = socket::Packet::Unsupported.dump(buffer);
|
||||
if !ok && ERROR {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump unsupported packet")));
|
||||
}
|
||||
|
@ -72,6 +80,25 @@ impl<'a> Instance<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn serve<const ERROR: bool>(&mut self) -> std::io::Result<()> {
|
||||
let result = self.serve_internal::<ERROR>();
|
||||
//println!("Stopping server due to serve_internal returning a result");
|
||||
result
|
||||
}
|
||||
|
||||
/// Receive and execute callbacks forever
|
||||
pub fn serve_internal<const ERROR: bool>(&mut self) -> std::io::Result<()> {
|
||||
let listener = TcpListener::bind(socket::socket_addr(self.port))?;
|
||||
for incoming in listener.incoming() {
|
||||
let mut incoming = incoming?;
|
||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let len = incoming.read(&mut buffer)?;
|
||||
let (obj_maybe, _) = socket::Packet::load(&buffer[..len]);
|
||||
if let Some(packet) = obj_maybe {
|
||||
self.handle_packet::<ERROR>(packet, &mut buffer, &mut incoming)?;
|
||||
} else {
|
||||
if ERROR {
|
||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid packet received from {}", incoming.peer_addr()?)));
|
||||
|
@ -90,10 +117,12 @@ mod tests {
|
|||
use std::net::TcpStream;
|
||||
use super::*;
|
||||
|
||||
const PORT: u16 = 31337;
|
||||
|
||||
#[test]
|
||||
fn serve_full_test() -> std::io::Result<()> {
|
||||
let _server = std::thread::spawn(|| {
|
||||
Instance::new()
|
||||
Instance::new(PORT, PORT + 80)
|
||||
.register("echo".to_string(), &mut |params| params)
|
||||
.register("hello".to_string(), &mut |params| {
|
||||
if let Some(Primitive::String(name)) = params.get(0) {
|
||||
|
@ -105,7 +134,7 @@ mod tests {
|
|||
.serve::<true>()
|
||||
});
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
let mut front = TcpStream::connect(socket::socket_addr()).unwrap();
|
||||
let mut front = TcpStream::connect(socket::socket_addr(PORT)).unwrap();
|
||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let call = socket::Packet::Call(usdpl_core::RemoteCall {
|
||||
id: 42,
|
||||
|
@ -140,13 +169,13 @@ mod tests {
|
|||
fn serve_err_test() {
|
||||
let _client = std::thread::spawn(|| {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
let mut front = TcpStream::connect(socket::socket_addr()).unwrap();
|
||||
let mut front = TcpStream::connect(socket::socket_addr(PORT+1)).unwrap();
|
||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let (_, len) = socket::Packet::Bad.dump(&mut buffer);
|
||||
front.write(&buffer[..len]).unwrap();
|
||||
let _ = front.read(&mut buffer).unwrap();
|
||||
});
|
||||
Instance::new()
|
||||
Instance::new(PORT+1, PORT+1+80)
|
||||
.register("echo".to_string(), &mut |params| params)
|
||||
.register("hello".to_string(), &mut |params| {
|
||||
if let Some(Primitive::String(name)) = params.get(0) {
|
||||
|
@ -163,7 +192,7 @@ mod tests {
|
|||
#[should_panic]
|
||||
fn serve_unsupported_test() {
|
||||
let _server = std::thread::spawn(|| {
|
||||
Instance::new()
|
||||
Instance::new(PORT+2, PORT+2+80)
|
||||
.register("echo".to_string(), &mut |params| params)
|
||||
.register("hello".to_string(), &mut |params| {
|
||||
if let Some(Primitive::String(name)) = params.get(0) {
|
||||
|
@ -175,7 +204,7 @@ mod tests {
|
|||
.serve::<true>()
|
||||
});
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
let mut front = TcpStream::connect(socket::socket_addr()).unwrap();
|
||||
let mut front = TcpStream::connect(socket::socket_addr(PORT+2)).unwrap();
|
||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||
let (ok, len) = socket::Packet::Unsupported.dump(&mut buffer);
|
||||
assert!(ok, "Packet dump failed");
|
||||
|
|
|
@ -7,3 +7,7 @@
|
|||
mod instance;
|
||||
|
||||
pub use instance::Instance;
|
||||
|
||||
pub mod core {
|
||||
pub use usdpl_core::*;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
name = "usdpl-core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/NGnius/usdpl-rs"
|
||||
readme = "../README.md"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -3,17 +3,14 @@ use std::net::{SocketAddrV4, SocketAddr, Ipv4Addr};
|
|||
use crate::serdes::{Loadable, Dumpable};
|
||||
use crate::{RemoteCall, RemoteCallResponse};
|
||||
|
||||
pub const PORT: u16 = 31337;
|
||||
pub const HTTP_PORT: u16 = 31338;
|
||||
pub const HOST_STR: &str = "127.0.0.1";
|
||||
pub const HOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
|
||||
pub const SOCKET_ADDR_STR: &str = "127.0.0.1:31337";
|
||||
//pub const SOCKET_ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(HOST, PORT));
|
||||
|
||||
pub const PACKET_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
pub fn socket_addr() -> SocketAddr {
|
||||
SocketAddr::V4(SocketAddrV4::new(HOST, PORT))
|
||||
#[inline]
|
||||
pub fn socket_addr(port: u16) -> SocketAddr {
|
||||
SocketAddr::V4(SocketAddrV4::new(HOST, port))
|
||||
}
|
||||
|
||||
pub enum Packet {
|
||||
|
@ -24,6 +21,7 @@ pub enum Packet {
|
|||
Message(String),
|
||||
Unsupported,
|
||||
Bad,
|
||||
Many(Vec<Packet>),
|
||||
}
|
||||
|
||||
impl Packet {
|
||||
|
@ -36,6 +34,7 @@ impl Packet {
|
|||
Self::Message(_) => 5,
|
||||
Self::Unsupported => 6,
|
||||
Self::Bad => 7,
|
||||
Self::Many(_) => 8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +62,10 @@ impl Loadable for Packet {
|
|||
},
|
||||
6 => (Some(Self::Unsupported), 0),
|
||||
7 => (None, 0),
|
||||
8 => {
|
||||
let (obj, len) = <_>::load(&buf[1..]);
|
||||
(obj.map(Self::Many), len)
|
||||
}
|
||||
_ => (None, 0)
|
||||
};
|
||||
result.1 += 1;
|
||||
|
@ -84,6 +87,7 @@ impl Dumpable for Packet {
|
|||
Self::Message(s) => s.dump(&mut buf[1..]),
|
||||
Self::Unsupported => (true, 0),
|
||||
Self::Bad => (false, 0),
|
||||
Self::Many(v) => v.dump(&mut buf[1..]),
|
||||
};
|
||||
result.1 += 1;
|
||||
result
|
||||
|
|
|
@ -4,12 +4,17 @@ description = "WASM front-end library for USDPL"
|
|||
version = "0.1.0"
|
||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-only"
|
||||
repository = "https://github.com/NGnius/usdpl-rs"
|
||||
readme = "../README.md"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook"]
|
||||
decky = []
|
||||
crankshaft = []
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.63"
|
||||
|
@ -35,6 +40,6 @@ usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
|||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.13"
|
||||
|
||||
[profile.release]
|
||||
#[profile.release]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
||||
#opt-level = "s"
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$1" ]; then
|
||||
if [ "$1" == "--help" ]; then
|
||||
echo "Usage:
|
||||
$0 [decky|crankshaft|<nothing>]"
|
||||
exit 0
|
||||
elif [ "$1" == "decky" ]; then
|
||||
echo "Building WASM module for decky framework"
|
||||
wasm-pack build --target web --features decky
|
||||
elif [ "$1" == "crankshaft" ]; then
|
||||
echo "WARNING: crankshaft support is unimplemented"
|
||||
wasm-pack build --target web --features crankshaft
|
||||
else
|
||||
echo "Unsupported plugin framework \`$1\`"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "WARNING: Building for any plugin framework, which may not work for every framework"
|
||||
wasm-pack build --target web
|
||||
fi
|
||||
|
||||
wasm-pack build --target web
|
||||
python3 ./scripts/generate_embedded_wasm.py
|
||||
|
|
37
usdpl-front/scripts/generate_embedded_wasm.py
Normal file
37
usdpl-front/scripts/generate_embedded_wasm.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import base64
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Embedding WASM into udspl.js")
|
||||
# assumption: current working directory (relative to this script) is ../
|
||||
# assumption: release wasm binary at ./pkg/usdpl_bg.wasm
|
||||
with open("./pkg/usdpl_bg.wasm", mode="rb") as infile:
|
||||
with open("./pkg/usdpl.js", mode="ab") as outfile:
|
||||
outfile.write("\n\n// USDPL customization\nconst encoded = \"".encode())
|
||||
encoded = base64.b64encode(infile.read())
|
||||
outfile.write(encoded)
|
||||
outfile.write("\";\n\n".encode())
|
||||
outfile.write(
|
||||
"""function asciiToBinary(str) {
|
||||
if (typeof atob === 'function') {
|
||||
return atob(str)
|
||||
} else {
|
||||
return new Buffer(str, 'base64').toString('binary');
|
||||
}
|
||||
}
|
||||
|
||||
function decode() {
|
||||
var binaryString = asciiToBinary(encoded);
|
||||
var bytes = new Uint8Array(binaryString.length);
|
||||
for (var i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
return (async function() {return new Response(bytes.buffer);})();
|
||||
}
|
||||
|
||||
export function init_embedded() {
|
||||
return init(decode())
|
||||
}
|
||||
""".encode())
|
||||
with open("./pkg/usdpl.d.ts", "a") as outfile:
|
||||
outfile.write("\n\n// USDPL customization\nexport function init_embedded();\n")
|
||||
print("Done: Embedded WASM into udspl.js")
|
|
@ -8,8 +8,8 @@ use usdpl_core::socket;
|
|||
use usdpl_core::serdes::{Dumpable, Loadable};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn send(packet: socket::Packet) -> bool {
|
||||
let socket = match TcpSocket::new(socket::HOST_STR, socket::PORT) {
|
||||
pub(crate) fn send(packet: socket::Packet, port: u16) -> bool {
|
||||
let socket = match TcpSocket::new(socket::HOST_STR, port) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
@ -30,8 +30,8 @@ pub(crate) fn send(packet: socket::Packet) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn send_native(packet: socket::Packet) -> Option<socket::Packet> {
|
||||
let mut socket = match TcpStream::connect(socket::socket_addr()) {
|
||||
pub(crate) fn send_native(packet: socket::Packet, port: u16) -> Option<socket::Packet> {
|
||||
let mut socket = match TcpStream::connect(socket::socket_addr(port)) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
|
35
usdpl-front/src/convert.rs
Normal file
35
usdpl-front/src/convert.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use wasm_bindgen::prelude::JsValue;
|
||||
use js_sys::JSON::{stringify, parse};
|
||||
|
||||
use usdpl_core::serdes::Primitive;
|
||||
|
||||
pub(crate) fn primitive_to_js(primitive: Primitive) -> JsValue {
|
||||
match primitive {
|
||||
Primitive::Empty => JsValue::null(),
|
||||
Primitive::String(s) => JsValue::from_str(&s),
|
||||
Primitive::F32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::F64(f)=> JsValue::from_f64(f),
|
||||
Primitive::U32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::U64(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::I32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::I64(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::Bool(b) => JsValue::from_bool(b),
|
||||
Primitive::Json(s) => parse(&s).ok().unwrap_or(JsValue::from_str(&s)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn js_to_primitive(val: JsValue) -> Primitive {
|
||||
if let Some(b) = val.as_bool() {
|
||||
Primitive::Bool(b)
|
||||
} else if let Some(f) = val.as_f64() {
|
||||
Primitive::F64(f)
|
||||
} else if let Some(s) = val.as_string() {
|
||||
Primitive::String(s)
|
||||
} else if val.is_null() || val.is_undefined() {
|
||||
Primitive::Empty
|
||||
} else if let Ok(s) = stringify(&val) {
|
||||
Primitive::Json(s.as_string().unwrap())
|
||||
} else {
|
||||
Primitive::Empty
|
||||
}
|
||||
}
|
|
@ -5,12 +5,13 @@
|
|||
//!
|
||||
|
||||
mod connection;
|
||||
mod convert;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use js_sys::JSON::{stringify, parse};
|
||||
|
||||
use usdpl_core::{socket::Packet, RemoteCall, serdes::Primitive};
|
||||
use usdpl_core::{socket::Packet, RemoteCall};
|
||||
const REMOTE_CALL_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
|
||||
const REMOTE_PORT: std::sync::atomic::AtomicU16 = std::sync::atomic::AtomicU16::new(31337);
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global allocator.
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
|
@ -24,16 +25,22 @@ extern {
|
|||
|
||||
/// Initialize the front-end library
|
||||
#[wasm_bindgen]
|
||||
pub fn init() -> bool {
|
||||
pub fn init_usdpl(port: u16) -> bool {
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
REMOTE_PORT.store(port, std::sync::atomic::Ordering::Relaxed);
|
||||
true
|
||||
}
|
||||
|
||||
/// Get the targeted plugin framework, or "any" if unknown
|
||||
#[wasm_bindgen]
|
||||
pub fn target() -> String {
|
||||
"any".to_string()
|
||||
#[cfg(all(feature = "decky", not(any(feature = "crankshaft"))))]
|
||||
{"decky".to_string()}
|
||||
#[cfg(all(feature = "crankshaft", not(any(feature = "decky"))))]
|
||||
{"crankshaft".to_string()}
|
||||
#[cfg(not(any(feature = "decky", feature = "crankshaft")))]
|
||||
{"any".to_string()}
|
||||
}
|
||||
|
||||
/// Call a function on the back-end.
|
||||
|
@ -43,42 +50,19 @@ pub fn call_backend(name: String, parameters: Vec<JsValue>) -> Option<Vec<JsValu
|
|||
let next_id = REMOTE_CALL_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
let mut params = Vec::with_capacity(parameters.len());
|
||||
for val in parameters {
|
||||
if let Some(b) = val.as_bool() {
|
||||
params.push(Primitive::Bool(b));
|
||||
} else if let Some(f) = val.as_f64() {
|
||||
params.push(Primitive::F64(f));
|
||||
} else if let Some(s) = val.as_string() {
|
||||
params.push(Primitive::String(s));
|
||||
} else if val.is_null() || val.is_undefined() {
|
||||
params.push(Primitive::Empty);
|
||||
} else if let Ok(s) = stringify(&val) {
|
||||
params.push(Primitive::Json(s.as_string().unwrap()));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
params.push(convert::js_to_primitive(val));
|
||||
}
|
||||
let results = match connection::send_native(Packet::Call(RemoteCall {
|
||||
id: next_id,
|
||||
function: name,
|
||||
parameters: params,
|
||||
})) {
|
||||
}), REMOTE_PORT.load(std::sync::atomic::Ordering::Relaxed)) {
|
||||
Some(Packet::CallResponse(resp)) => resp,
|
||||
_ => return None,
|
||||
};
|
||||
let mut js_results = Vec::with_capacity(results.response.len());
|
||||
for val in results.response {
|
||||
let js_val = match val {
|
||||
Primitive::Empty => JsValue::null(),
|
||||
Primitive::String(s) => JsValue::from_str(&s),
|
||||
Primitive::F32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::F64(f)=> JsValue::from_f64(f),
|
||||
Primitive::U32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::U64(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::I32(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::I64(f)=> JsValue::from_f64(f as _),
|
||||
Primitive::Bool(b) => JsValue::from_bool(b),
|
||||
Primitive::Json(s) => parse(&s).ok().unwrap_or(JsValue::from_str(&s)),
|
||||
};
|
||||
let js_val = convert::primitive_to_js(val);
|
||||
js_results.push(js_val);
|
||||
}
|
||||
Some(js_results)
|
||||
|
|
Loading…
Reference in a new issue