// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
// --------- Warning: This is a build system generated file. ----------
//

//! @file
//!
//! @brief This file was generated by <i>omni.bind</i>.

#include <omni/core/Interface.h>
#include <omni/core/OmniAttr.h>
#include <omni/core/ResultError.h>

#include <functional>
#include <type_traits>
#include <utility>

#ifndef OMNI_BIND_INCLUDE_INTERFACE_IMPL


//! Graph definition.  Defines work to be done as a graph.
//!
//! Nodes within a graph represent work to be done.  The actual work to be performed is described in a
//! @rstref{definition <ef_definition>}.  Each node wanting to perform work points to a defintion.
//!
//! This interface is a subclass of the work definition interface (i.e. @ref omni::graph::exec::unstable::IDef) and
//! extends @ref omni::graph::exec::unstable::IDef with methods to describe work as a graph.
//!
//! Visually:
//!
//! @rst
//!
//! .. image:: /../docs/ef-simple-w-defs.svg
//!     :align: center
//!
//! @endrst
//!
//! Above, you can see the two types of definitions: opaque definitions (described by @ref
//! omni::graph::exec::unstable::INodeDef) and graph definitions (described by this interface).
//!
//! Nodes within a graph definition can point to other graph definitions. This composibility is where EF gets its *graph
//! of graphs* moniker.
//!
//! Multiple node's in the execution graph can point to the same instance of a graph definition. This saves both space
//! and graph construction time.  However, since each graph definition can be shared, its pointer value cannot be used
//! to uniquely identify its location in the graph.  To solve this, when traversing/executing a graph definition, an
//! @ref omni::graph::exec::unstable::ExecutionPath is passed (usually via @ref
//! omni::graph::exec::unstable::ExecutionTask::getUpstreamPath()).
//!
//! When defining new graph types, it is common to create a new implementation of this interface.  See @ref
//! omni::graph::exec:unstable::NodeGraphDef for an implementation of this interface that can be easily inherited from.
//! See @rstref{Definition Creation <ef_definition_creation>} for a guide on creating your own graph definition.
//!
//! How a graph definition's nodes are traversed during execution is defined by the definition's @ref
//! omni::graph::exec::unstable::IExecutor.  See @rstref{Execution Concepts <ef_execution_concepts>} for an in-depth
//! guide on how executors and graph definitions work together during execution.
//!
//! See also @ref omni::graph::exec::unstable::INode, @ref omni::graph::exec::unstable::IExecutor, and @ref
//! omni::graph::exec::unstable::ExecutionTask.
template <>
class omni::core::Generated<omni::graph::exec::unstable::INodeGraphDef_abi>
    : public omni::graph::exec::unstable::INodeGraphDef_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::graph::exec::unstable::INodeGraphDef")

    //! Return this graph's topology object.
    //!
    //! Each @ref omni::graph::exec::unstable::INodeGraphDef owns a @ref omni::graph::exec::unstable::ITopology.
    //!
    //! The returned @ref omni::graph::exec::unstable::ITopology. will *not* have @ref omni::core::IObject::acquire()
    //! called before being returned.
    omni::graph::exec::unstable::ITopology* getTopology() noexcept;

    //! Initialize the state of the graph.
    //!
    //! It is up to the implementation of the graph type to decide whether this call needs to be propagated over all
    //! nodes within the graph or a single shared state is owned by the graph.
    //!
    //! @param  rootTask    State will be initialized for every instance of this graph. Root task will provide a path to
    //!                     allow discovery of the state.  Must not be @c nullptr.
    void initializeState(omni::graph::exec::unstable::ExecutionTask& rootTask);

    //! Pre-execution call can be used to setup the graph state prior to execution or skip entirely the execution.
    //!
    //! The given task must not be @c nullptr.
    omni::graph::exec::unstable::Status preExecute(omni::graph::exec::unstable::ExecutionTask& info) noexcept;

    //! Post-execution call can be used to finalize the execution, e.g. transfer computation results to consumers.
    //!
    //! The given task must not be @c nullptr.
    omni::graph::exec::unstable::Status postExecute(omni::graph::exec::unstable::ExecutionTask& info) noexcept;

    //! Acquire factory object allowing for allocating new node instances for this node graph def.
    //!
    //! Provided factory may be empty when graph def doesn't allow allocating new nodes outside of pass that constructed
    //! the definition in the first place.
    //!
    //! Accessing node factory is thread-safe but mutating graphs topology is not. This includes node creation.
    omni::core::ObjectPtr<omni::graph::exec::unstable::INodeFactory> getNodeFactory() noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline omni::graph::exec::unstable::ITopology* omni::core::Generated<
    omni::graph::exec::unstable::INodeGraphDef_abi>::getTopology() noexcept
{
    return getTopology_abi();
}

inline void omni::core::Generated<omni::graph::exec::unstable::INodeGraphDef_abi>::initializeState(
    omni::graph::exec::unstable::ExecutionTask& rootTask)
{
    OMNI_THROW_IF_FAILED(initializeState_abi(&rootTask));
}

inline omni::graph::exec::unstable::Status omni::core::Generated<omni::graph::exec::unstable::INodeGraphDef_abi>::preExecute(
    omni::graph::exec::unstable::ExecutionTask& info) noexcept
{
    return preExecute_abi(&info);
}

inline omni::graph::exec::unstable::Status omni::core::Generated<omni::graph::exec::unstable::INodeGraphDef_abi>::postExecute(
    omni::graph::exec::unstable::ExecutionTask& info) noexcept
{
    return postExecute_abi(&info);
}

inline omni::core::ObjectPtr<omni::graph::exec::unstable::INodeFactory> omni::core::Generated<
    omni::graph::exec::unstable::INodeGraphDef_abi>::getNodeFactory() noexcept
{
    return omni::core::steal(getNodeFactory_abi());
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
