initial import of main veilid core
This commit is contained in:
140
veilid-core/src/intf/wasm/utils/channel.rs
Normal file
140
veilid-core/src/intf/wasm/utils/channel.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use crate::xx::*;
|
||||
use alloc::collections::VecDeque;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Channel<T> {
|
||||
items: VecDeque<T>,
|
||||
cap: usize,
|
||||
eventual: Eventual,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Sender<T> {
|
||||
imp: Arc<Mutex<Channel<T>>>,
|
||||
}
|
||||
|
||||
impl<T> Clone for Sender<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
imp: self.imp.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Receiver<T> {
|
||||
imp: Arc<Mutex<Channel<T>>>,
|
||||
}
|
||||
|
||||
impl<T> Clone for Receiver<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
imp: self.imp.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn channel<T>(cap: usize) -> (Sender<T>, Receiver<T>) {
|
||||
let imp = Channel {
|
||||
items: VecDeque::with_capacity(cap),
|
||||
cap: cap,
|
||||
eventual: Eventual::new(),
|
||||
};
|
||||
|
||||
let imparc = Arc::new(Mutex::new(imp));
|
||||
(
|
||||
Sender {
|
||||
imp: imparc.clone(),
|
||||
},
|
||||
Receiver {
|
||||
imp: imparc.clone(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum TrySendError<T> {
|
||||
Full(T),
|
||||
Disconnected(T),
|
||||
}
|
||||
|
||||
impl<T> Sender<T> {
|
||||
// NOTE: This needs a timeout or you could block a very long time
|
||||
// pub async fn send(&self, msg: T) -> Result<(), SendError<T>> {
|
||||
// xxx
|
||||
// }
|
||||
|
||||
pub async fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> {
|
||||
let eventual = {
|
||||
let mut inner = self.imp.lock();
|
||||
if inner.items.len() == inner.cap {
|
||||
return Err(TrySendError::Full(msg));
|
||||
}
|
||||
let empty = inner.items.is_empty();
|
||||
inner.items.push_back(msg);
|
||||
if empty {
|
||||
Some(inner.eventual.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if let Some(e) = eventual {
|
||||
e.resolve().await;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.imp.lock().cap
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.imp.lock().items.is_empty()
|
||||
}
|
||||
pub fn is_full(&self) -> bool {
|
||||
let inner = self.imp.lock();
|
||||
inner.items.len() == inner.cap
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.imp.lock().items.len()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct RecvError;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum TryRecvError {
|
||||
Empty,
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
impl<T> Receiver<T> {
|
||||
pub async fn recv(&self) -> Result<T, RecvError> {
|
||||
let eventual = {
|
||||
let inner = self.imp.lock();
|
||||
inner.eventual.clone()
|
||||
};
|
||||
while self.is_empty() {
|
||||
eventual.instance_clone(true).await;
|
||||
}
|
||||
Ok(self.imp.lock().items.pop_front().unwrap())
|
||||
}
|
||||
pub async fn try_recv(&self) -> Result<T, TryRecvError> {
|
||||
if self.is_empty() {
|
||||
return Err(TryRecvError::Empty);
|
||||
}
|
||||
Ok(self.imp.lock().items.pop_front().unwrap())
|
||||
}
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.imp.lock().cap
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.imp.lock().items.is_empty()
|
||||
}
|
||||
pub fn is_full(&self) -> bool {
|
||||
let inner = self.imp.lock();
|
||||
inner.items.len() == inner.cap
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.imp.lock().items.len()
|
||||
}
|
||||
}
|
91
veilid-core/src/intf/wasm/utils/mod.rs
Normal file
91
veilid-core/src/intf/wasm/utils/mod.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
#![cfg(target_arch = "wasm32")]
|
||||
|
||||
pub mod channel;
|
||||
|
||||
use crate::xx::*;
|
||||
use core::sync::atomic::{AtomicI8, Ordering};
|
||||
use js_sys::{global, Reflect};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "wee_alloc")] {
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
// allocator.
|
||||
extern crate wee_alloc;
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// Use `js_namespace` here to bind `console.log(..)` instead of just
|
||||
// `log(..)`
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
pub fn console_log(s: &str);
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn alert(s: &str);
|
||||
}
|
||||
|
||||
pub fn is_nodejs() -> bool {
|
||||
static CACHE: AtomicI8 = AtomicI8::new(-1);
|
||||
let cache = CACHE.load(Ordering::Relaxed);
|
||||
if cache != -1 {
|
||||
return cache != 0;
|
||||
}
|
||||
|
||||
let res = js_sys::eval("process.release.name === 'node'")
|
||||
.map(|res| res.is_truthy())
|
||||
.unwrap_or_default();
|
||||
|
||||
CACHE.store(res as i8, Ordering::Relaxed);
|
||||
res
|
||||
}
|
||||
|
||||
pub fn is_browser() -> bool {
|
||||
static CACHE: AtomicI8 = AtomicI8::new(-1);
|
||||
let cache = CACHE.load(Ordering::Relaxed);
|
||||
if cache != -1 {
|
||||
return cache != 0;
|
||||
}
|
||||
|
||||
let res = Reflect::has(&global().as_ref(), &"window".into()).unwrap_or_default();
|
||||
|
||||
CACHE.store(res as i8, Ordering::Relaxed);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn is_browser_https() -> bool {
|
||||
static CACHE: AtomicI8 = AtomicI8::new(-1);
|
||||
let cache = CACHE.load(Ordering::Relaxed);
|
||||
if cache != -1 {
|
||||
return cache != 0;
|
||||
}
|
||||
|
||||
let res = js_sys::eval("window.location.protocol === 'https'")
|
||||
.map(|res| res.is_truthy())
|
||||
.unwrap_or_default();
|
||||
|
||||
CACHE.store(res as i8, Ordering::Relaxed);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn node_require(module: &str) -> JsValue {
|
||||
if !is_nodejs() {
|
||||
return JsValue::UNDEFINED;
|
||||
}
|
||||
|
||||
let mut home = env!("CARGO_MANIFEST_DIR");
|
||||
if home.len() == 0 {
|
||||
home = ".";
|
||||
}
|
||||
|
||||
match js_sys::eval(format!("require(\"{}/{}\")", home, module).as_str()) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
panic!("node_require failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user