// DO NOT EDIT! This file was auto-generated by crates/build/re_types_builder/src/codegen/cpp/mod.rs
// Based on "crates/store/re_sdk_types/definitions/rerun/archetypes/video_stream.fbs".

#pragma once

#include "../collection.hpp"
#include "../component_batch.hpp"
#include "../component_column.hpp"
#include "../components/draw_order.hpp"
#include "../components/opacity.hpp"
#include "../components/video_codec.hpp"
#include "../components/video_sample.hpp"
#include "../result.hpp"

#include <cstdint>
#include <optional>
#include <utility>
#include <vector>

namespace rerun::archetypes {
    /// **Archetype**: Video stream consisting of raw video chunks.
    ///
    /// For logging video containers like mp4, refer to `archetypes::AssetVideo` and `archetypes::VideoFrameReference`.
    /// To learn more about video support in Rerun, check the [video reference](https://rerun.io/docs/reference/video).
    ///
    /// All components except `sample` are typically logged statically once per entity.
    /// `sample` is then logged repeatedly for each frame on the timeline.
    ///
    /// TODO(#10422): `archetypes::VideoFrameReference` does not yet work with `archetypes::VideoStream`.
    ///
    /// ⚠ **This type is _unstable_ and may change significantly in a way that the data won't be backwards compatible.**
    ///
    struct VideoStream {
        /// The codec used to encode the video chunks.
        ///
        /// This property is expected to be constant over time and is ideally logged statically once per stream.
        std::optional<ComponentBatch> codec;

        /// Video sample data (also known as "video chunk").
        ///
        /// The current timestamp is used as presentation timestamp (PTS) for all data in this sample.
        /// There is currently no way to log differing decoding timestamps, meaning
        /// that there is no support for B-frames.
        /// See <https://github.com/rerun-io/rerun/issues/10090> for more details.
        ///
        /// Rerun chunks containing frames (i.e. bundles of sample data) may arrive out of order,
        /// but may cause the video playback in the Viewer to reset.
        /// It is recommended to have all chunks for a video stream to be ordered temporally order.
        ///
        /// Logging separate videos on the same entity is allowed iff they share the exact same
        /// codec parameters & resolution.
        ///
        /// The samples are expected to be encoded using the `codec` field.
        /// Each video sample must contain enough data for exactly one video frame
        /// (this restriction may be relaxed in the future for some codecs).
        ///
        /// Unless your stream consists entirely of key-frames (in which case you should consider `archetypes::EncodedImage`)
        /// never log this component as static data as this means that you loose all information of
        /// previous samples which may be required to decode an image.
        ///
        /// See `components::VideoCodec` for codec specific requirements.
        std::optional<ComponentBatch> sample;

        /// Opacity of the video stream, useful for layering several media.
        ///
        /// Defaults to 1.0 (fully opaque).
        std::optional<ComponentBatch> opacity;

        /// An optional floating point value that specifies the 2D drawing order.
        ///
        /// Objects with higher values are drawn on top of those with lower values.
        /// Defaults to `-15.0`.
        std::optional<ComponentBatch> draw_order;

      public:
        /// The name of the archetype as used in `ComponentDescriptor`s.
        static constexpr const char ArchetypeName[] = "rerun.archetypes.VideoStream";

        /// `ComponentDescriptor` for the `codec` field.
        static constexpr auto Descriptor_codec = ComponentDescriptor(
            ArchetypeName, "VideoStream:codec",
            Loggable<rerun::components::VideoCodec>::ComponentType
        );
        /// `ComponentDescriptor` for the `sample` field.
        static constexpr auto Descriptor_sample = ComponentDescriptor(
            ArchetypeName, "VideoStream:sample",
            Loggable<rerun::components::VideoSample>::ComponentType
        );
        /// `ComponentDescriptor` for the `opacity` field.
        static constexpr auto Descriptor_opacity = ComponentDescriptor(
            ArchetypeName, "VideoStream:opacity",
            Loggable<rerun::components::Opacity>::ComponentType
        );
        /// `ComponentDescriptor` for the `draw_order` field.
        static constexpr auto Descriptor_draw_order = ComponentDescriptor(
            ArchetypeName, "VideoStream:draw_order",
            Loggable<rerun::components::DrawOrder>::ComponentType
        );

      public:
        VideoStream() = default;
        VideoStream(VideoStream&& other) = default;
        VideoStream(const VideoStream& other) = default;
        VideoStream& operator=(const VideoStream& other) = default;
        VideoStream& operator=(VideoStream&& other) = default;

        explicit VideoStream(rerun::components::VideoCodec _codec)
            : codec(ComponentBatch::from_loggable(std::move(_codec), Descriptor_codec)
                        .value_or_throw()) {}

        /// Update only some specific fields of a `VideoStream`.
        static VideoStream update_fields() {
            return VideoStream();
        }

        /// Clear all the fields of a `VideoStream`.
        static VideoStream clear_fields();

        /// The codec used to encode the video chunks.
        ///
        /// This property is expected to be constant over time and is ideally logged statically once per stream.
        VideoStream with_codec(const rerun::components::VideoCodec& _codec) && {
            codec = ComponentBatch::from_loggable(_codec, Descriptor_codec).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `codec` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_codec` should
        /// be used when logging a single row's worth of data.
        VideoStream with_many_codec(const Collection<rerun::components::VideoCodec>& _codec) && {
            codec = ComponentBatch::from_loggable(_codec, Descriptor_codec).value_or_throw();
            return std::move(*this);
        }

        /// Video sample data (also known as "video chunk").
        ///
        /// The current timestamp is used as presentation timestamp (PTS) for all data in this sample.
        /// There is currently no way to log differing decoding timestamps, meaning
        /// that there is no support for B-frames.
        /// See <https://github.com/rerun-io/rerun/issues/10090> for more details.
        ///
        /// Rerun chunks containing frames (i.e. bundles of sample data) may arrive out of order,
        /// but may cause the video playback in the Viewer to reset.
        /// It is recommended to have all chunks for a video stream to be ordered temporally order.
        ///
        /// Logging separate videos on the same entity is allowed iff they share the exact same
        /// codec parameters & resolution.
        ///
        /// The samples are expected to be encoded using the `codec` field.
        /// Each video sample must contain enough data for exactly one video frame
        /// (this restriction may be relaxed in the future for some codecs).
        ///
        /// Unless your stream consists entirely of key-frames (in which case you should consider `archetypes::EncodedImage`)
        /// never log this component as static data as this means that you loose all information of
        /// previous samples which may be required to decode an image.
        ///
        /// See `components::VideoCodec` for codec specific requirements.
        VideoStream with_sample(const rerun::components::VideoSample& _sample) && {
            sample = ComponentBatch::from_loggable(_sample, Descriptor_sample).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `sample` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_sample` should
        /// be used when logging a single row's worth of data.
        VideoStream with_many_sample(const Collection<rerun::components::VideoSample>& _sample) && {
            sample = ComponentBatch::from_loggable(_sample, Descriptor_sample).value_or_throw();
            return std::move(*this);
        }

        /// Opacity of the video stream, useful for layering several media.
        ///
        /// Defaults to 1.0 (fully opaque).
        VideoStream with_opacity(const rerun::components::Opacity& _opacity) && {
            opacity = ComponentBatch::from_loggable(_opacity, Descriptor_opacity).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `opacity` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_opacity` should
        /// be used when logging a single row's worth of data.
        VideoStream with_many_opacity(const Collection<rerun::components::Opacity>& _opacity) && {
            opacity = ComponentBatch::from_loggable(_opacity, Descriptor_opacity).value_or_throw();
            return std::move(*this);
        }

        /// An optional floating point value that specifies the 2D drawing order.
        ///
        /// Objects with higher values are drawn on top of those with lower values.
        /// Defaults to `-15.0`.
        VideoStream with_draw_order(const rerun::components::DrawOrder& _draw_order) && {
            draw_order =
                ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `draw_order` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_draw_order` should
        /// be used when logging a single row's worth of data.
        VideoStream with_many_draw_order(const Collection<rerun::components::DrawOrder>& _draw_order
        ) && {
            draw_order =
                ComponentBatch::from_loggable(_draw_order, Descriptor_draw_order).value_or_throw();
            return std::move(*this);
        }

        /// Partitions the component data into multiple sub-batches.
        ///
        /// Specifically, this transforms the existing `ComponentBatch` data into `ComponentColumn`s
        /// instead, via `ComponentBatch::partitioned`.
        ///
        /// This makes it possible to use `RecordingStream::send_columns` to send columnar data directly into Rerun.
        ///
        /// The specified `lengths` must sum to the total length of the component batch.
        Collection<ComponentColumn> columns(const Collection<uint32_t>& lengths_);

        /// Partitions the component data into unit-length sub-batches.
        ///
        /// This is semantically similar to calling `columns` with `std::vector<uint32_t>(n, 1)`,
        /// where `n` is automatically guessed.
        Collection<ComponentColumn> columns();
    };

} // namespace rerun::archetypes

namespace rerun {
    /// \private
    template <typename T>
    struct AsComponents;

    /// \private
    template <>
    struct AsComponents<archetypes::VideoStream> {
        /// Serialize all set component batches.
        static Result<Collection<ComponentBatch>> as_batches(
            const archetypes::VideoStream& archetype
        );
    };
} // namespace rerun
