// 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/coordinate_frame.fbs".

#pragma once

#include "../collection.hpp"
#include "../component_batch.hpp"
#include "../component_column.hpp"
#include "../components/transform_frame_id.hpp"
#include "../result.hpp"

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

namespace rerun::archetypes {
    /// **Archetype**: Specifies the coordinate frame for an entity.
    ///
    /// **Experimental:** Transform frames are still in early development!
    ///
    /// If not specified, the coordinate frame uses an implicit frame derived from the entity path.
    /// The implicit frame's name is `tf#/your/entity/path` and has an identity transform connection to its parent path.
    ///
    /// To learn more about transforms see [Spaces & Transforms](https://rerun.io/docs/concepts/spaces-and-transforms) in the reference.
    ///
    /// ## Example
    ///
    /// ### Change coordinate frame to different built-in frames
    /// ![image](https://static.rerun.io/coordinate_frame_builtin_frame/71f941f35cf73c299c6ea7fbc4487a140db8e8f8/full.png)
    ///
    /// ```cpp
    /// #include <rerun.hpp>
    ///
    /// int main() {
    ///     const auto rec = rerun::RecordingStream("rerun_example_transform3d_hierarchy");
    ///     rec.spawn().exit_on_failure();
    ///
    ///     rec.set_time_sequence("time", 0);
    ///     rec.log(
    ///         "red_box",
    ///         rerun::Boxes3D::from_half_sizes({{0.5f, 0.5f, 0.5f}}
    ///         ).with_colors({rerun::Color(255, 0, 0)}),
    ///         // Use Transform3D to place the box, so we actually change the underlying coordinate frame and not just the box's pose.
    ///         rerun::Transform3D::from_translation({2.0f, 0.0f, 0.0f})
    ///     );
    ///     rec.log(
    ///         "blue_box",
    ///         rerun::Boxes3D::from_half_sizes({{0.5f, 0.5f, 0.5f}}
    ///         ).with_colors({rerun::Color(0, 0, 255)}),
    ///         // Use Transform3D to place the box, so we actually change the underlying coordinate frame and not just the box's pose.
    ///         rerun::Transform3D::from_translation({-2.0f, 0.0f, 0.0f})
    ///     );
    ///     rec.log("point", rerun::Points3D({{0.0f, 0.0f, 0.0f}}).with_radii({0.5f}));
    ///
    ///     // Change where the point is located by cycling through its coordinate frame.
    ///     const char* frame_ids[] = {"tf#/red_box", "tf#/blue_box"};
    ///     for (int t = 0; t <2; t++) {
    ///         rec.set_time_sequence("time", t + 1); // leave it untouched at t==0.
    ///         rec.log("point", rerun::CoordinateFrame(frame_ids[t]));
    ///     }
    /// }
    /// ```
    ///
    /// ⚠ **This type is _unstable_ and may change significantly in a way that the data won't be backwards compatible.**
    ///
    struct CoordinateFrame {
        /// The coordinate frame to use for the current entity.
        std::optional<ComponentBatch> frame_id;

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

        /// `ComponentDescriptor` for the `frame_id` field.
        static constexpr auto Descriptor_frame_id = ComponentDescriptor(
            ArchetypeName, "CoordinateFrame:frame_id",
            Loggable<rerun::components::TransformFrameId>::ComponentType
        );

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

        explicit CoordinateFrame(rerun::components::TransformFrameId _frame_id)
            : frame_id(ComponentBatch::from_loggable(std::move(_frame_id), Descriptor_frame_id)
                           .value_or_throw()) {}

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

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

        /// The coordinate frame to use for the current entity.
        CoordinateFrame with_frame_id(const rerun::components::TransformFrameId& _frame_id) && {
            frame_id =
                ComponentBatch::from_loggable(_frame_id, Descriptor_frame_id).value_or_throw();
            return std::move(*this);
        }

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