// 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.
//

//! @file IExecutionController.h
//!
//! @brief Defines @ref omni::kit::exec::core::unstable::IExecutionController.
#pragma once

#include <omni/graph/exec/unstable/IBase.h>
#include <omni/kit/IStageUpdate.h> // StageUpdateSettings

//! @defgroup groupOmniKitExecCoreInterfaces API Interfaces
//!
//! @brief Convenience interfaces backed by a stable ABI.

namespace omni
{

namespace graph
{

namespace exec
{
namespace unstable
{

class IDef;
class IGraph;

} // namespace unstable
} // namespace exec
} // namespace graph

namespace kit
{

namespace exec
{

//! Main namespace for Kit's integration of @ref omni::graph::exec.
namespace core
{

//! In-development interfaces for Kit's integration with Execution Framework.
//! Do not take dependencies on any code in this namespace.
namespace unstable
{

// forward declarations needed by interface declaration
class IExecutionContext;
class IExecutionController;
class IExecutionController_abi;

//! @ref omni::kit::exec::core::unstable::IExecutionController encapsulates a @ref omni::graph::exec::unstable::IGraph
//! which orchestrates the computation for one of Kit's @c UsdContext.
//!
//! See @ref omni::kit::exec::core::unstable::IExecutionControllerFactory.
class IExecutionController_abi
    : public omni::core::Inherits<graph::exec::unstable::IBase, OMNI_TYPE_ID("omni.kit.exec.core.unstable.IExecutionController")>
{
protected:
    //! Populates or updates the internal @ref omni::graph::exec::unstable::IGraph.
    virtual OMNI_ATTR("throw_result") omni::core::Result compile_abi() noexcept = 0;

    //! Searches for the @ref omni::graph::exec::unstable::IDef and executes it.  Useful for on-demand execution.
    //!
    //! @p *outExecuted is update to @c true if execution was successful, @c false otherwise.
    //!
    //! An exception will be thrown for all internal errors (e.g. memory allocation failures).
    //!
    //! This method is not thread safe, only a single thread should call this method at any given time.
    virtual OMNI_ATTR("throw_result") omni::core::Result
        executeDefinition_abi(OMNI_ATTR("not_null, throw_if_null") omni::graph::exec::unstable::IDef* execDef,
                              OMNI_ATTR("out, not_null, throw_if_null, *return") bool* outExecuted) noexcept = 0;

    //! Executes the internal graph at the given time.
    //!
    //! @p *outExecuted is update to @c true if execution was successful, @c false otherwise.
    //!
    //! An exception will be thrown for all internal errors (e.g. memory allocation failures).
    //!
    //! This method is not thread safe, only a single thread should call this method at any given time.
    virtual OMNI_ATTR("throw_result") omni::core::Result
        execute_abi(double currentTime,
                    float elapsedSecs,
                    double absoluteSimTime,
                    OMNI_ATTR("in") const omni::kit::StageUpdateSettings* updateSettings,
                    OMNI_ATTR("out, not_null, throw_if_null, *return") bool* outExecuted) noexcept = 0;

    //! Returns the context owned by this controller
    //!
    //! The returned @ref omni::kit::exec::core::unstable::IExecutionContext will *not* have @ref
    //! omni::core::IObject::acquire() called before being returned.
    virtual OMNI_ATTR("no_acquire") IExecutionContext* getContext_abi() noexcept = 0;

    //! Returns the graph owned by this controller
    //!
    //! The returned @ref omni::graph::exec::unstable::IGraph will *not* have @ref
    //! omni::core::IObject::acquire() called before being returned.
    virtual OMNI_ATTR("no_acquire") omni::graph::exec::unstable::IGraph* getGraph_abi() noexcept = 0;
};

//! Smart pointer for @ref omni::kit::exec::core::unstable::IExecutionController.
using ExecutionControllerPtr = omni::core::ObjectPtr<IExecutionController>;

} // namespace unstable
} // namespace core
} // namespace exec
} // namespace kit
} // namespace omni

// generated API declaration
#define OMNI_BIND_INCLUDE_INTERFACE_DECL
#include <omni/kit/exec/core/unstable/IExecutionController.gen.h>

//! @copydoc omni::kit::exec::core::unstable::IExecutionController_abi
//!
//! @ingroup groupOmniKitExecCoreInterfaces
class omni::kit::exec::core::unstable::IExecutionController
    : public omni::core::Generated<omni::kit::exec::core::unstable::IExecutionController_abi>
{
};

// additional headers needed for API implementation
#include <omni/graph/exec/unstable/IDef.h>
#include <omni/graph/exec/unstable/IGraph.h>
#include <omni/kit/exec/core/unstable/IExecutionContext.h>

// generated API implementation
#define OMNI_BIND_INCLUDE_INTERFACE_IMPL
#include <omni/kit/exec/core/unstable/IExecutionController.gen.h>
