macro_rules! signal {
($scope:ident, $inner:expr) => { ... };
($scope:ident, server, $inner:expr) => { ... };
($scope:ident, server, clone: $($clone:ident) +, $inner:expr) => { ... };
($scope:ident, client, $inner:expr) => { ... };
($scope:ident, client, clone: $($clone:ident) +, $inner:expr) => { ... };
($scope:ident, clone: $($clone:ident) +, $data:expr) => { ... };
}
Expand description
The signal!
macro is used to create signals of all types. It automatically detects
the type of the provided data or function and if it implements PartialEq or Hash
Arguments:
scope
: mandatory. The Scope to use when creating the Signalclone:
: optional. A space-separated list of data to clone and provide to the function.server
|client
: optional. Whether the signal should run only on the server or the client.inner
: the data or function the signal handles.
Examples:
§Example of reactive data signals
use reactive_signals::{Scope, Signal, signal, runtimes::ClientRuntime};
let sc = ClientRuntime::new_root_scope();
// Create a string signal. Since string implements PartialEq the
// signal will only notify it's subscribers if it's value change.
let string_sig = signal!(sc, "hi".to_string());
struct MyNoEqData;
// Create a signal from data that doesn't implement equality.
// it will always notify the subscribers when it changes.
let no_eq_sig = signal!(sc, MyNoEqData);
§Example of functional reactive signals
use reactive_signals::{Scope, Signal, signal, runtimes::ClientRuntime};
let sc = ClientRuntime::new_root_scope();
struct MyNoEqData;
let count_sig = signal!(sc, 4);
// create a simple functional signal
let func_sig = signal!(sc, move || count_sig.get() + 1);
///////////// the clone argument /////////////
let counter = Rc::new(RefCell::new(0));
// using the clone argument you can provide a space-separated
// list of data to clone and provide to the function.
let counter_upd = signal!(sc, clone: counter, move || *counter.borrow_mut() += 1);
// the above is equivalent to:
let counter_upd = {
let counter = counter.clone();
signal!(sc, move || *counter.borrow_mut() += 1)
};
///////////// client and server only signals /////////////
// create a signal that only runs on the server
let server_func = signal!(sc, server, move || count_sig.get() + 1);
// create a signal that only runs on the client
let client_func = signal!(sc, client, move || count_sig.get() + 1);
§Example of async functional reactive signals
Note that this has not yet been implemented and the exact details of the API has not been ironed out.
ⓘ
// creating an async closure/function is basically the same as normal one
let remote_count = signal!(sc, move async || {
// some async stuff
fetch_usize_count().await
});
// an async signal works just like any other signal, it just waits until
// the async closure finishes before notifiying subscribers.
signal!(sc, move || println!("Remote count is now: {}", remote_count.get()));
let async_timer = signal!(sc, 500 ms, move async |&mut interval| {
// runs after 500 ms
// you can change the interval or stop it by:
*interval = None;
});