1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
// Copyright (c) 2021 Open Community Project Association https://ocpa.ch
// This software is published under the AGPLv3 license.
//! # Run Libqaul in an own Thread
//!
//! Start libqaul in an own thread and communicate
//! via a sync mpsc queues into and from this thread.
//!
//! This setup is to decouple the GUI thread from
//! libqaul.
//! The communication will happen via protobuf rpc messages.
use crossbeam_channel::TryRecvError;
use directories::ProjectDirs;
use futures::executor::block_on;
use std::collections::BTreeMap;
use std::thread;
use crate::rpc::sys::Sys;
use crate::rpc::Rpc;
/// C API module
mod c;
/// android module
/// The module only compiled, when the compile target is android.
#[cfg(target_os = "android")]
mod android;
/// start libqaul in an own thread
///
/// Provide the location for storage, all data of qaul will be saved there.
pub fn start(storage_path: String) {
self::start_with_config(storage_path, None);
}
/// start libqaul in an own thread
///
/// * Provide the location for storage, all data of qaul will be saved there.
/// * Optionally provide some configuration options, to initially configure libqaul to your needs.
/// the following options can be provided:
/// * Internet module listening port. By default this port is randomly assigned.
pub fn start_with_config(storage_path: String, config: Option<BTreeMap<String, String>>) {
// Spawn new thread
thread::spawn(move || {
block_on(async move {
// start libqaul
crate::start(storage_path, config).await;
})
});
}
/// start libqaul on a desktop platform (Linux, Mac, Windows)
///
/// It will automatically define the path to the common OS specific
/// configuration and data location.
///
/// The locations are:
///
/// * Linux: /home/USERNAME/.config/qaul
/// * MacOS: /Users/USERNAME/Library/Application Support/net.qaul.qaul
/// * in flutter app: /Users/USERNAME/Library/Containers/net.qaul.qaulApp/Application Support/net.qaul.qaul
/// * Windows: C:\Users\USERNAME\AppData\Roaming\qaul\qaul\config
pub fn start_desktop() {
log::trace!("start_desktop");
// create path
if let Some(proj_dirs) = ProjectDirs::from("net", "qaul", "qaul") {
// get path
let path = proj_dirs.config_dir();
log::trace!("configuration path: {:?}", path);
// check if path already exists
if !path.exists() {
log::trace!("create path");
// create path if it does not exist
std::fs::create_dir_all(path).unwrap();
}
log::trace!("start libqaul");
// start the library with the path
self::start_with_config(path.to_str().unwrap().to_string(), None);
} else {
log::error!("Configuration path couldn't be created.");
}
}
/// start libqaul for android
/// here for debugging and testing
///
/// Hand over the path on the file system
/// where the app is allowed to store data.
pub fn start_android(storage_path: String) {
// start libqaul in an own thread
self::start_with_config(storage_path, None);
}
/// Check if libqaul finished initializing
///
/// The initialization of libqaul can take several seconds.
/// If you send any message before it finished initializing, libqaul will crash.
/// Wait therefore until this function returns true before sending anything to libqaul.
pub fn initialization_finished() -> bool {
if let Some(_) = crate::INITIALIZED.try_get() {
return true;
}
false
}
/// send an RPC message to libqaul
pub fn send_rpc(binary_message: Vec<u8>) {
Rpc::send_to_libqaul(binary_message);
}
/// receive a RPC message from libqaul
pub fn receive_rpc() -> Result<Vec<u8>, TryRecvError> {
Rpc::receive_from_libqaul()
}
/// count of rpc messages to receive in the queue
pub fn receive_rpc_queued() -> usize {
Rpc::receive_from_libqaul_queue_length()
}
/// count of sent rpc messages
pub fn send_rpc_count() -> i32 {
Rpc::send_rpc_count()
}
/// send a SYS message to libqaul
pub fn send_sys(binary_message: Vec<u8>) {
Sys::send_to_libqaul(binary_message);
}
/// receive a SYS message from libqaul
pub fn receive_sys() -> Result<Vec<u8>, TryRecvError> {
Sys::receive_from_libqaul()
}