一个Plugin提供了一些函数接受用户输入,在首帧之前要统计所有用户输入, 一个简单的方法是在Plugin::finish()做处理。
在生态库中很少见到这种需求,只有在复杂生态库才能看到。
在Plugin构建时添加一个保存数据的资源,在所有插件加载完毕后,读取数据并删掉资源。
impl Plugin for EnhancedInputPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<ContextRegistry>()
.init_resource::<ResetInput>()
.init_resource::<ActionSources>()
.configure_sets(PreUpdate, EnhancedInputSystem.after(InputSystem));
}
fn finish(&self, app: &mut App) {
let registry = app
.world_mut()
.remove_resource::<ContextRegistry>()
.expect("registry should be inserted in `build`");
for contexts in registry.iter() {
contexts.setup(app);
}
}
}
impl InputContextAppExt for App {
fn add_input_context<C: InputContext>(&mut self) -> &mut Self {
debug!(
"registering `{}` for `{}`",
any::type_name::<C>(),
any::type_name::<C::Schedule>(),
);
let id = self.world_mut().register_component::<Actions<C>>();
let mut registry = self.world_mut().resource_mut::<ContextRegistry>(); // <--
if let Some(contexts) = registry
.iter_mut()
.find(|c| c.schedule_id == TypeId::of::<C::Schedule>())
{
debug_assert!(
!contexts.action_ids.contains(&id),
"context `{}` shouldn't be added more then once",
any::type_name::<C>()
);
contexts.action_ids.push(id); // 保存
} else {
let mut contexts = ScheduleContexts::new::<C::Schedule>();
contexts.action_ids.push(id);
registry.push(contexts); // 保存
}
self.add_observer(add_context::<C>)
.add_observer(remove_context::<C>);
self
}
}