carb/Error.h

File members: carb/Error.h

// 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.
//
#pragma once

#include "Defines.h"
#include "Interface.h"
#include "Types.h"
#include "Version.h"
#include "detail/DeferredLoad.h"

#include "../omni/core/Result.h"

#include <cinttypes>

namespace carb
{

using omni::core::Result;

// bring all the kResult___ values into carb namespace
#define CARB_RESULT_USE_OMNI_RESULT_GEN(symbol_, ...) using omni::core::kResult##symbol_;
OMNI_RESULT_CODE_LIST(CARB_RESULT_USE_OMNI_RESULT_GEN)

class Error;

struct ErrorApi
{
    CARB_PLUGIN_INTERFACE("carb::ErrorApi", 1, 0);

    static ErrorApi const& instance() noexcept;

    Error const*(CARB_ABI* viewCurrentError)(Result* code);

    Error*(CARB_ABI* takeCurrentError)(Result* code);

    Result(CARB_ABI* setError)(Result code, char const* message, std::size_t message_size);

    Result(CARB_ABI* setErrorTo)(Error* error);

    void(CARB_ABI* setErrorOom)();

    Result(CARB_ABI* errorRelease)(Error* error);

    Error*(CARB_ABI* errorClone)(Error const* source);

    Error*(CARB_ABI* errorCreate)(Result code, const char* message, std::size_t message_size);

    Result(CARB_ABI* getErrorInfo)(Error const* error, Result* code, char const** message, std::size_t* message_size);

    Result(CARB_ABI* getCodeDescription)(
        Result code, char const** name, std::size_t* name_size, char const** message, std::size_t* message_size);
};

} // namespace carb

#if CARB_REQUIRE_LINKED
CARB_DYNAMICLINK carb::ErrorApi const* carbGetErrorApi(carb::Version* version);
#else
CARB_DYNAMICLINK carb::ErrorApi const* carbGetErrorApi(carb::Version* version) CARB_ATTRIBUTE(weak);
#endif

namespace carb
{
namespace detail
{

CARB_DETAIL_DEFINE_DEFERRED_LOAD(getCarbErrorApiFunc, carbGetErrorApi, (carb::ErrorApi const* (*)(carb::Version*)));

} // namespace detail

inline ErrorApi const& ErrorApi::instance() noexcept
{
    static ErrorApi const* const papi = []() -> ErrorApi const* {
        const Version expected_version = ErrorApi::getInterfaceDesc().version;
        Version found_version = expected_version;

        auto p = detail::getCarbErrorApiFunc()(&found_version);
        CARB_FATAL_UNLESS(p != nullptr,
                          "Failed to load Error API for version this module was compiled against. This module was "
                          "compiled with Error API %" PRIu32 ".%" PRIu32
                          ", but the maximum-supported version of the "
                          "API in the linked %s is %" PRIu32 ".%" PRIu32,
                          expected_version.major, expected_version.minor,
                          CARB_PLATFORM_WINDOWS ? "carb.dll" : "libcarb.so", found_version.major, found_version.minor);
        return p;
    }();
    return *papi;
}

} // namespace carb