// Copyright (c) 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/OmniAttr.h>
#include <omni/core/Interface.h>
#include <omni/core/ResultError.h>

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

#ifndef OMNI_BIND_INCLUDE_INTERFACE_IMPL


//! Control block to maintain weak and strong reference counts for an object.
//!
//! The @ref IWeakObject interface supports the notion of "weak pointers".  Unlike "strong pointers" (e.g. @ref
//! ObjectPtr) weak pointers do not affect the pointee's reference count.  While this sounds like a raw pointer (and
//! possibly a bad idea), the magic of a weak pointer is that if the pointee's reference count goes to zero, the weak
//! pointer updates its internal pointer to `nullptr`.
//!
//! @ref IWeakObjectControlBlock is an ABI-safe object used to store a pointer to both the object and the object's
//! reference count (i.e. the "strong count").  This object additionally stores a "weak count", which is a count of
//! objects pointing to the @ref IWeakObjectControlBlock.
//!
//! Both @ref WeakPtr and @ref IWeakObject affect the "weak count".
//!
//! Only @ref ObjectPtr will affect the "strong count".
//!
//! Direct usage of this object should be avoided.  See @ref WeakPtr to learn how weak pointers are used in practice.
//!
//! **Advanced: Design Considerations**
//!
//! The design of ONI's weak pointers takes three main design considerations into account:
//!
//! - The user API should work similar to <a href="https://en.cppreference.com/w/cpp/memory/weak_ptr">std::weak_ptr</a>.
//!
//! - Enabling weak pointer support for an object should should not tank performance in hot code paths.
//!
//! - Weak pointers must be able to point to object's whose DLL has been unloaded from memory.
//!
//! Above, the final point has a strong affect on the implementation of weak pointers.  In particular, this object (i.e.
//! @ref IWeakObjectControlBlock).  Consider:
//!
//! - For a virtual function to be called successfully, the code implementing the virtual function must still be loaded.
//!
//! - An @ref IWeakObjectControlBlock may outlive the DLL that created the object to which it points.
//!
//! Rather than exposing a raw struct with the weak and strong counts (and associated inline code to manipulate them),
//! this interface is used to hide both the counts and the manipulation logic.  However, this introduces virtual
//! functions, which could potentially be unloaded.  To address the unloading problem, *carb.dll* provides
//! `omni::core::getOrCreateWeakObjectControlBlock()`.  This C-ABI returns an implementation of @ref
//! IWeakObjectControlBlock implemented within *carb.dll*. This effectively avoids the DLL unloading problem, since
//! *carb.dll* is considered a core dependency that cannot be unloaded and therefore the virtual function
//! implementations for @ref IWeakObjectControlBlock will always be loaded.
template <>
class omni::core::Generated<omni::core::IWeakObjectControlBlock_abi> : public omni::core::IWeakObjectControlBlock_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::core::IWeakObjectControlBlock")

    //! Returns a pointer to the object pointed to by this control block.  May return `nullptr`.
    //!
    //! If the object pointed to by this control block has a strong reference count of zero, `nullptr` is returned.
    //! Otherwise, @ref IObject::acquire() is called on the object before being returned.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::ObjectPtr<omni::core::IObject> getObject() noexcept;
};

//! Interface defining a contract for objects which support "weak"/non-owning references.
//!
//! This interface works tightly with @ref WeakPtr to implement weak pointers.  Users of weak pointers should focus on
//! @ref WeakPtr rather than this interface, as this interface is an implementation detail of the weak pointer ABI.
//!
//! Developers wishing to add weak pointer support to their objects must implement this interface, which is a
//! non-trivial task.  A default implementation is provided in @ref ImplementsWeak.
template <>
class omni::core::Generated<omni::core::IWeakObject_abi> : public omni::core::IWeakObject_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::core::IWeakObject")

    //! Returns a control block containing reference count information needed for the implementation of weak pointers.
    //!
    //! Users of weak pointers must never call this method.  Rather, they should focus on exclusively using @ref
    //! WeakPtr.
    //!
    //! Implementers of this method are encouraged to use the implementation found in @ref omni::core::ImplementsWeak.
    //!
    //! The returns pointer is never `nullptr`.
    //!
    //! The returned pointer will have @ref IObject::acquire() called on it before being returned.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::ObjectPtr<omni::core::IWeakObjectControlBlock> getWeakObjectControlBlock() noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline omni::core::ObjectPtr<omni::core::IObject> omni::core::Generated<omni::core::IWeakObjectControlBlock_abi>::getObject() noexcept
{
    return omni::core::steal(getObject_abi());
}

inline omni::core::ObjectPtr<omni::core::IWeakObjectControlBlock> omni::core::Generated<
    omni::core::IWeakObject_abi>::getWeakObjectControlBlock() noexcept
{
    return omni::core::steal(getWeakObjectControlBlock_abi());
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
