-
Notifications
You must be signed in to change notification settings - Fork 0
How to implement a new Command?
Main Idea: Each command has its static infomation and instance. Basically, to implement a new command you need to implement two trait CommandInstance and CommandTypeInfo, respectively providing information about how to execute an instance of command and static information about command.
Suppose we are going to add a command call Foo
in mod foo
We use Command
to hold static information about command:
#[derive(Clone)]
pub struct Command {
/// command id i.e. command name
id: CommandIdRef<'static>,
create_instance_fn: CreateInstanceFn,
}
By implementing CommandTypeInfo
trait for Foo
, we can acquire the related Command
. Usaually we just need to implement new
to tell how to build a instance, and command
to tell other related static information.
pub trait CommandTypeInfo: CommandInstance + Sized + 'static {
/// Tell the system how to create instance
fn new() -> Self;
/// Static typing infomation of command, which is used to register the command
fn command() -> &'static Command;
/// Boxed version of `new`
fn boxed() -> Box<dyn CommandInstance> {
Box::new(Self::new())
}
fn id() -> CommandIdRef<'static> {
Self::command().id
}
}
We can implement command
via the macro command_type_stub
, then we have code below:
struct Foo;
impl CommandTypeInfo for Foo {
fn new() -> Self{
Foo
}
command_type_stub!{ id: "foo" }
}
Then implement CommandInstance
for Foo
:
#[asycn_trait]
impl CommandInstance for Foo {
...
}
Now we should first register the mod foo
to GlobalCommandTable
to let it know foo
including commands.
To do this, just modify the definition of GLOBAL_COMMAND_TABLE
in commands.rs
, add the mod foo inside register_mod!
pub static GLOBAL_COMMANDS_TABLE: Lazy<GlobalCommandTable> = register_mod! {..., foo};
Then to tell that Foo
is a command, we should also register Foo
to foo
by using register!
inside foo
like below:
register! { Foo }
The relationship of Foo
, Command
, CommandInstance
, CommandTypeInfo
and GlobalCommandTable
is shown as below: