会话角色和责任(示例)

会话组件在组件拓扑中封装产品体验。它可(直接或间接)启动所有产品专用组件,管理这些组件的生命周期,并管理产品专用组件(如面向用户的应用)与设备专用组件(如输入设备、音频和显示屏,如有)之间的控制流和信息流。

以下部分演示了会话作者如何实现其中一些责任。

呈现元素的视图

在以下示例中,会话通过使用 ViewSpec 调用 PresentView() element 视图转发到 GraphicalPresenter ViewSpec 包含重复的 ViewRef Element 的 View 的可共享句柄)和一组可选的初始产品专用 element-annotation

实现 Graphical Presenter 角色的组件知道如何在已连接的屏幕上打开视图。

    fn present_view_for_element(
        graphical_presenter: &GraphicalPresenterProxy,
        element: &Element
    ) -> Result<ViewControllerProxy, Error> {
        let view_provider = element.connect_to_service::<ViewProviderMarker>()?;
        let token_pair = scenic::ViewTokenPair::new()?;
        let scenic::ViewRefPair {
            mut control_ref,
            mut view_ref
        } = scenic::ViewRefPair::new()?;
        let view_ref_dup = fuchsia_scenic::duplicate_view_ref(&view_ref)?;

        view_provider.create_view_with_view_ref(
            token_pair.view_token.value,
            &mut control_ref,
            &mut view_ref,
        )?;

        let annotations = element.get_annotations()?;

        let view_spec = ViewSpec {
            view_holder_token: Some(token_pair.view_holder_token),
            view_ref: Some(view_ref_dup),
            annotations: Some(annotations),
            ..Default::default()
        };

        let (view_controller_proxy, server_end) = create_proxy::<ViewControllerMarker>()?;
        graphical_presenter.present_view(view_spec, Some(server_end))?;

        Ok(view_controller_proxy)
    }

处理输入

在以下示例中,如果 MouseHandler 检测到鼠标型输入事件,处理程序会将该事件发送到景观并返回空矢量。对于所有其他类型的输入事件,MouseHandler 会返回一个包含 InputEvent 的向量,供下一个 InputHandler 进行处理。

#[async_trait]
impl InputHandler for MouseHandler {
   async fn handle_input_event(
       &mut self,
       input_event: InputEvent,
   ) -> Vec<InputEvent> {
       match input_event {
           InputEvent {
               device_event: InputDeviceEvent::Mouse(mouse_event),
               device_descriptor: InputDeviceDescriptor::Mouse(mouse_descriptor),
           } => {
               // ... Handler specific details
               self.send_events_to_scenic(...)).await;
               vec![] // InputEvent is consumed because it was sent to Scenic
           }
           _ => vec![input_event], // InputEvent is returned for the next InputHandler
       }
   }
}