// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.ui.scenic.internal;

// The set of error codes returned by Flatland::Present().
enum Error {
    BAD_OPERATION = 0;
};

// TODO(36766): Unify with math types for other APIs.
struct Vec2 {
    float32 x;
    float32 y;
};

/// The return type of GraphLink::GetLayout(). This table contains most of the information necessary
/// for a client to decide how to layout their content in a Flatland instance. This data may be
/// provided to the client before the command that creates the Link is presented, so that the client
/// may lay out content properly before their first call to Present().
table LayoutInfo {
    /// The layout size of a Graph in logical pixels, defined by the parent’s call to
    /// SetLinkProperties(). Clients should re-layout their content when this value changes.
    1: Vec2 logical_size;
};

/// GraphLinks will be informed when they are actively attached to a output display (either
/// directly, or through a chain of parent links) and when they are not. Until they are connected to
/// a display, some pieces of information (such as pixel scale) may be unavailable.
enum GraphLinkStatus {
    CONNECTED_TO_DISPLAY = 0;
    DISCONNECTED_FROM_DISPLAY = 1;
};

/// A protocol that provides information about a particular Link to the child client. Each Flatland
/// instance may only specify a single root transform, so other objects in the graph can only be
/// children of a single GraphLink. However, more than one GraphLink protocol may be active at a
/// time for a particular Flatland instance. Specifically, when a Flatland instance is transitioning
/// from using one Link to another, each Link will have a separate protocol instance, and more than
/// one protocol may receive certain updates.
protocol GraphLink {
    /// A hanging get for receiving layout information. Clients may receive layout information
    /// before the GraphLink operation has been presented. This allows children to layout their
    /// content before their first call to Present(). In transition cases where two GraphLink
    /// channels exist at the same time, both protocol instances will be receiving different layout
    /// information.
    ///
    /// This hanging get will only fire when the LayoutInfo is different than the previously
    /// returned LayoutInfo. Note that, since LayoutInfo is a table, only some fields may have
    /// changed.
    GetLayout() -> (LayoutInfo info);

    /// A hanging get for receiving the status of the Link. This provides global connectivity
    /// information to the child.
    ///
    /// This hanging get will only fire when the GraphLinkStatus is different than the previously
    /// returned GraphLinkStatus.
    GetStatus() -> (GraphLinkStatus status);
};

enum ContentLinkStatus {
    /// The underlying Graph has connected its Link, called Present(), the acquisition fences of
    /// the Present() call have all be reached, and the Graph's content has been rendered to an
    /// output device.
    CONTENT_HAS_PRESENTED = 0;
};

/// A protocol that provides information about a particular Link to the parent client. Flatland
/// instances may contain any number of ContentLinks, each of which may or may not be attached to
/// the Root Transform. Each ContentLink has its own protocol instance.
protocol ContentLink {
    /// A hanging get for receiving the status of a Link. This provides information to the parent,
    /// such as whether or not the child has successfully presented content through this Link.
    ///
    /// This hanging get will only fire when the ContentLinkStatus is different than the previously
    /// returned ContentLinkStatus.
    GetStatus() -> (ContentLinkStatus status);
};

/// A typed wrapper for an eventpair, representing the child endpoint of a Link.
struct GraphLinkToken {
    handle<eventpair> value;
};

/// A typed wrapper for an eventpair, representing the parent endpoint of a Link.
struct ContentLinkToken {
    handle<eventpair> value;
};

/// The properties of a Link as defined by the parent. This data, along with the set of attached
/// Transforms, will be used to compute the LayoutInfo for the child of the Link.
table LinkProperties {
    /// The size of the Link in logical pixels. This maps directly to the logical_size field in
    /// LayoutInfo.
    1: Vec2 logical_size;
};

/// A user-defined identifier for a particular transform. See CreateTransform() and
/// ReleaseTransform() for more information.
using TransformId = uint64;

/// A user-defined identifier for a particular Link. See CreateLink() for more information.
using LinkId = uint64;

/// Each Flatland instance contains a Graph, which consists of a set of objects, and the
/// relationships between those objects. The client can specify a subset of those objects
/// (specifically, the directed acyclic graph starting at the root transform) to be presented as
/// content to some kind of output -- usually, a display.
///
/// Flatland Graphs are both hierarchical, and distributed. Graphs from different Flatland instances
/// may be linked together, allowing multiple processes to be involved in authoring content for a
/// particular output.
///
/// All functions in this protocol are feed-forward. The operations they represent are not fully
/// executed until Present() is called.
protocol Flatland {
    /// Complete execution of all feed-forward operations.
    ///
    /// If executing an operation produces an error (e.g., CreateTransform(0)), Present() will
    /// return an error. Operations that produce errors are ignored. Future operations are still
    /// executed.
    ///
    /// TODO(36166): Present should stop execution, and kill the channel, when irrecoverable errors
    /// are detected.
    ///
    /// The client may only call Present() a certain number of times before it must wait for this
    /// function to return. This number or presents remaining is the return value of this function.
    /// The number of presents remaining will never drop without a corresponding call to Present()
    /// by the client. However, it may stay the same, or even increase, with each return from
    /// Present().
    ///
    /// num_presents_remaining will always be >= 1. Present() will not return until the client is
    /// allowed to call Present() again.
    Present() -> (uint32 num_presents_remaining) error Error;

    // ***** Graph management *****

    /// A Link is a connection between the objects authored in this Graph, and the objects in
    /// the Graph of another process. The parent process has control over how the linked content is
    /// integrated into their Graph.
    ///
    /// A link is formed by creating an event pair, passing one end to the parent (which calls
    /// CreateLink()) and the other end to the child (which calls LinkToParent()).
    ///
    /// Only nodes connected to the Root Transform in this Flatland instance will be rendered as
    /// part of the parent's Graph.
    ///
    /// Calling LinkToParent() a second time will disconnect the Root Transform from the existing
    /// parent's Graph, and attach it to a new parent's Graph.
    ///
    /// This function is feed-forward, meaning that the Root Transform will not be attached to the
    /// parent Graph until Present() is called. However, Clients will receive information through
    /// their GraphLinkListener (e.g., LayoutInfo) immediately after calling this function, even if
    /// they have not called Present() or SetRoot(). This allows clients to wait for layout
    /// information from their parent before calling Present(), if they wish.
    LinkToParent(GraphLinkToken token, request<GraphLink> graph_link);

    /// Disconnects this Graph from its parent Graph and returns the GraphLinkToken used to
    /// establish the link. This token can then be used to establish a new link with the Parent
    /// graph.
    ///
    /// To clear the existing content from the screen without unlinking the current Graph, use
    /// SetRootTransform(0) instead.
    ///
    /// Despite having a return type, this function is still feed-forward Like LinkToParent() and
    /// requires a call to Present() to be executed. The GraphLinkToken will be returned after the
    /// presented operations have been executed.
    UnlinkFromParent() -> (GraphLinkToken token);

    /// This function will reset all state on this interface.
    ClearGraph();

    // ***** Transforms *****

    // Transform constructors.

    /// Creates a new Transform node. Transforms are a hierarchical piece of a Flatland graph. They
    /// can have children, and can reference Content. A sub-graph represented by a Transform and its
    /// descendants can be rendered to a display.
    ///
    /// Transforms are kept alive, even when released, as long as they are children of either an
    /// unreleased Transform, or the Root Transform.
    ///
    /// Each Transform can have a single piece of attached Content. Common types of Content include
    /// bitmaps, asynchronous streams of images, and links to Transforms in other processes.
    ///
    /// Transforms have attributes. Child Transforms inherit the combined attributes of their
    /// parents. Content attached to a Transform is also affected by that Transform's attributes.
    ///
    /// When a sub-graph of Transforms is rendered, Content will be rendered back-to-front, starting
    /// with the Content on the root transform, and continuing recursively through all of its child
    /// Transforms in the order the children were added. See AddChild() for more information.
    ///
    /// Zero is not a valid transform id. All other values are valid, assuming they are not already
    /// in use (see ReleaseTransform() for more details).
    CreateTransform(TransformId transform_id);

    // Transform management

    /// Adds a child Transform to a parent Transform. The new child Transform, and any Content
    /// attached to it or its children, will be rendered on top of the parent’s Content, as well as
    /// any previously added children.
    AddChild(TransformId parent_transform_id, TransformId child_transform_id);

    /// Removes a child Transform from a parent Transform.
    RemoveChild(TransformId parent_transform_id, TransformId child_transform_id);

    /// Sets the Root Transform for the graph.
    ///
    /// The sub-graph defined by the Root Transform and its children will be rendered as Content
    /// in the linked parent Graph (see LinkToParent()). Any parents of the Root Transform in this
    /// Graph will be ignored.
    ///
    /// The Root Transform, and all children of the Root Transform, are kept alive if they are
    /// released (see ReleaseTransform() for more details).
    ///
    /// There is only ever one Root. Since 0 is not a valid transform id (see CreateTransform()),
    /// calling SetRootTransform(0) clears the current Root, destroying any previously released
    /// objects that are not referenced by the new root.
    SetRootTransform(TransformId transform_id);

    // ***** Content *****

    // Content comes in many forms, but most content can be treated conceptually as a bitmap.
    // Content is attached to Transforms. Each Transform can have, at most, one piece of attached
    // Content. Content will inherit all of the attributes from its attached Transform (which
    // inherits the attributes of its parent Transform, and so on).

    // Content is contained within a unit rectangle, with the top-left corner at the origin of the
    // coordinate space defined by the attached Transform. Content can be resized using either
    // scale attributes on transforms, or the appropriate Content mutators.

    // Content constructors

    /// A Link is a connection between the objects authored in this Graph, and the objects in
    /// another process. The parent process has control over how the linked content is integrated
    /// into their Graph through this Link object, and the object's associated Link properties.
    ///
    /// |LinkProperties| must have logical_size set. This is the initial size that will drive the
    /// layout of the child.
    CreateLink(LinkId link_id, ContentLinkToken token, LinkProperties properties,
               request<ContentLink> content_link);

    // Content management

    /// Setting a Link on a Transform makes the content from the Link visible in the render tree
    /// as long as the Transform is visible from the root Transform. The contents of the Link will
    /// be rendered before, and therefore "behind", any content attached to the descendants of the
    /// Transform.
    SetLinkOnTransform(LinkId link_id, TransformId transform_id);

    // Content mutators

    /// Transforms are usually sufficient to change how content is presented. Links, however, have
    /// special properties that are not part of the Transform hierarchy. Those properties can be set
    /// using this function.
    SetLinkProperties(LinkId link_id, LinkProperties properties);

    // ***** Cleanup operations *****

    /// Released Transforms and Content will be garbage collected by the system once they are no
    /// longer necessary for rendering (i.e., there is no path from the Root Transform to the
    /// object, all pending rendering has completed, and new Content is available). The only
    /// exceptions are Link objects (see ReleaseLink() for more details).
    ///
    /// However, once released, the id immediately goes out of scope for future function calls, and
    /// can be reused by the client when creating new Transforms and Content.
    ///
    /// It is an error to call Graph functions on a released id (unless that id has been reused to
    /// construct a new object).
    ReleaseTransform(TransformId transform_id);

    /// Releasing a Link removes the attached sub-Graph from the scene, even if the Link is still
    /// connected to a Transform. Unlike other Content, Links are garbage collected by the system
    /// during the next Present() because a released Link is guaranteed to provide no renderable
    /// content.
    ///
    /// Use SetLinkOnTransform(transform_id, 0) to clean up references to deleted Links.
    ///
    /// Despite having a return type, this function is still feed-forward Like LinkToParent() and
    /// requires a call to Present() to be executed. The ContentLinkToken will be returned after the
    /// presented operations have been executed.
    ReleaseLink(LinkId id) -> (ContentLinkToken token);
};
