How To Document#

This section provides brief overview on how to document using Breathe directive and includes API documentation automatically generated from C++ source code.

Note

API documentation is generated using Doxygen and integrated via Breathe. Due to Sphinx version < 9.x limitations with complex C++ templates, use specific class and function directives rather than namespace-level documentation.

Automatic API Documentation with @api Tag#

The project includes an automated RST generation utility that extracts API items tagged with @api in Doxygen comments and generates categorized documentation.

How to use @api tag:

Add the @api tag to any Doxygen comment block to include it in the generated API documentation:

/**
 * @brief Connection handler for client communication
 * @api
 */
class ClientConnection {
    // ...
};

/**
 * @brief Initialize the communication system
 * @return true if successful
 * @api
 */
bool initialize();

Generated documentation structure:

The utility automatically creates:

  • API Index - Overview of all tagged items

  • Namespace Reference - Namespaces containing @api items

  • Class Reference - Classes and structs with @api tag

  • Member Reference - Functions and methods with @api tag

Build integration:

generate_api_rst(
    name = "generate_api_rst",
    doxygen_xml = "//path/to:doxygen_target",
    output_dir = "generated",
    project_name = "mw::com",
)

The generated RST files are automatically included in the Sphinx documentation under the “Generated API Documentation” section.

Using Breathe Directives#

To document specific classes or functions, use these Breathe directives:

Document a specific class:

.. doxygenclass:: score::message_passing::detail::ClientConnection
    :members:
    :protected-members:
    :undoc-members:

Document a specific function:

.. doxygenfunction:: score::mw::com::functionName

Document a struct:

.. doxygenstruct:: score::mw::com::ConfigStruct
    :members:

Example: ClientConnection#

class ClientConnection : public score::message_passing::IClientConnection#

Public Functions

ClientConnection(std::shared_ptr<ISharedResourceEngine> engine, const ServiceProtocolConfig &protocol_config, const IClientFactory::ClientConfig &client_config) noexcept#
~ClientConnection() noexcept override#
ClientConnection(const ClientConnection&) = delete#
ClientConnection(ClientConnection&&) = delete#
ClientConnection &operator=(const ClientConnection&) = delete#
ClientConnection &operator=(ClientConnection&&) = delete#
virtual score::cpp::expected_blank<score::os::Error> Send(score::cpp::span<const std::uint8_t> message) noexcept override#

Send a binary message to the respective server, don’t expect a reply.

The call is non-blocking and will fail if it would otherwise block due to implementation details. The call will likely fail with score::os::Error in State::Init and definitely fail in State::Stopped. The call is unlikely (but still possible) to fail in State::Ready, unless the message is too big to transport, in which case the call will definitely fail. Even if the call doesn’t fail, there is still a possibility that the message will be lost by the receiving side, however, that only happens if the receiving side dies or disconnects before receiving the message. The implementation is allowed to use different transport mechanisms depending on the message size; the server is still guaranteed to receive the messages from the same client connection sequentially in the same order as they were sent. However, if multiple connections are created from the same client process, to the same or to the different servers, the order of messages across connections is not guaranteed. Note: the non-blocking guarantee for an ASIL B client to a QM server is only given if the messages to send are queued on the client side (ClientConfig::maxQueuedSends is not 0).

Parameters:

message – The memory span containing the message to send

Returns:

error if fails

virtual score::cpp::expected<score::cpp::span<const std::uint8_t>, score::os::Error> SendWaitReply(score::cpp::span<const std::uint8_t> message, score::cpp::span<std::uint8_t> reply) noexcept override#

Send a binary message to the respective server, wait for reply.

The call is blocking.

Parameters:
  • message – The memory span containing the message to send

  • reply – The memory span designating the buffer for the reply message

Returns:

the reply span trimmed to the actual size of the reply message if succeeds, error if fails

virtual score::cpp::expected_blank<score::os::Error> SendWithCallback(score::cpp::span<const std::uint8_t> message, ReplyCallback callback) noexcept override#

Send a binary message to the respective server, register callback for reply.

The call is non-blocking. Note: the non-blocking guarantee for an ASIL B client to a QM server is only given if the messages to send are queued on the client side (ClientConfig::maxQueuedSends is not 0). Note: if the server receives the message but dies or disconnects before the reply arrives to the client, the error will be passed to the callback; the method itself will not return an error.

Parameters:
  • message – The memory span containing the message to send

  • callback – The callback to call on reply

Returns:

error if fails

virtual State GetState() const noexcept override#

Return the current state.

virtual StopReason GetStopReason() const noexcept override#

Return the last stopping reason for the State::Stopping/State::Stopped.

virtual void Start(StateCallback state_callback, NotifyCallback notify_callback) noexcept override#

Start the connection.

The callbacks lifetime (or rather the lifetime of the system state captured in the callbacks by reference) needs to end not earlier than after the connection has returned into the Stop state

virtual void Stop() noexcept override#

Stop the existing connection.

virtual void Restart() noexcept override#

Try to restart a stopped connection.

For some stop reasons (such as kPermission) it is highly unlikely to have a successful restart.

Additional Resources#

For complete API documentation:

  • Browse the Doxygen-generated HTML in bazel-bin/score/mw/com/design/doxygen_build/html/index.html

  • Review header files in score/mw/com/ for inline documentation

  • Check the design documentation at score/mw/com/design/