omni/ext/IExtensions.h

File members: omni/ext/IExtensions.h

// Copyright (c) 2020-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 "../../carb/Framework.h"
#include "../../carb/IObject.h"
#include "../../carb/Interface.h"
#include "../../carb/events/IEvents.h"

namespace omni
{
namespace ext
{

struct Version
{
    int32_t major;
    int32_t minor;
    int32_t patch;
    const char* prerelease;
    const char* build;
};

struct ExtensionInfo
{
    const char* id;
    const char* name;
    const char* packageId;
    Version version;
    bool enabled;
    const char* title;
    const char* path;
};

enum class ExtensionPathType
{
    eCollection,
    eDirectPath,
    eExt1Folder,
    eCollectionUser,
    eCollectionCache,
    eCount
};

struct ExtensionFolderInfo
{
    const char* path;
    ExtensionPathType type;
};

struct RegistryProviderInfo
{
    const char* name;
};

using ExtensionSummaryFlag = uint32_t;

constexpr ExtensionSummaryFlag kExtensionSummaryFlagNone = 0;

constexpr ExtensionSummaryFlag kExtensionSummaryFlagAnyEnabled = (1 << 1);

constexpr ExtensionSummaryFlag kExtensionSummaryFlagBuiltin = (1 << 2);

constexpr ExtensionSummaryFlag kExtensionSummaryFlagInstalled = (1 << 3);

struct ExtensionSummary
{
    const char* fullname;
    ExtensionSummaryFlag flags;

    ExtensionInfo enabledVersion;

    ExtensionInfo latestVersion;
};

const carb::events::EventType kEventScriptChanged = CARB_EVENTS_TYPE_FROM_STR("SCRIPT_CHANGED");

const carb::events::EventType kEventFolderChanged = CARB_EVENTS_TYPE_FROM_STR("FOLDER_CHANGED");

const carb::events::EventType kEventRegistryRefreshBegin = CARB_EVENTS_TYPE_FROM_STR("omni.ext.REGISTRY_REFRESH_BEGIN");

const carb::events::EventType kEventRegistryRefreshEndSuccess =
    CARB_EVENTS_TYPE_FROM_STR("omni.ext.REGISTRY_REFRESH_END_SUCCESS");

const carb::events::EventType kEventRegistryRefreshEndFailure =
    CARB_EVENTS_TYPE_FROM_STR("omni.ext.REGISTRY_REFRESH_END_FAILURE");

const carb::events::EventType kEventExtensionPullBegin = CARB_EVENTS_TYPE_FROM_STR("omni.ext.EXTENSION_PULL_BEGIN");

const carb::events::EventType kEventExtensionPullEndSuccess =
    CARB_EVENTS_TYPE_FROM_STR("omni.ext.EXTENSION_PULL_END_SUCCESS");

const carb::events::EventType kEventExtensionPullEndFailure =
    CARB_EVENTS_TYPE_FROM_STR("omni.ext.EXTENSION_PULL_END_FAILURE");

struct VersionLockDesc
{
    bool separateFile;
    bool skipCoreExts;
    bool overwrite;
};

enum class DownloadState
{
    eDownloading,
    eDownloadSuccess,
    eDownloadFailure
};

struct SolverInput
{
    const char** extensionNames;

    size_t extensionNameCount;

    bool addEnabled;

    bool returnOnlyDisabled;
};

class IRegistryProvider : public carb::IObject
{
public:
    virtual DownloadState refreshIndex() = 0;

    virtual carb::dictionary::Item* syncIndex() = 0;

    virtual bool publishExtension(const char* extPath, carb::dictionary::Item* extDict) = 0;

    virtual bool unpublishExtension(const char* extId) = 0;

    virtual bool pullExtension(const char* extId, const char* extFolder) = 0;

    virtual DownloadState pullExtensionAsync(const char* extId, const char* extFolder) = 0;

    CARB_DEPRECATED("Not called. Index stripping was deprecated.") virtual bool setMaxStrippingLevel(int32_t level) = 0;
};

using IRegistryProviderPtr = carb::ObjectPtr<IRegistryProvider>;

class IPathProtocolProvider : public carb::IObject
{
public:
    virtual const char* addPath(const char* url) = 0;

    virtual void removePath(const char* url) = 0;
};

using IPathProtocolProviderPtr = carb::ObjectPtr<IPathProtocolProvider>;

class IExtensionManagerHooks;

class ExtensionManager : public carb::IObject
{
public:
    virtual void processAndApplyAllChanges() = 0;

    virtual size_t getExtensionCount() const = 0;

    virtual void getExtensions(ExtensionInfo* extensions) const = 0;

    virtual carb::dictionary::Item* getExtensionDict(const char* extId) const = 0;

    void setExtensionEnabled(const char* extensionId, bool enabled)
    {
        setExtensionEnabledBatch(&extensionId, 1, enabled);
    }

    virtual void setExtensionEnabledBatch(const char** extensionIds, size_t extensionIdCount, bool enabled) = 0;

    bool setExtensionEnabledImmediate(const char* extensionId, bool enabled)
    {
        return setExtensionEnabledBatchImmediate(&extensionId, 1, enabled);
    }

    virtual bool setExtensionEnabledBatchImmediate(const char** extensionIds, size_t extensionIdCount, bool enabled) = 0;

    virtual void setExtensionsExcluded(const char** extensionIds, size_t extensionIdCount) = 0;

    virtual size_t getFolderCount() const = 0;

    virtual void getFolders(ExtensionFolderInfo* extensionFolderInfos) const = 0;

    virtual void addPath(const char* path, ExtensionPathType type = ExtensionPathType::eCollection) = 0;

    virtual void removePath(const char* path) = 0;

    virtual carb::events::IEventStream* getChangeEventStream() const = 0;

    virtual IExtensionManagerHooks* getHooks() const = 0;

    virtual bool addRegistryProvider(const char* providerName, IRegistryProvider* provider) = 0;

    virtual void removeRegistryProvider(const char* providerName) = 0;

    virtual size_t getRegistryProviderCount() const = 0;

    virtual void getRegistryProviders(RegistryProviderInfo* infos) = 0;

    virtual void refreshRegistry() = 0;

    virtual bool syncRegistry() = 0;

    virtual size_t getRegistryExtensionCount() const = 0;

    virtual void getRegistryExtensions(ExtensionInfo* extensions) const = 0;

    virtual size_t getRegistryExtensionPackageCount() const = 0;

    virtual void getRegistryExtensionPackages(ExtensionInfo* extensions) const = 0;

    virtual carb::dictionary::Item* getRegistryExtensionDict(const char* extId) = 0;

    virtual bool publishExtension(const char* extId, const char* providerName = "", bool allowOverwrite = false) = 0;

    virtual bool unpublishExtension(const char* extId, const char* providerName = "") = 0;

    virtual bool pullExtension(const char* extId) = 0;

    virtual void pullExtensionAsync(const char* extId) = 0;

    virtual void fetchExtensionSummaries(ExtensionSummary** summaries, size_t* summaryCount) = 0;

    virtual void fetchExtensionVersions(const char* nameAndVersion, ExtensionInfo** extensions, size_t* extensionCount) = 0;

    virtual void fetchExtensionPackages(const char* nameAndVersion, ExtensionInfo** extensions, size_t* extensionCount) = 0;

    virtual void disableAllExtensions() = 0;

    virtual void addUserPaths() = 0;

    virtual void addCachePath() = 0;

    virtual bool generateVersionLock(const char* extId, const VersionLockDesc& desc) = 0;

    virtual bool addPathProtocolProvider(const char* scheme, IPathProtocolProvider* provider) = 0;

    virtual void removePathProtocolProvider(const char* scheme) = 0;

    virtual bool solveExtensions(const SolverInput& input,
                                 ExtensionInfo** extensions,
                                 size_t* extensionCount,
                                 const char** errorMessage) = 0;

    virtual size_t getExtensionPackageCount() const = 0;

    virtual void getExtensionPackages(ExtensionInfo* extensions) const = 0;

    virtual bool uninstallExtension(const char* extId) = 0;
};

struct IExtensions
{
    CARB_PLUGIN_INTERFACE("omni::ext::IExtensions", 1, 1)

    ExtensionManager*(CARB_ABI* createExtensionManagerPtr)(carb::events::IEventStream* changeEventStream);

    carb::ObjectPtr<ExtensionManager> createExtensionManager(carb::events::IEventStream* changeEventStream = nullptr);
};

//                                             Extension Manager Hooks                                                //

enum class ExtensionStateChangeType
{
    eBeforeExtensionEnable,
    eAfterExtensionEnable,
    eBeforeExtensionShutdown,
    eAfterExtensionShutdown,
    eCount,
};

class IExtensionStateChangeHook : public carb::IObject
{
public:
    virtual void onStateChange(const char* extId, ExtensionStateChangeType type) = 0;
};

using IExtensionStateChangeHookPtr = carb::ObjectPtr<IExtensionStateChangeHook>;

using Order = int32_t;

static constexpr Order kDefaultOrder = 0;

class IHookHolder : public carb::IObject
{
};

using IHookHolderPtr = carb::ObjectPtr<IHookHolder>;

class IExtensionManagerHooks
{
public:
    IHookHolderPtr createExtensionStateChangeHook(IExtensionStateChangeHook* hook,
                                                  ExtensionStateChangeType type,
                                                  const char* extFullName = "",
                                                  const char* extDictPath = "",
                                                  Order order = kDefaultOrder,
                                                  const char* hookName = nullptr);
    virtual IHookHolder* createExtensionStateChangeHookPtr(IExtensionStateChangeHook* hook,
                                                           ExtensionStateChangeType type,
                                                           const char* extFullName = "",
                                                           const char* extDictPath = "",
                                                           Order order = kDefaultOrder,
                                                           const char* hookName = nullptr) = 0;
};

//                                                Inline Functions                                                    //

inline IHookHolderPtr IExtensionManagerHooks::createExtensionStateChangeHook(IExtensionStateChangeHook* hook,
                                                                             ExtensionStateChangeType type,
                                                                             const char* extFullName,
                                                                             const char* extDictPath,
                                                                             Order order,
                                                                             const char* hookName)
{
    return carb::stealObject(
        this->createExtensionStateChangeHookPtr(hook, type, extFullName, extDictPath, order, hookName));
}

inline carb::ObjectPtr<ExtensionManager> IExtensions::createExtensionManager(carb::events::IEventStream* changeEventStream)
{
    return carb::stealObject(this->createExtensionManagerPtr(changeEventStream));
}

} // namespace ext
} // namespace omni