Refinement, plugins, etc.

This commit is contained in:
Kirottu
2022-12-31 12:51:46 +02:00
parent 990bf12b79
commit ce4b157160
17 changed files with 36037 additions and 223 deletions

View File

@@ -6,9 +6,8 @@ for integrating with `stable_abi`.
# Arguments
* `$init`: Function that takes an `RString` as the only argument, which points to the anyrun config directory. It returns nothing.
The path is used for plugin specific config files.
**NOTE**: Should not block or block for a long time. If this blocks the main thread will too.
* `$init`: Function that takes an `RString` as the only argument, which points to the anyrun config directory. Returns the data
the plugin operates on.
* `$info`: Function that returns the plugin info as a `PluginInfo` object. Takes no arguments.
@@ -17,85 +16,100 @@ This is run asynchronously automatically.
* `$handler`: The function to handle the selection of an item. Takes a `Match` as it's only argument and returns a `HandleResult` with
the appropriate action.
* `$type`: The type of the shared data to be provided to various functions.
**/
#[macro_export]
macro_rules! plugin {
($init:ident, $info:ident, $get_matches:ident, $handler:ident) => {
mod anyrun_plugin_internal {
static THREAD: ::std::sync::Mutex<
Option<(
::std::thread::JoinHandle<
::abi_stable::std_types::RVec<::anyrun_plugin::anyrun_interface::Match>,
>,
u64,
)>,
> = ::std::sync::Mutex::new(None);
static ID_COUNTER: ::std::sync::atomic::AtomicU64 =
::std::sync::atomic::AtomicU64::new(0);
($init:ident, $info:ident, $get_matches:ident, $handler:ident, $type:ty) => {
static ANYRUN_INTERNAL_THREAD: ::std::sync::Mutex<
Option<(
::std::thread::JoinHandle<
::abi_stable::std_types::RVec<::anyrun_plugin::anyrun_interface::Match>,
>,
u64,
)>,
> = ::std::sync::Mutex::new(None);
static ANYRUN_INTERNAL_ID_COUNTER: ::std::sync::atomic::AtomicU64 =
::std::sync::atomic::AtomicU64::new(0);
static ANYRUN_INTERNAL_DATA: ::std::sync::Mutex<Option<$type>> =
::std::sync::Mutex::new(None);
#[::abi_stable::export_root_module]
fn init_root_module() -> ::anyrun_plugin::anyrun_interface::PluginRef {
use ::abi_stable::prefix_type::PrefixTypeTrait;
::anyrun_plugin::anyrun_interface::Plugin {
init,
info,
get_matches,
poll_matches,
handle_selection,
#[::abi_stable::export_root_module]
fn anyrun_internal_init_root_module() -> ::anyrun_plugin::anyrun_interface::PluginRef {
use ::abi_stable::prefix_type::PrefixTypeTrait;
::anyrun_plugin::anyrun_interface::Plugin {
init: anyrun_internal_init,
info: anyrun_internal_info,
get_matches: anyrun_internal_get_matches,
poll_matches: anyrun_internal_poll_matches,
handle_selection: anyrun_internal_handle_selection,
}
.leak_into_prefix()
}
#[::abi_stable::sabi_extern_fn]
fn anyrun_internal_init(config_dir: ::abi_stable::std_types::RString) {
::std::thread::spawn(|| {
*ANYRUN_INTERNAL_DATA.lock().unwrap() = Some($init(config_dir));
});
}
#[::abi_stable::sabi_extern_fn]
fn anyrun_internal_info() -> ::anyrun_plugin::anyrun_interface::PluginInfo {
$info()
}
#[::abi_stable::sabi_extern_fn]
fn anyrun_internal_get_matches(input: ::abi_stable::std_types::RString) -> u64 {
let current_id =
ANYRUN_INTERNAL_ID_COUNTER.load(::std::sync::atomic::Ordering::Relaxed);
ANYRUN_INTERNAL_ID_COUNTER
.store(current_id + 1, ::std::sync::atomic::Ordering::Relaxed);
let handle = ::std::thread::spawn(move || {
if let Some(data) = ANYRUN_INTERNAL_DATA.lock().unwrap().as_mut() {
$get_matches(input, data)
} else {
::abi_stable::std_types::RVec::new()
}
.leak_into_prefix()
}
});
#[::abi_stable::sabi_extern_fn]
fn init(config_dir: ::abi_stable::std_types::RString) {
super::$init(config_dir);
}
*ANYRUN_INTERNAL_THREAD.lock().unwrap() = Some((handle, current_id));
#[::abi_stable::sabi_extern_fn]
fn info() -> ::anyrun_plugin::anyrun_interface::PluginInfo {
super::$info()
}
current_id
}
#[::abi_stable::sabi_extern_fn]
fn get_matches(input: ::abi_stable::std_types::RString) -> u64 {
let current_id = ID_COUNTER.load(::std::sync::atomic::Ordering::Relaxed);
ID_COUNTER.store(current_id + 1, ::std::sync::atomic::Ordering::Relaxed);
let handle = ::std::thread::spawn(move || super::$get_matches(input));
*THREAD.lock().unwrap() = Some((handle, current_id));
current_id
}
#[::abi_stable::sabi_extern_fn]
fn poll_matches(id: u64) -> ::anyrun_plugin::anyrun_interface::PollResult {
match THREAD.try_lock() {
Ok(thread) => match thread.as_ref() {
Some((thread, task_id)) => {
if *task_id == id {
if !thread.is_finished() {
return ::anyrun_plugin::anyrun_interface::PollResult::Pending;
}
} else {
return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled;
#[::abi_stable::sabi_extern_fn]
fn anyrun_internal_poll_matches(id: u64) -> ::anyrun_plugin::anyrun_interface::PollResult {
match ANYRUN_INTERNAL_THREAD.try_lock() {
Ok(thread) => match thread.as_ref() {
Some((thread, task_id)) => {
if *task_id == id {
if !thread.is_finished() {
return ::anyrun_plugin::anyrun_interface::PollResult::Pending;
}
} else {
return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled;
}
None => return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled,
},
Err(_) => return ::anyrun_plugin::anyrun_interface::PollResult::Pending,
}
let (thread, _) = THREAD.lock().unwrap().take().unwrap();
::anyrun_plugin::anyrun_interface::PollResult::Ready(thread.join().unwrap())
}
None => return ::anyrun_plugin::anyrun_interface::PollResult::Cancelled,
},
Err(_) => return ::anyrun_plugin::anyrun_interface::PollResult::Pending,
}
#[::abi_stable::sabi_extern_fn]
fn handle_selection(
selection: ::anyrun_plugin::anyrun_interface::Match,
) -> ::anyrun_plugin::anyrun_interface::HandleResult {
super::$handler(selection)
}
let (thread, _) = ANYRUN_INTERNAL_THREAD.lock().unwrap().take().unwrap();
::anyrun_plugin::anyrun_interface::PollResult::Ready(thread.join().unwrap())
}
#[::abi_stable::sabi_extern_fn]
fn anyrun_internal_handle_selection(
selection: ::anyrun_plugin::anyrun_interface::Match,
) -> ::anyrun_plugin::anyrun_interface::HandleResult {
$handler(
selection,
ANYRUN_INTERNAL_DATA.lock().unwrap().as_mut().unwrap(),
)
}
};
}