// Copyright (c) 2022, 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


//! Consumes (listens for) log messages.
//!
//! @ref omni::log::ILogMessageConsumer is usually associated with an @ref omni::log::ILog instance.  Add a consumer to
//! an @ref omni::log::ILog object with @ref omni::log::ILog::addMessageConsumer().
template <>
class omni::core::Generated<omni::log::ILogMessageConsumer_abi> : public omni::log::ILogMessageConsumer_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::log::ILogMessageConsumer")

    //! Receives a log message.
    //!
    //! Logging a message from this method results in undefined behavior.
    //!
    //! Accessing the owning @ref omni::log::ILog from this method will lead to undefined behavior.
    //!
    //! The memory pointed to by the provided pointers will remain valid only during the duration of this call.
    //!
    //! @thread_safety This method must be thread safe as the attached @ref omni::log::ILog may send messages to this
    //! object in parallel.
    void onMessage(const char* channel,
                   omni::log::Level level,
                   const char* moduleName,
                   const char* fileName,
                   const char* functionName,
                   uint32_t lineNumber,
                   const char* msg,
                   carb::thread::ProcessId pid,
                   carb::thread::ThreadId tid,
                   uint64_t timestamp) noexcept;
};

//! Consumes (listens for) state change to one or more @ref omni::log::ILog objects.
//!
//! Add this object to an omni::log::ILog via @ref omni::log::ILog::addChannelUpdateConsumer().
template <>
class omni::core::Generated<omni::log::ILogChannelUpdateConsumer_abi> : public omni::log::ILogChannelUpdateConsumer_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::log::ILogChannelUpdateConsumer")

    //! Called when an attached @ref omni::log::ILog's state changes.
    //!
    //! Accessing the given omni::log::ILog from this method is safe.
    //!
    //! If @p name is @c nullptr, the change happened to the global log (i.e. not to a specific channel).
    //!
    //! @thread_safety
    //!   This method must be thread safe as the attached ILogs may send messages to this object in parallel.
    //!
    //!   Updates may come out-of-order and may be spurious.
    void onChannelUpdate(omni::core::ObjectParam<omni::log::ILog> log,
                         omni::core::ObjectParam<omni::str::IReadOnlyCString> name,
                         omni::log::ChannelUpdateReason reason) noexcept;
};

//! Multi-channel logging interface which can write logs to multiple consumers.
//!
//! See the @rstref{Omniverse Logging Guide <carb_logging>} to better understand how logging works from both the user's
//! and developer's point-of-view.
//!
//! In practice, use of this interface is hidden to the user.  Most logging occurs via the following macros:
//!
//! - @ref OMNI_LOG_VERBOSE
//! - @ref OMNI_LOG_INFO
//! - @ref OMNI_LOG_WARN
//! - @ref OMNI_LOG_ERROR
//! - @ref OMNI_LOG_FATAL
//!
//! The macros above internally call @ref omniGetLogWithoutAcquire(), which returns an @ref omni::log::ILog pointer. See
//! @ref omniGetLogWithoutAcquire() for details on how to control which @ref omni::log::ILog pointer is returned.
//!
//! The logging interface defines two concepts: **log channels** and **log consumers**.
//!
//! **Log channels** are identified by a string and represent the idea of a logging "channel". Each channel has a:
//!
//! - Enabled/Disabled flag (see @ref omni::log::ILog::setChannelEnabled()).
//!
//! - Log level at which messages should be ignored (see @ref omni::log::ILog::setChannelLevel()).
//!
//! Each message logged is associated with a single log channel.
//!
//! Each time a message is logged, the channel's settings are checked to see if the message should be filtered out. If
//! the message is not filtered, the logging interface formats the message and passes it to each log message consumer.
//!
//! **Log consumers** (e.g. @ref omni::log::ILogMessageConsumer) are attached to the logging system via @ref
//! omni::log::ILog::addMessageConsumer().  Along with the formatted message, log consumers are passed a bevvy of
//! additional information, such as filename, line number, channel name, message level, etc. The consumer may choose to
//! perform additional filtering at this point. Eventually, it is up to the log consumer to "log" the message to its
//! backing store (e.g. `stdout`).
//!
//! The @ref omni::log::ILog interface itself has a global enable/disabled flag and log level. Each channel can choose
//! to respect the global flags (via @ref omni::log::SettingBehavior::eInherit) or override the global flags with their
//! own (via @ref omni::log::SettingBehavior::eOverride).
//!
//! With these settings, user have fine-grain control over which messages are filtered and where messages are logged.
//!
//! See @ref OMNI_LOG_ADD_CHANNEL() for information on creating and registering log channels.
//!
//! In order to support rich user experiences, the logging system also allows consumers to be notified of internal state
//! changes such as a channel being added, the logging level changing, etc.  See @ref
//! omni::log::ILog::addChannelUpdateConsumer() for details.
template <>
class omni::core::Generated<omni::log::ILog_abi> : public omni::log::ILog_abi
{
public:
    OMNI_PLUGIN_INTERFACE("omni::log::ILog")

    //! Sends the supplied message to all registered @ref omni::log::ILogMessageConsumer objects.
    //!
    //! @param str Must be a `\0` terminated string.
    //!
    //! @param strCharCount The number of characters in @p str (including the terminating `\0`). If @p strCharCount is
    //! 0, its value will be computed by this method.
    void log(const char* channel,
             omni::log::Level level,
             const char* moduleName,
             const char* fileName,
             const char* functionName,
             uint32_t lineNumber,
             const char* str,
             uint32_t strCharCount) noexcept;

    //! Formats the supplied message and sends the result to all registered @ref omni::log::ILogMessageConsumer objects.
    void logf(const char* channel,
              omni::log::Level level,
              const char* moduleName,
              const char* fileName,
              const char* functionName,
              uint32_t lineNumber,
              const char* format,
              ...) noexcept;

    //! Adds the given log consumer to the internal list of log consumers.
    //!
    //! Each message is associated with a single log channel.  When a message is logged by a log channel, the message is
    //! checked to see if it should be filtered.  If not, it is given to the logging system (@ref omni::log::ILog) which
    //! eventually sends the message to each registered @ref omni::log::ILogMessageConsumer.
    //!
    //! A consumer can be registered a single time with a given @ref omni::log::ILog instance but can be registered with
    //! multiple @ref omni::log::ILog instances.
    //!
    //! Each message may be sent to registered consumers in parallel.
    //!
    //! Logging a message from a consumer callback will lead to undefined behavior.
    //!
    //! Calling @ref omni::log::ILog::addMessageConsumer() from @ref omni::log::ILogMessageConsumer::onMessage() will
    //! lead to undefined behavior.
    //!
    //! @thread_safety This method is thread safe.
    void addMessageConsumer(omni::core::ObjectParam<omni::log::ILogMessageConsumer> consumer) noexcept;

    //! Removes the given consumer from the internal consumer list.
    //!
    //! This method silently accepts `nullptr`.
    //!
    //! This method silently accepts consumers that have not been registered with this object.
    //!
    //! Calling @ref omni::log::ILog::removeMessageConsumer() from omni::log::ILogMessageConsumer::onMessage() will lead
    //! to undefined behavior.
    //!
    //! @thread_safety This method is thread safe.
    void removeMessageConsumer(omni::core::ObjectParam<omni::log::ILogMessageConsumer> consumer) noexcept;

    //! Set the logging level of this object.
    //!
    //! By default log channels obey the logging level set on this object.  However, this behavior can be overridden
    //! with @ref omni::log::ILog::setChannelLevel().
    //!
    //! @thread_safety This method is thread safe.
    void setLevel(omni::log::Level level) noexcept;

    //! Returns the logging level of this object.
    //!
    //! @thread_safety This method is thread safe.
    omni::log::Level getLevel() noexcept;

    //! Set if the log is enabled/disabled.
    //!
    //! By default log channels obey the enable/disabled flag set on this object.  However, this behavior can be
    //! overridden with @ref omni::log::ILog::setChannelEnabled().
    //!
    //! @thread_safety This method is thread safe.
    void setEnabled(bool isEnabled) noexcept;

    //! Returns if the log is enabled/disabled.
    //!
    //! @thread_safety This method is thread safe.
    bool isEnabled() noexcept;

    //! Instructs the logging system to deliver all log messages to the logging backends asynchronously.
    //!
    //! This causes @ref omni::log::ILog::log() calls to be buffered so that @ref omni::log::ILog::log() may return as
    //! quickly as possible. A background thread then issues these buffered log messages to the registered Logger
    //! backend objects.
    //!
    //! @thread_safety This method is thread safe.
    //!
    //! @returns Returns the state of asynchronous logging before this method was called.
    bool setAsync(bool logAsync) noexcept;

    //! Returns `true` if asynchronous logging is enabled.
    //!
    //! @thread_safety This method is thread safe.
    bool isAsync() noexcept;

    //! Associates a log channel's id with a chunk of memory to store its settings.
    //!
    //! A log channel can be registered multiple times.  In fact, this is quite common, as a log channel's settings are
    //! usually stored per-module and a log channel may span multiple modules.
    //!
    //! When registering a channel via this API, the given setting's memory is updated.
    //!
    //! @param name Name of the channel. Copied by this method.
    //!
    //! @param level Pointer to where the channels level is stored.  The pointer must point to valid memory until @ref
    //! omni::log::ILog::removeChannel() is called.
    //!
    //! @param description The description of the channel.  Can be `nullptr`.  If not `nullptr`, and a description for
    //! the channel is already set and not empty, the given description is ignored.  Otherwise, the description is
    //! copied by this method.
    //!
    //! @thread_safety This method is thread safe.
    void addChannel(const char* name, omni::log::Level* level, const char* description) noexcept;

    //! Removes a log channel's settings memory.
    //!
    //! Use this method when unloading a module to prevent the log writing settings to unloaded memory.
    //!
    //! @thread_safety This method is thread safe.
    void removeChannel(const char* name, omni::log::Level* level) noexcept;

    //! Sets the given channel's log level.
    //!
    //! If the channel has not yet been registered with @ref omni::log::ILog::addChannel(), the setting will be
    //! remembered and applied when the channel is eventually added.
    //!
    //! @thread_safety This method is thread safe.
    void setChannelLevel(const char* name, omni::log::Level level, omni::log::SettingBehavior behavior) noexcept;

    //! Returns the given channel's logging level and override behavior.
    //!
    //! All parameters must be non-`nullptr`.
    //!
    //! If the given channel is not found, an @ref omni::core::kResultNotFound is returned.
    //!
    //! @return Returns @ref omni::core::kResultSuccess upon success, a failure code otherwise.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::Result getChannelLevel(const char* name,
                                       omni::log::Level* outLevel,
                                       omni::log::SettingBehavior* outBehavior) noexcept;

    //! Sets the given channel's enabled/disabled flag.
    //!
    //! If the channel has not yet been registered with @ref omni::log::ILog::addChannel(), the setting will be
    //! remembered and applied when the channel is eventually added.
    //!
    //! @thread_safety This method is thread safe.
    void setChannelEnabled(const char* name, bool isEnabled, omni::log::SettingBehavior behavior) noexcept;

    //! Returns the given channel's logging enabled state and override behavior.
    //!
    //! All parameters must be non-`nullptr`.
    //!
    //! If the given channel is not found, an @ref omni::core::kResultNotFound is returned.
    //!
    //! Return @ref omni::core::kResultSuccess upon success, a failure code otherwise.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::Result getChannelEnabled(const char* name,
                                         bool* outIsEnabled,
                                         omni::log::SettingBehavior* outBehavior) noexcept;

    //! Sets a channel's description.  If the channel does not exists, it is created.
    //!
    //! The given channel @p name and @p description must not be `nullptr`.
    //!
    //! The memory pointed to by @p description is copied by this method.
    //!
    //! If the channel already has a description, it is replaced.
    //!
    //! @thread_safety This method is thread safe.
    void setChannelDescription(const char* name, const char* description) noexcept;

    //! Returns the given channel's description.
    //!
    //! All parameters must be non-`nullptr`.
    //!
    //! When calling this method, @p *outDescription must be `nullptr`.
    //!
    //! If the channel does not have a description set, @p *outDescription is set to `nullptr`.
    //!
    //! If @p *outDescription is set to non-`nullptr`, it will have @ref omni::core::IObject::acquire() called on it
    //! before it is passed back to the caller.
    //!
    //! If the given channel is not found, an @ref omni::core::kResultNotFound is returned.
    //!
    //! @return Returns @ref omni::core::kResultSuccess upon success, a failure code otherwise.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::Result getChannelDescription(const char* name, omni::str::IReadOnlyCString** outDescription) noexcept;

    //! Given a channel and a verbosity level, returns `true` if the channel is actively logging at the given level.
    //!
    //! Using the `OMNI_LOG_*` macros is preferred over this method, as those macros use a much more efficient method to
    //! filter messages.  However, the mechanics utilized by `OMNI_LOG_*` are not viable when binding to languages such
    //! as Python, thus this method's existence.
    //!
    //! @thread_safety This method is thread safe.
    bool isLoggingAtLevel(const char* name, omni::log::Level level) noexcept;

    //! Flush all queued messages to message consumers.
    //!
    //! If asynchronous logging is enabled (see @ref omni::log::ILog::setAsync), blocks until all pending messages have
    //! been delivered to message consumers.
    //!
    //! @thread_safety This method is thread safe.
    void flush() noexcept;

    //! Adds the given channel updated consumer to the internal list of update consumers.
    //!
    //! Each time the state of the log changes, each update consumer is notified.
    //!
    //! A consumer can be registered a single time with a given @ref omni::log::ILog instance but can be registered with
    //! multiple @ref omni::log::ILog instances.
    //!
    //! Each message may be sent to registered consumers in parallel.
    //!
    //! It is safe to access @ref omni::log::ILog from the callback.
    //!
    //! @thread_safety This method is thread safe.
    void addChannelUpdateConsumer(omni::core::ObjectParam<omni::log::ILogChannelUpdateConsumer> consumer) noexcept;

    //! Removes the given consumer from the internal consumer list.
    //!
    //! This method silently accepts `nullptr`.
    //!
    //! This method silently accepts consumers that have not been registered with this object.
    //!
    //! Calling @ref omni::log::ILog::removeChannelUpdateConsumer() from @ref
    //! omni::log::ILogMessageConsumer::onMessage() will lead to undefined behavior.
    //!
    //! @thread_safety This method is thread safe.
    void removeChannelUpdateConsumer(omni::core::ObjectParam<omni::log::ILogChannelUpdateConsumer> consumer) noexcept;

    //! Adds the given log consumer to the internal list of log consumers.
    //!
    //! Each message is associated with a single log channel.  When a message is logged by a log channel, the message is
    //! checked to see if it should be filtered.  If not, it is given to the logging system (@ref omni::log::ILog) which
    //! eventually sends the message to each registered @ref omni::log::ILogMessageConsumer.
    //!
    //! A consumer can be registered a single time with a given @ref omni::log::ILog instance but can be registered with
    //! multiple @ref omni::log::ILog instances.
    //!
    //! Each message may be sent to registered consumers in parallel.
    //!
    //! Logging a message from a consumer callback will lead to undefined behavior.
    //!
    //! Calling @ref omni::log::ILog::addMessageConsumer() from @ref omni::log::ILogMessageConsumer::onMessage() will
    //! lead to undefined behavior.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::ObjectPtr<omni::log::ILogMessageConsumer> addMessageConsumer(
        std::function<void(const char* channel,
                           omni::log::Level level,
                           const char* moduleName,
                           const char* fileName,
                           const char* functionName,
                           uint32_t lineNumber,
                           const char* msg,
                           carb::thread::ProcessId pid,
                           carb::thread::ThreadId tid,
                           uint64_t timestamp)> fun) noexcept;

    //! Adds the given channel updated consumer to the internal list of update consumers.
    //!
    //! Each time the state of the log changes, each update consumer is notified.
    //!
    //! A consumer can be registered a single time with a given @ref omni::log::ILog instance but can be registered with
    //! multiple @ref omni::log::ILog instances.
    //!
    //! Each message may be sent to registered consumers in parallel.
    //!
    //! It is safe to access @ref omni::log::ILog from the callback.
    //!
    //! @thread_safety This method is thread safe.
    omni::core::ObjectPtr<omni::log::ILogChannelUpdateConsumer> addChannelUpdateConsumer(
        std::function<void(omni::log::ILog* log, omni::str::IReadOnlyCString* name, omni::log::ChannelUpdateReason reason)>
            fun) noexcept;
};

#endif

#ifndef OMNI_BIND_INCLUDE_INTERFACE_DECL

inline void omni::core::Generated<omni::log::ILogMessageConsumer_abi>::onMessage(const char* channel,
                                                                                 omni::log::Level level,
                                                                                 const char* moduleName,
                                                                                 const char* fileName,
                                                                                 const char* functionName,
                                                                                 uint32_t lineNumber,
                                                                                 const char* msg,
                                                                                 carb::thread::ProcessId pid,
                                                                                 carb::thread::ThreadId tid,
                                                                                 uint64_t timestamp) noexcept
{
    onMessage_abi(channel, level, moduleName, fileName, functionName, lineNumber, msg, pid, tid, timestamp);
}

inline void omni::core::Generated<omni::log::ILogChannelUpdateConsumer_abi>::onChannelUpdate(
    omni::core::ObjectParam<omni::log::ILog> log,
    omni::core::ObjectParam<omni::str::IReadOnlyCString> name,
    omni::log::ChannelUpdateReason reason) noexcept
{
    onChannelUpdate_abi(log.get(), name.get(), reason);
}

inline void omni::core::Generated<omni::log::ILog_abi>::log(const char* channel,
                                                            omni::log::Level level,
                                                            const char* moduleName,
                                                            const char* fileName,
                                                            const char* functionName,
                                                            uint32_t lineNumber,
                                                            const char* str,
                                                            uint32_t strCharCount) noexcept
{
    log_abi(channel, level, moduleName, fileName, functionName, lineNumber, str, strCharCount);
}

inline void omni::core::Generated<omni::log::ILog_abi>::logf(const char* channel,
                                                             omni::log::Level level,
                                                             const char* moduleName,
                                                             const char* fileName,
                                                             const char* functionName,
                                                             uint32_t lineNumber,
                                                             const char* format,
                                                             ...) noexcept
{
    va_list arg_list_;
    va_start(arg_list_, format);
    logf_abi(channel, level, moduleName, fileName, functionName, lineNumber, format, arg_list_);
    va_end(arg_list_);
}

inline void omni::core::Generated<omni::log::ILog_abi>::addMessageConsumer(
    omni::core::ObjectParam<omni::log::ILogMessageConsumer> consumer) noexcept
{
    addMessageConsumer_abi(consumer.get());
}

inline void omni::core::Generated<omni::log::ILog_abi>::removeMessageConsumer(
    omni::core::ObjectParam<omni::log::ILogMessageConsumer> consumer) noexcept
{
    removeMessageConsumer_abi(consumer.get());
}

inline void omni::core::Generated<omni::log::ILog_abi>::setLevel(omni::log::Level level) noexcept
{
    setLevel_abi(level);
}

inline omni::log::Level omni::core::Generated<omni::log::ILog_abi>::getLevel() noexcept
{
    return getLevel_abi();
}

inline void omni::core::Generated<omni::log::ILog_abi>::setEnabled(bool isEnabled) noexcept
{
    setEnabled_abi(isEnabled);
}

inline bool omni::core::Generated<omni::log::ILog_abi>::isEnabled() noexcept
{
    return isEnabled_abi();
}

inline bool omni::core::Generated<omni::log::ILog_abi>::setAsync(bool logAsync) noexcept
{
    return setAsync_abi(logAsync);
}

inline bool omni::core::Generated<omni::log::ILog_abi>::isAsync() noexcept
{
    return isAsync_abi();
}

inline void omni::core::Generated<omni::log::ILog_abi>::addChannel(const char* name,
                                                                   omni::log::Level* level,
                                                                   const char* description) noexcept
{
    addChannel_abi(name, level, description);
}

inline void omni::core::Generated<omni::log::ILog_abi>::removeChannel(const char* name, omni::log::Level* level) noexcept
{
    removeChannel_abi(name, level);
}

inline void omni::core::Generated<omni::log::ILog_abi>::setChannelLevel(const char* name,
                                                                        omni::log::Level level,
                                                                        omni::log::SettingBehavior behavior) noexcept
{
    setChannelLevel_abi(name, level, behavior);
}

inline omni::core::Result omni::core::Generated<omni::log::ILog_abi>::getChannelLevel(
    const char* name, omni::log::Level* outLevel, omni::log::SettingBehavior* outBehavior) noexcept
{
    return getChannelLevel_abi(name, outLevel, outBehavior);
}

inline void omni::core::Generated<omni::log::ILog_abi>::setChannelEnabled(const char* name,
                                                                          bool isEnabled,
                                                                          omni::log::SettingBehavior behavior) noexcept
{
    setChannelEnabled_abi(name, isEnabled, behavior);
}

inline omni::core::Result omni::core::Generated<omni::log::ILog_abi>::getChannelEnabled(
    const char* name, bool* outIsEnabled, omni::log::SettingBehavior* outBehavior) noexcept
{
    return getChannelEnabled_abi(name, outIsEnabled, outBehavior);
}

inline void omni::core::Generated<omni::log::ILog_abi>::setChannelDescription(const char* name,
                                                                              const char* description) noexcept
{
    setChannelDescription_abi(name, description);
}

inline omni::core::Result omni::core::Generated<omni::log::ILog_abi>::getChannelDescription(
    const char* name, omni::str::IReadOnlyCString** outDescription) noexcept
{
    return getChannelDescription_abi(name, outDescription);
}

inline bool omni::core::Generated<omni::log::ILog_abi>::isLoggingAtLevel(const char* name, omni::log::Level level) noexcept
{
    return isLoggingAtLevel_abi(name, level);
}

inline void omni::core::Generated<omni::log::ILog_abi>::flush() noexcept
{
    flush_abi();
}

inline void omni::core::Generated<omni::log::ILog_abi>::addChannelUpdateConsumer(
    omni::core::ObjectParam<omni::log::ILogChannelUpdateConsumer> consumer) noexcept
{
    addChannelUpdateConsumer_abi(consumer.get());
}

inline void omni::core::Generated<omni::log::ILog_abi>::removeChannelUpdateConsumer(
    omni::core::ObjectParam<omni::log::ILogChannelUpdateConsumer> consumer) noexcept
{
    removeChannelUpdateConsumer_abi(consumer.get());
}

inline omni::core::ObjectPtr<omni::log::ILogMessageConsumer> omni::core::Generated<omni::log::ILog_abi>::addMessageConsumer(
    std::function<void(const char* channel,
                       omni::log::Level level,
                       const char* moduleName,
                       const char* fileName,
                       const char* functionName,
                       uint32_t lineNumber,
                       const char* msg,
                       carb::thread::ProcessId pid,
                       carb::thread::ThreadId tid,
                       uint64_t timestamp)> fun) noexcept
{

    class Consumer : public omni::core::Implements<omni::log::ILogMessageConsumer>
    {
    public:
        virtual void onMessage_abi(const char* channel,
                                   omni::log::Level level,
                                   const char* moduleName,
                                   const char* fileName,
                                   const char* functionName,
                                   uint32_t lineNumber,
                                   const char* msg,
                                   carb::thread::ProcessId pid,
                                   carb::thread::ThreadId tid,
                                   uint64_t timestamp) noexcept override
        {
            m_function(channel, level, moduleName, fileName, functionName, lineNumber, msg, pid, tid, timestamp);
        }

        Consumer(std::function<void(const char* channel,
                                    omni::log::Level level,
                                    const char* moduleName,
                                    const char* fileName,
                                    const char* functionName,
                                    uint32_t lineNumber,
                                    const char* msg,
                                    carb::thread::ProcessId pid,
                                    carb::thread::ThreadId tid,
                                    uint64_t timestamp)> cb)
            : m_function(std::move(cb))
        {
        }

    private:
        std::function<void(const char* channel,
                           omni::log::Level level,
                           const char* moduleName,
                           const char* fileName,
                           const char* functionName,
                           uint32_t lineNumber,
                           const char* msg,
                           carb::thread::ProcessId pid,
                           carb::thread::ThreadId tid,
                           uint64_t timestamp)>
            m_function;
    };

    auto consumer{ omni::core::steal(new Consumer{ std::move(fun) }) };
    addMessageConsumer_abi(consumer.get());
    return consumer;
}

inline omni::core::ObjectPtr<omni::log::ILogChannelUpdateConsumer> omni::core::Generated<omni::log::ILog_abi>::addChannelUpdateConsumer(
    std::function<void(omni::log::ILog* log, omni::str::IReadOnlyCString* name, omni::log::ChannelUpdateReason reason)> fun) noexcept
{

    class Consumer : public omni::core::Implements<omni::log::ILogChannelUpdateConsumer>
    {
    public:
        virtual void onChannelUpdate_abi(omni::log::ILog* log,
                                         omni::str::IReadOnlyCString* name,
                                         omni::log::ChannelUpdateReason reason) noexcept override
        {
            m_function(log, name, reason);
        }

        Consumer(std::function<
                 void(omni::log::ILog* log, omni::str::IReadOnlyCString* name, omni::log::ChannelUpdateReason reason)> cb)
            : m_function(std::move(cb))
        {
        }

    private:
        std::function<void(omni::log::ILog* log, omni::str::IReadOnlyCString* name, omni::log::ChannelUpdateReason reason)>
            m_function;
    };

    auto consumer{ omni::core::steal(new Consumer{ std::move(fun) }) };
    addChannelUpdateConsumer_abi(consumer.get());
    return consumer;
}

#endif

#undef OMNI_BIND_INCLUDE_INTERFACE_DECL
#undef OMNI_BIND_INCLUDE_INTERFACE_IMPL
