pub struct AppBuilder { /* private fields */ }Expand description
Builder for constructing a MAF application. Used to register stores, RPC functions, background tasks, and more.
Implementations§
Source§impl AppBuilder
impl AppBuilder
Sourcepub fn on_connect<Params, Handler, const IS_ASYNC: bool>(
self,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<OnConnectDiconnectContext, Params, (), OnConnectDisconnectError, (), IS_ASYNC>,
pub fn on_connect<Params, Handler, const IS_ASYNC: bool>(
self,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<OnConnectDiconnectContext, Params, (), OnConnectDisconnectError, (), IS_ASYNC>,
Sourcepub fn on_disconnect<Params, Handler, const IS_ASYNC: bool>(
self,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<OnConnectDiconnectContext, Params, (), OnConnectDisconnectError, (), IS_ASYNC>,
pub fn on_disconnect<Params, Handler, const IS_ASYNC: bool>(
self,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<OnConnectDiconnectContext, Params, (), OnConnectDisconnectError, (), IS_ASYNC>,
Register a function to run when a user disconnects. To get the user object, use the User
struct as a parameter.
§Example
use maf::prelude::*;
fn on_disconnect(user: User) {
println!("user disconnected! id: {}", user.meta.id());
}
fn build() -> App {
App::builder()
.on_disconnect(on_disconnect)
.build()
}Sourcepub fn rpc<Params, Return, const IS_ASYNC: bool, Handler: IntoCallable<RpcRequestContext, Params, Return, RpcError, RpcRequestInit, IS_ASYNC>>(
self,
method: impl ToString,
handler: Handler,
) -> Selfwhere
Return: Serialize + 'static,
pub fn rpc<Params, Return, const IS_ASYNC: bool, Handler: IntoCallable<RpcRequestContext, Params, Return, RpcError, RpcRequestInit, IS_ASYNC>>(
self,
method: impl ToString,
handler: Handler,
) -> Selfwhere
Return: Serialize + 'static,
Register a new RPC method.
See crate::rpc module-level documentation for more details on RPCs.
§Example
use maf::prelude::*;
struct CounterStore {
count: i32,
}
impl StoreData for CounterStore { /* ... */ }
async fn add(Params(count): Params<i32>, store: Store<CounterStore>) -> i32 {
let mut data = store.write().await;
*data += count;
println!("incremented counter by {count}. new value: {}", &*data);
*data
}
fn build() -> App {
App::builder()
.rpc("add", add)
.store::<CounterStore>()
.build()
}
maf::register!(build);Sourcepub fn background<Params, Handler, const IS_ASYNC: bool>(
self,
handler: Handler,
) -> Self
pub fn background<Params, Handler, const IS_ASYNC: bool>( self, handler: Handler, ) -> Self
Register a task to run in the background.
§Example
use maf::prelude::*;
async fn background() {
loop {
tasks::sleep(std::time::Duration::from_secs(1)).await;
println!("Hello from the background!");
}
}
fn build() -> App {
App::builder()
.background(background)
.build()
}Sourcepub fn store<T: StoreData>(self) -> Self
pub fn store<T: StoreData>(self) -> Self
Statically declare a store, initializing it with the default value.
This method should be called with a type argument that implements StoreData.
§Example
use maf::prelude::*;
struct CounterStore {
count: i32,
}
impl StoreData for CounterStore {
type Select<'this> = i32; // Serializable type representing the store's data
// The default value for the store should be provided here
fn init() -> Self {
CounterStore { count: 0 }
}
fn select(&self, _user: &User) -> Self::Select<'_> {
self.count
}
fn name() -> impl AsRef<str> {
"counter"
}
}
fn build() -> App {
App::builder()
// Register the store so it can be used in RPCs and elsewhere. The type argument
// specifies the store's data type.
.store::<CounterStore>()
.build()
}
maf::register!(build);Sourcepub fn select<Name: ToString, Params, Ret, Handler: IntoCallable<SelectContext, Params, Ret, Infallible, (), IS_ASYNC>, const IS_ASYNC: bool, const N_PARAMS: usize>(
self,
name: Name,
handler: Handler,
) -> Selfwhere
Params: GetParamSelectDependencies<N_PARAMS>,
Ret: Serialize + 'static,
pub fn select<Name: ToString, Params, Ret, Handler: IntoCallable<SelectContext, Params, Ret, Infallible, (), IS_ASYNC>, const IS_ASYNC: bool, const N_PARAMS: usize>(
self,
name: Name,
handler: Handler,
) -> Selfwhere
Params: GetParamSelectDependencies<N_PARAMS>,
Ret: Serialize + 'static,
Register a store where its contents are derived with the provided function.
This is useful for creating “views” of existing stores that automatically update when their dependencies change.
§Example
use maf::prelude::*;
#[derive(Debug, Serialize)]
pub struct Player {
id: Uuid,
name: String,
is_alive: bool,
}
struct GameStore {
players: HashMap<Uuid, Player>,
}
impl StoreData for GameStore {
// On this store, we are not exposing any data to the client.
type Select<'this> = ();
// ... implement init, name, and select ...
}
fn build() -> App {
App::builder()
// Register the main game store
.store::<GameStore>()
// The "alive_players" select will automatically update whenever the `GameStore`
// changes. Clients will see an "alive_players" store that contains only the alive
// players.
.select("alive_players", |store: StoreRef<GameStore>| {
store.players.values()
.filter(|player| player.is_alive)
.cloned()
.collect::<Vec<Player>>()
})
// Multiple selects can be added. Here is another example that counts the number of
// players in the game.
.select("player_count", |store: StoreRef<GameStore>| {
store.players.len()
})
.build()
}
maf::register!(build);Sourcepub fn meta<Name: ToString, Params, Ret, Handler: IntoCallable<MetaContext, Params, Ret, Infallible, (), IS_ASYNC>, const IS_ASYNC: bool, const N_PARAMS: usize>(
self,
visibility: MetaVisibility,
name: Name,
handler: Handler,
) -> Selfwhere
Params: GetParamSelectDependencies<N_PARAMS>,
Ret: Serialize + 'static,
pub fn meta<Name: ToString, Params, Ret, Handler: IntoCallable<MetaContext, Params, Ret, Infallible, (), IS_ASYNC>, const IS_ASYNC: bool, const N_PARAMS: usize>(
self,
visibility: MetaVisibility,
name: Name,
handler: Handler,
) -> Selfwhere
Params: GetParamSelectDependencies<N_PARAMS>,
Ret: Serialize + 'static,
Subscribes a meta entry to be automatically updated when its dependencies change.
The handler function is called to compute the meta value whenever any of its dependencies
change.
§Example
use maf::prelude::*;
struct CounterStore {
count: i32,
}
impl StoreData for CounterStore { /* ... */ }
fn build() -> App {
App::builder()
.store::<CounterStore>()
// Whenever the `CounterStore` is updated, the "count" meta value will also be
// updated.
.meta(MetaVisibility::Public, "count", |store: StoreRef<CounterStore>| {
store.count
})
}
maf::register!(build);Sourcepub fn local<T: Send + Sync + 'static>(self, state: T) -> Self
pub fn local<T: Send + Sync + 'static>(self, state: T) -> Self
Declares a crate::Local, a piece of state that does not need to be synchronized with
connect clients. If synchronization with clients is needed, use crate::Store
The initial value of the local state should be provided as an argument.
§Example
use maf::prelude::*;
struct Points {
points: u32,
}
// [`Points`] does not need to be `serde::Serialize` and is not visible to clients
async fn score_point(points: Local<Points>) {
let points = points.write().await;
points += 1;
if points > 100 {
println!("You win!");
}
}
fn build() -> App {
App::builder()
.local(Points { points: 0 })
.rpc("score_point", score_point)
.build()
}Sourcepub fn hook<Params, Return, Handler, const IS_ASYNC: bool>(
self,
method: impl ToString,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<HookContext, Params, Return, HookError, (), IS_ASYNC>,
Return: Serialize + 'static,
pub fn hook<Params, Return, Handler, const IS_ASYNC: bool>(
self,
method: impl ToString,
handler: Handler,
) -> Selfwhere
Handler: IntoCallable<HookContext, Params, Return, HookError, (), IS_ASYNC>,
Return: Serialize + 'static,
Declare a hook function. TODO: write documentation for this.
Sourcepub fn platform(self, platform: TargetPlatform) -> Self
pub fn platform(self, platform: TargetPlatform) -> Self
Binds the MAF app to a specified TargetPlatform.
See crate::platform for more details on platforms.
pub fn build(self) -> App
Source§impl AppBuilder
impl AppBuilder
Sourcepub fn plugin(self, plugin: impl Plugin) -> Self
pub fn plugin(self, plugin: impl Plugin) -> Self
Registers a plugin to modify the application.
§Examples
use maf::prelude::*;
// A plugin that adds game functionality to the app.
// NOTE: options and configuration can be passed to the plugin via its fields.
pub struct GamePlugin {
total_rounds: u32,
}
// ... other plugin code ...
impl Plugin for GamePlugin {
fn build(&self, app: AppBuilder) -> AppBuilder {
// Initialize game state, RPCs, stores, etc.
app
// .store::<GameState>()
// .rpc("start_round", start_round)
// ...
}
}
// ... where the app is built ...
fn build() -> App {
App::builder()
// Consume the plugin to modify the app
.plugin(GamePlugin { total_rounds: 5 })
// ... other app configuration ...
.build()
}
maf::register!(build);