fix wasm, flutter work

This commit is contained in:
John Smith
2022-01-20 22:32:22 -05:00
parent effc4aeeac
commit 2eeb8e52f2
11 changed files with 4588 additions and 180 deletions

View File

@@ -1,3 +1,5 @@
src/bridge_generated.rs
##############################################################################
### MacOS

3059
veilid-flutter/rust/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,13 @@ version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "staticlib"]
[dependencies]
async-std = { version = "^1", features = ["unstable"] }
veilid-core = { path="../../veilid-core" }
flutter_rust_bridge = "^1"
log = "^0"
[build-dependencies]
cfg-if = "^1"

View File

@@ -0,0 +1,87 @@
use cfg_if::*;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
fn resolve_llvm_path() -> Option<PathBuf> {
let paths: Vec<PathBuf> =
env::var_os("PATH").map(|paths| env::split_paths(&paths).collect())?;
cfg_if! {
if #[cfg(target_os="linux")] {
// build host is linux
// find clang
let d = paths.iter().find_map(|p| {
if p.join("clang").exists() {
if let Ok(real_clang_path) = fs::canonicalize(p.join("clang")) {
if let Some(llvmbindir) = real_clang_path.parent() {
if let Some(llvmdir) = llvmbindir.parent() {
return Some(llvmdir.to_owned());
}
}
}
}
None
});
d.or_else(|| {
["/usr/lib/llvm-13", "/usr/lib/llvm-12", "/usr/lib/llvm-11", "/usr/lib/llvm-10"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
})
} else if #[cfg(target_os="macos")] {
// build host is mac
["/opt/homebrew/opt/llvm", "/usr/local/homebrew/opt/llvm"].iter().map(Path::new).find_map(|p| if p.exists() { Some(p.to_owned()) } else { None } )
} else {
// anywhere else, just use the default paths
llvm_path = None;
}
}
}
fn main() {
//let out_dir = env::var_os("OUT_DIR").unwrap();
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
let input_path = Path::new(&manifest_dir).join("src").join("api.rs");
let output_path = Path::new(&manifest_dir)
.parent()
.unwrap()
.join("lib")
.join("bridge_generated.dart");
let llvm_path = resolve_llvm_path();
eprintln!("input_path: {:?}", input_path);
eprintln!("output_path: {:?}", output_path);
eprintln!("llvm_path: {:?}", llvm_path);
let mut command = Command::new("flutter_rust_bridge_codegen");
if let Some(llvm_path) = llvm_path {
command.args([
OsStr::new("--rust-input"),
input_path.as_os_str(),
OsStr::new("--dart-output"),
output_path.as_os_str(),
OsStr::new("--llvm-path"),
llvm_path.as_os_str(),
]);
} else {
command.args([
OsStr::new("--rust-input"),
input_path.as_os_str(),
OsStr::new("--dart-output"),
output_path.as_os_str(),
]);
}
let mut child = command
.spawn()
.expect("flutter_rust_bridge_codegen did not execute correctly");
child
.wait()
.expect("flutter_rust_bridge_codegen was not running");
println!("cargo:rerun-if-changed=src/api.c");
}

View File

@@ -1,4 +1,7 @@
use std::sync::Arc;
use flutter_rust_bridge::*;
use log::*;
use std::collections::HashMap;
/////////////////////////////////////////
// Config Settings
@@ -84,8 +87,8 @@ pub struct VeilidConfigLeases {
pub struct VeilidConfigNetwork {
pub max_connections: u32,
pub connection_initial_timeout: u64,
pub node_id: key::DHTKey,
pub node_id_secret: key::DHTKeySecret,
pub node_id: String,
pub node_id_secret: String,
pub bootstrap: Vec<String>,
pub rpc: VeilidConfigRPC,
pub dht: VeilidConfigDHT,
@@ -93,7 +96,6 @@ pub struct VeilidConfigNetwork {
pub natpmp: bool,
pub enable_local_peer_scope: bool,
pub restricted_nat_retries: u32,
pub tls: VeilidConfigTLS,
pub protocol: VeilidConfigProtocol,
pub leases: VeilidConfigLeases,
}
@@ -146,10 +148,10 @@ pub struct VeilidConfig {
/////////////////////////////////////////
#[derive(Debug)]
pub enum APIErrorKind {
pub enum VeilidAPIError {
AlreadyInitialized,
NotInitialized,
InvalidConfig,
InvalidConfig(String),
Timeout,
Shutdown,
NodeNotFound(String),
@@ -171,10 +173,20 @@ pub enum APIErrorKind {
},
}
#[derive(Debug)]
pub struct VeilidAPIError {
kind: APIErrorKind,
message: String,
impl VeilidAPIError {
fn from_core(api_error: veilid_core::VeilidAPIError) -> Self {
match api_error {
veilid_core::VeilidAPIError::Timeout => VeilidAPIError::Timeout,
veilid_core::VeilidAPIError::Shutdown => VeilidAPIError::Shutdown,
veilid_core::VeilidAPIError::NodeNotFound(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::NoDialInfo(node_id) => VeilidAPIError::NodeNotFound(format!("{}",node_id)),
veilid_core::VeilidAPIError::Internal(msg) => VeilidAPIError::Internal(msg.clone()),
veilid_core::VeilidAPIError::Unimplemented(msg)=> VeilidAPIError::Unimplemented(msg.clone()),
veilid_core::VeilidAPIError::ParseError{message, value} => VeilidAPIError::ParseError{ message: message.clone(), value: value.clone() },
veilid_core::VeilidAPIError::InvalidArgument { context, argument, value } => VeilidAPIError::InvalidArgument{ context: context.clone(), argument: argument.clone(), value: value.clone() },
veilid_core::VeilidAPIError::MissingArgument {context, argument } => VeilidAPIError::MissingArgument{ context: context.clone(), argument: argument.clone() },
}
}
}
#[derive(Debug)]
@@ -189,25 +201,185 @@ pub enum AttachmentState {
Detaching,
}
impl AttachmentState {
fn from_core(attachment_state: veilid_core::AttachmentState) -> Self {
match attachment_state {
veilid_core::AttachmentState::Detached => AttachmentState::Detached,
veilid_core::AttachmentState::Attaching=> AttachmentState::Attaching,
veilid_core::AttachmentState::AttachedWeak=> AttachmentState::AttachedWeak,
veilid_core::AttachmentState::AttachedGood=> AttachmentState::AttachedGood,
veilid_core::AttachmentState::AttachedStrong=> AttachmentState::AttachedStrong,
veilid_core::AttachmentState::FullyAttached=> AttachmentState::FullyAttached,
veilid_core::AttachmentState::OverAttached=> AttachmentState::OverAttached,
veilid_core::AttachmentState::Detaching=> AttachmentState::Detaching,
}
}
}
#[derive(Debug)]
pub enum VeilidUpdate {
Attachment (AttachmentState),
}
/////////////////////////////////////////
///
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<(), VeilidAPIError> {
let core = veilid_core::VeilidCore::new();
core.
impl VeilidUpdate {
fn from_core(veilid_update: veilid_core::VeilidUpdate) -> Self {
match veilid_update {
veilid_core::VeilidUpdate::Attachment(attachment) => Self::Attachment(AttachmentState::from_core(attachment))
}
}
}
pub fn get_veilid_state() -> Result<VeilidState, VeilidAPIError> {
#[derive(Debug)]
pub struct VeilidState {
attachment: AttachmentState,
}
impl VeilidState {
fn from_core(veilid_state: veilid_core::VeilidState) -> Self {
Self {
attachment: AttachmentState::from_core(veilid_state.attachment)
}
}
}
type Result<T> = std::result::Result<T, VeilidAPIError>;
/////////////////////////////////////////
pub fn startup_veilid_core(sink: StreamSink<VeilidUpdate>, config: VeilidConfig) -> Result<VeilidState> {
let core = veilid_core::VeilidCore::new();
// convert config to hashmap
let config_map = HashMap::<String, Box<dyn core::any::Any + 'static>>::new();
macro_rules! get_config {
($key:expr) => {
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($key.clone()));
}
}
macro_rules! default_config {
($key:expr, $default_value:expr) => {
config_map.insert(stringify!($key)[7..].to_owned(), Box::new($default_value));
}
}
get_config!(config.program_name);
get_config!(config.namespace);
get_config!(config.capabilities.protocol_udp);
get_config!(config.capabilities.protocol_connect_tcp);
get_config!(config.capabilities.protocol_accept_tcp);
get_config!(config.capabilities.protocol_connect_ws);
get_config!(config.capabilities.protocol_accept_ws);
get_config!(config.capabilities.protocol_connect_wss);
get_config!(config.capabilities.protocol_accept_wss);
get_config!(config.table_store.directory);
get_config!(config.table_store.delete);
get_config!(config.block_store.directory);
get_config!(config.block_store.delete);
get_config!(config.protected_store.allow_insecure_fallback);
get_config!(config.protected_store.always_use_insecure_storage);
get_config!(config.protected_store.insecure_fallback_directory);
get_config!(config.protected_store.delete);
get_config!(config.network.node_id);
get_config!(config.network.node_id_secret);
get_config!(config.network.max_connections);
get_config!(config.network.connection_initial_timeout);
get_config!(config.network.bootstrap);
get_config!(config.network.dht.resolve_node_timeout);
get_config!(config.network.dht.resolve_node_count);
get_config!(config.network.dht.resolve_node_fanout);
get_config!(config.network.dht.max_find_node_count);
get_config!(config.network.dht.get_value_timeout);
get_config!(config.network.dht.get_value_count);
get_config!(config.network.dht.get_value_fanout);
get_config!(config.network.dht.set_value_timeout);
get_config!(config.network.dht.set_value_count);
get_config!(config.network.dht.set_value_fanout);
get_config!(config.network.dht.min_peer_count);
get_config!(config.network.dht.min_peer_refresh_time);
get_config!(config.network.dht.validate_dial_info_receipt_time);
get_config!(config.network.rpc.concurrency);
get_config!(config.network.rpc.queue_size);
get_config!(config.network.rpc.max_timestamp_behind);
get_config!(config.network.rpc.max_timestamp_ahead);
get_config!(config.network.rpc.timeout);
get_config!(config.network.rpc.max_route_hop_count);
get_config!(config.network.upnp);
get_config!(config.network.natpmp);
get_config!(config.network.enable_local_peer_scope);
get_config!(config.network.restricted_nat_retries);
default_config!(config.network.tls.certificate_path, "");
default_config!(config.network.tls.private_key_path, "");
default_config!(config.network.tls.connection_initial_timeout, 0u64);
default_config!(config.network.application.https.enabled, false);
default_config!(config.network.application.https.listen_address, "");
default_config!(config.network.application.https.path, "");
default_config!(config.network.application.https.url, Option::<String>::None);
default_config!(config.network.application.http.enabled, false);
default_config!(config.network.application.http.listen_address, "");
default_config!(config.network.application.http.path, "");
default_config!(config.network.application.http.url, Option::<String>::None);
get_config!(config.network.protocol.udp.enabled);
get_config!(config.network.protocol.udp.socket_pool_size);
get_config!(config.network.protocol.udp.listen_address);
get_config!(config.network.protocol.udp.public_address);
get_config!(config.network.protocol.tcp.connect);
get_config!(config.network.protocol.tcp.listen);
get_config!(config.network.protocol.tcp.max_connections);
get_config!(config.network.protocol.tcp.listen_address);
get_config!(config.network.protocol.tcp.public_address);
get_config!(config.network.protocol.ws.connect);
get_config!(config.network.protocol.ws.listen);
get_config!(config.network.protocol.ws.max_connections);
get_config!(config.network.protocol.ws.listen_address);
get_config!(config.network.protocol.ws.path);
get_config!(config.network.protocol.ws.url);
get_config!(config.network.protocol.wss.connect);
default_config!(config.network.protocol.wss.listen, false);
get_config!(config.network.protocol.wss.max_connections);
default_config!(config.network.protocol.wss.listen_address, "");
default_config!(config.network.protocol.wss.path, "");
default_config!(config.network.protocol.wss.url, Option::<String>::None);
get_config!(config.network.leases.max_server_signal_leases);
get_config!(config.network.leases.max_server_relay_leases);
get_config!(config.network.leases.max_client_signal_leases);
get_config!(config.network.leases.max_client_relay_leases);
let setup = veilid_core::VeilidCoreSetup {
update_callback: Arc::new(
move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> {
Box::pin(async move {
if !sink.add(VeilidUpdate::from_core(update)) {
error!("error sending veilid update callback");
}
})
},
),
config_callback: Arc::new(
move |key| {
config_map.get(&key).ok_or_else(|| {
let err = format!("config key '{}' doesn't exist", key);
error!("{}",err);
err
}).map(|v| {
*v.clone()
})
}
),
};
async_std::task::block_on( async {
let api = core.startup(setup).await.map_err(|e| VeilidAPIError::InvalidConfig(e.clone()))?;
let core_state = api.get_state().await.map_err(VeilidAPIError::from_core)?;
Ok(VeilidState::from_core(core_state))
})
}
pub fn get_veilid_state() -> Result<VeilidState> {
}
// xxx api functions
pub fn shutdown_veilid_core() -> Result<(), VeilidAPIError> {
pub fn shutdown_veilid_core() -> Result<()> {
}