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

#pragma once

#include "../collection.hpp"
#include "../component_batch.hpp"
#include "../component_column.hpp"
#include "../components/clear_is_recursive.hpp"
#include "../indicator_component.hpp"
#include "../rerun_sdk_export.hpp"
#include "../result.hpp"

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

namespace rerun::archetypes {
    /// **Archetype**: Empties all the components of an entity.
    ///
    /// The presence of a clear means that a latest-at query of components at a given path(s)
    /// will not return any components that were logged at those paths before the clear.
    /// Any logged components after the clear are unaffected by the clear.
    ///
    /// This implies that a range query that includes time points that are before the clear,
    /// still returns all components at the given path(s).
    /// Meaning that in practice clears are ineffective when making use of visible time ranges.
    /// Scalar plots are an exception: they track clears and use them to represent holes in the
    /// data (i.e. discontinuous lines).
    ///
    /// ## Example
    ///
    /// ### Flat
    /// ![image](https://static.rerun.io/clear_simple/2f5df95fcc53e9f0552f65670aef7f94830c5c1a/full.png)
    ///
    /// ```cpp
    /// #include <rerun.hpp>
    ///
    /// #include <cmath>
    /// #include <numeric>
    /// #include <string> // to_string
    /// #include <vector>
    ///
    /// int main() {
    ///     const auto rec = rerun::RecordingStream("rerun_example_clear");
    ///     rec.spawn().exit_on_failure();
    ///
    ///     std::vector<rerun::Vector3D> vectors = {
    ///         {1.0, 0.0, 0.0},
    ///         {0.0, -1.0, 0.0},
    ///         {-1.0, 0.0, 0.0},
    ///         {0.0, 1.0, 0.0},
    ///     };
    ///     std::vector<rerun::Position3D> origins = {
    ///         {-0.5, 0.5, 0.0},
    ///         {0.5, 0.5, 0.0},
    ///         {0.5, -0.5, 0.0},
    ///         {-0.5, -0.5, 0.0},
    ///     };
    ///     std::vector<rerun::Color> colors = {
    ///         {200, 0, 0},
    ///         {0, 200, 0},
    ///         {0, 0, 200},
    ///         {200, 0, 200},
    ///     };
    ///
    ///     // Log a handful of arrows.
    ///     for (size_t i = 0; i <vectors.size(); ++i) {
    ///         auto entity_path = "arrows/" + std::to_string(i);
    ///         rec.log(
    ///             entity_path,
    ///             rerun::Arrows3D::from_vectors(vectors[i])
    ///                 .with_origins(origins[i])
    ///                 .with_colors(colors[i])
    ///         );
    ///     }
    ///
    ///     // Now clear them, one by one on each tick.
    ///     for (size_t i = 0; i <vectors.size(); ++i) {
    ///         auto entity_path = "arrows/" + std::to_string(i);
    ///         rec.log(entity_path, rerun::Clear::FLAT);
    ///     }
    /// }
    /// ```
    struct Clear {
        std::optional<ComponentBatch> is_recursive;

      public:
        static constexpr const char IndicatorComponentName[] = "rerun.components.ClearIndicator";

        /// Indicator component, used to identify the archetype when converting to a list of components.
        using IndicatorComponent = rerun::components::IndicatorComponent<IndicatorComponentName>;
        /// The name of the archetype as used in `ComponentDescriptor`s.
        static constexpr const char ArchetypeName[] = "rerun.archetypes.Clear";

        /// `ComponentDescriptor` for the `is_recursive` field.
        static constexpr auto Descriptor_is_recursive = ComponentDescriptor(
            ArchetypeName, "is_recursive",
            Loggable<rerun::components::ClearIsRecursive>::Descriptor.component_name
        );

      public: // START of extensions from clear_ext.cpp:
        RERUN_SDK_EXPORT static const Clear FLAT;

        RERUN_SDK_EXPORT static const Clear RECURSIVE;

        Clear(bool _is_recursive = false) : Clear(components::ClearIsRecursive(_is_recursive)) {}

        // END of extensions from clear_ext.cpp, start of generated code:

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

        explicit Clear(rerun::components::ClearIsRecursive _is_recursive)
            : is_recursive(
                  ComponentBatch::from_loggable(std::move(_is_recursive), Descriptor_is_recursive)
                      .value_or_throw()
              ) {}

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

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

        Clear with_is_recursive(const rerun::components::ClearIsRecursive& _is_recursive) && {
            is_recursive = ComponentBatch::from_loggable(_is_recursive, Descriptor_is_recursive)
                               .value_or_throw();
            return std::move(*this);
        }

        /// This method makes it possible to pack multiple `is_recursive` in a single component batch.
        ///
        /// This only makes sense when used in conjunction with `columns`. `with_is_recursive` should
        /// be used when logging a single row's worth of data.
        Clear with_many_is_recursive(
            const Collection<rerun::components::ClearIsRecursive>& _is_recursive
        ) && {
            is_recursive = ComponentBatch::from_loggable(_is_recursive, Descriptor_is_recursive)
                               .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::Clear> {
        /// Serialize all set component batches.
        static Result<Collection<ComponentBatch>> as_batches(const archetypes::Clear& archetype);
    };
} // namespace rerun
