Note: This document covers API impact only. For more details, see the ABI compatibility page

Add a protocol event

Overview

- init step 1 step 2 step 3 step 4
fidl link link link
dart link link
go link link
hlcpp link link
llcpp link link
rust link link link

Initial State {#init}

FIDL {#fidl-init}

  1. protocol Example {
  2. -> OnExistingEvent();
  3. };

Dart {#dart-init}

  1. class Server extends fidllib.Example {
  2. final _onExistingEventStreamController = StreamController<void>();
  3. @override
  4. Stream<void> get onExistingEvent => _onExistingEventStreamController.stream;
  5. }
  6. void expectEvents(fidllib.ExampleProxy client) async {
  7. await client.onExistingEvent.first;
  8. }

Go {#go-init}

  1. func expectEvents(c *lib.ExampleWithCtxInterface) {
  2. _ = c.ExpectOnExistingEvent(context.Background())
  3. }
  4. func sendEvents(p *lib.ExampleEventProxy) {
  5. _ = p.OnExistingEvent()
  6. }

HLCPP {#hlcpp-init}

  1. void expectEvents(fidl_test::ExamplePtr* client) {
  2. client->events().OnExistingEvent = []() {};
  3. }
  4. void sendEvents(fidl::Binding<fidl_test::Example>* server) { server->events().OnExistingEvent(); }

LLCPP {#llcpp-init}

  1. class AsyncEventHandler : public fidl::WireAsyncEventHandler<fidl_test::Example> {
  2. void OnExistingEvent(fidl_test::Example::OnExistingEventResponse* event) override {}
  3. };
  4. class SyncEventHandler : public fidl::WireSyncEventHandler<fidl_test::Example> {
  5. void OnExistingEvent(fidl_test::Example::OnExistingEventResponse* event) override {}
  6. };
  7. void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) { server->OnExistingEvent(); }

Rust {#rust-init}

  1. fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
  2. let control_handle = stream.control_handle();
  3. control_handle.send_on_existing_event()?;
  4. Ok(())
  5. }
  6. async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
  7. let mut event_stream = client.take_event_stream();
  8. while let Some(event) = event_stream.try_next().await? {
  9. match event {
  10. fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
  11. }
  12. }
  13. Ok(())
  14. }

Update Source Code {#step-1}

Rust {#rust-1}

  • Add #[allow(unreachable_patterns)] and a catch-all arm (_) to any client event stream match statements
  1. fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
  2. let control_handle = stream.control_handle();
  3. control_handle.send_on_existing_event()?;
  4. Ok(())
  5. }
  6. async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
  7. let mut event_stream = client.take_event_stream();
  8. while let Some(event) = event_stream.try_next().await? {
  9. + #[allow(unreachable_patterns)]
  10. match event {
  11. fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
  12. + _ => {}
  13. }
  14. }
  15. Ok(())
  16. }

Update FIDL Library {#step-2}

  • Add the new event and mark it with the [Transitional] attribute.
  1. protocol Example {
  2. -> OnExistingEvent();
  3. + [Transitional]
  4. + -> OnNewEvent();
  5. };

Update Source Code {#step-3}

Dart {#dart-3}

  • Implement the stream for the new event for any server implementations.
  • You can start receiving the new event in any clients.
  1. class Server extends fidllib.Example {
  2. final _onExistingEventStreamController = StreamController<void>();
  3. + final _onNewEventStreamController = StreamController<void>();
  4. @override
  5. Stream<void> get onExistingEvent => _onExistingEventStreamController.stream;
  6. +
  7. + @override
  8. + Stream<void> get onNewEvent => _onNewEventStreamController.stream;
  9. }
  10. void expectEvents(fidllib.ExampleProxy client) async {
  11. await client.onExistingEvent.first;
  12. + await client.onNewEvent.first;
  13. }

Go {#go-3}

  • You can start using the new event on both the client and server side.
  1. func expectEvents(c *lib.ExampleWithCtxInterface) {
  2. _ = c.ExpectOnExistingEvent(context.Background())
  3. + _ = c.ExpectOnNewEvent(context.Background())
  4. }
  5. func sendEvents(p *lib.ExampleEventProxy) {
  6. _ = p.OnExistingEvent()
  7. + _ = p.OnNewEvent()
  8. }

HLCPP {#hlcpp-3}

  • You can start using the new event on both the client and server side.
  1. void expectEvents(fidl_test::ExamplePtr* client) {
  2. client->events().OnExistingEvent = []() {};
  3. + client->events().OnNewEvent = []() {};
  4. }
  5. - void sendEvents(fidl::Binding<fidl_test::Example>* server) { server->events().OnExistingEvent(); }
  6. + void sendEvents(fidl::Binding<fidl_test::Example>* server) {
  7. + server->events().OnExistingEvent();
  8. + server->events().OnNewEvent();
  9. + }

LLCPP {#llcpp-3}

  • For usages of the async event handle struct, add a handler for the new event if desired.
  • For usages of the async event handler class, you must add a handle for the new event.
  • You can start receiving the new event in any clients.
  1. class AsyncEventHandler : public fidl::WireAsyncEventHandler<fidl_test::Example> {
  2. void OnExistingEvent(fidl_test::Example::OnExistingEventResponse* event) override {}
  3. + void OnNewEvent(fidl_test::Example::OnNewEventResponse* event) override {}
  4. };
  5. class SyncEventHandler : public fidl::WireSyncEventHandler<fidl_test::Example> {
  6. void OnExistingEvent(fidl_test::Example::OnExistingEventResponse* event) override {}
  7. + void OnNewEvent(fidl_test::Example::OnNewEventResponse* event) override {}
  8. };
  9. - void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) { server->OnExistingEvent(); }
  10. + void sendEvents(fidl::ServerBindingRef<fidl_test::Example> server) {
  11. + server->OnExistingEvent();
  12. + server->OnNewEvent();
  13. + }

Rust {#rust-3}

  • Remove the #[allow(unreachable_patterns)] attribute and replace the catch-all arm with the new event.
  • You can start sending the new event in any servers.
  1. fn send_events(stream: fidl_lib::ExampleRequestStream) -> Result<(), fidl::Error> {
  2. let control_handle = stream.control_handle();
  3. control_handle.send_on_existing_event()?;
  4. + control_handle.send_on_new_event()?;
  5. Ok(())
  6. }
  7. async fn receive_events(client: fidl_lib::ExampleProxy) -> Result<(), fidl::Error> {
  8. let mut event_stream = client.take_event_stream();
  9. while let Some(event) = event_stream.try_next().await? {
  10. - #[allow(unreachable_patterns)]
  11. match event {
  12. fidl_lib::ExampleEvent::OnExistingEvent { .. } => {}
  13. - _ => {}
  14. + fidl_lib::ExampleEvent::OnNewEvent { .. } => {}
  15. }
  16. }
  17. Ok(())
  18. }

Update FIDL Library {#step-4}

  • Remove the [Transitional] attribute.
  1. protocol Example {
  2. -> OnExistingEvent();
  3. - [Transitional]
  4. -> OnNewEvent();
  5. };