carb/input/IInput.h

File members: carb/input/IInput.h

// Copyright (c) 2018-2024, 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 "../Interface.h"
#include "InputTypes.h"

namespace carb
{
namespace input
{

struct InputProvider;

class ActionMappingSet DOXYGEN_EMPTY_CLASS;

using ActionMappingSetHandle = ActionMappingSet*;

#ifndef DOXYGEN_BUILD
enum class LockType : uint8_t
{
    eRead,
    eUnlockRead,
    eWrite,
    eUnlockWrite,
};
#endif

struct IInput
{
    CARB_PLUGIN_INTERFACE("carb::input::IInput", 1, 2)

    InputProvider*(CARB_ABI* getInputProvider)();

    void(CARB_ABI* startup)();

    void(CARB_ABI* shutdown)();

    const char*(CARB_ABI* getKeyboardName)(Keyboard* keyboard);

    SubscriptionId(CARB_ABI* subscribeToKeyboardEvents)(Keyboard* keyboard, OnKeyboardEventFn fn, void* userData);

    void(CARB_ABI* unsubscribeToKeyboardEvents)(Keyboard* keyboard, SubscriptionId id);

    float(CARB_ABI* getKeyboardValue)(Keyboard* keyboard, KeyboardInput input);

    ButtonFlags(CARB_ABI* getKeyboardButtonFlags)(Keyboard* keyboard, KeyboardInput input);

    const char*(CARB_ABI* getMouseName)(Mouse* mouse);

    float(CARB_ABI* getMouseValue)(Mouse* mouse, MouseInput input);

    ButtonFlags(CARB_ABI* getMouseButtonFlags)(Mouse* mouse, MouseInput input);

    Float2(CARB_ABI* getMouseCoordsNormalized)(Mouse* mouse);

    Float2(CARB_ABI* getMouseCoordsPixel)(Mouse* mouse);

    SubscriptionId(CARB_ABI* subscribeToMouseEvents)(Mouse* mouse, OnMouseEventFn fn, void* userData);

    void(CARB_ABI* unsubscribeToMouseEvents)(Mouse* mouse, SubscriptionId id);

    const char*(CARB_ABI* getGamepadName)(Gamepad* gamepad);

    const char*(CARB_ABI* getGamepadGuid)(Gamepad* gamepad);

    float(CARB_ABI* getGamepadValue)(Gamepad* gamepad, GamepadInput input);

    ButtonFlags(CARB_ABI* getGamepadButtonFlags)(Gamepad* gamepad, GamepadInput input);

    SubscriptionId(CARB_ABI* subscribeToGamepadEvents)(Gamepad* gamepad, OnGamepadEventFn fn, void* userData);

    void(CARB_ABI* unsubscribeToGamepadEvents)(Gamepad* gamepad, SubscriptionId id);

    SubscriptionId(CARB_ABI* subscribeToGamepadConnectionEvents)(OnGamepadConnectionEventFn fn, void* userData);

    void(CARB_ABI* unsubscribeToGamepadConnectionEvents)(SubscriptionId id);

    void(CARB_ABI* distributeBufferedEvents)();

    ActionMappingSetHandle(CARB_ABI* createActionMappingSet)(const char* settingsPath);
    ActionMappingSetHandle(CARB_ABI* getActionMappingSetByPath)(const char* settingsPath);

    void(CARB_ABI* destroyActionMappingSet)(ActionMappingSetHandle actionMappingSet);

    size_t(CARB_ABI* getActionCount)(const ActionMappingSetHandle actionMappingSet);

    const char* const*(CARB_ABI* getActions)(const ActionMappingSetHandle actionMappingSet);

    size_t(CARB_ABI* addActionMapping)(ActionMappingSetHandle actionMappingSet,
                                       const char* actionName,
                                       const ActionMappingDesc& desc);

    void(CARB_ABI* setActionMapping)(ActionMappingSetHandle actionMappingSet,
                                     const char* actionName,
                                     size_t index,
                                     const ActionMappingDesc& desc);

    void(CARB_ABI* removeActionMapping)(ActionMappingSetHandle actionMappingSet, const char* actionName, size_t index);

    void(CARB_ABI* clearActionMappings)(ActionMappingSetHandle actionMappingSet, const char* actionName);

    size_t(CARB_ABI* getActionMappingCount)(const ActionMappingSetHandle actionMappingSet, const char* actionName);

    const ActionMappingDesc*(CARB_ABI* getActionMappings)(const ActionMappingSetHandle actionMappingSet,
                                                          const char* actionName);

    float(CARB_ABI* getActionValue)(const ActionMappingSetHandle actionMappingSet, const char* actionName);

    ButtonFlags(CARB_ABI* getActionButtonFlags)(const ActionMappingSetHandle actionMappingSet, const char* actionName);

    SubscriptionId(CARB_ABI* subscribeToActionEvents)(ActionMappingSetHandle actionMappingSet,
                                                      const char* actionName,
                                                      OnActionEventFn fn,
                                                      void* userData);

    void(CARB_ABI* unsubscribeToActionEvents)(SubscriptionId id);

    void(CARB_ABI* filterBufferedEvents)(InputEventFilterFn fn, void* userData);

    const char*(CARB_ABI* getDeviceName)(InputDevice* device);

    DeviceType(CARB_ABI* getDeviceType)(InputDevice* device);

    SubscriptionId(CARB_ABI* internalSubscribeToInputEvents)(
        InputDevice* device, EventTypeMask events, OnInputEventFn fn, void* userData, SubscriptionOrder order);

    SubscriptionId subscribeToInputEvents(InputDevice* device,
                                          EventTypeMask events,
                                          OnInputEventFn fn,
                                          void* userData,
                                          SubscriptionOrder order = kSubscriptionOrderDefault)
    {
        return internalSubscribeToInputEvents(device, events, fn, userData, order);
    }

    void(CARB_ABI* unsubscribeToInputEvents)(SubscriptionId id);

    KeyboardModifierFlags(CARB_ABI* getModifierFlags)(KeyboardModifierFlags modifierFlags,
                                                      const InputDevice* const* devices,
                                                      size_t nDevices,
                                                      const DeviceType* const deviceTypes,
                                                      size_t nDeviceTypes,
                                                      const MouseInput* mouseButtons,
                                                      size_t numMouseButtons);

    KeyboardModifierFlags(CARB_ABI* getGlobalModifierFlags)(KeyboardModifierFlags modifierFlags,
                                                            const MouseInput* mouseButtons,
                                                            size_t numMouseButtons);

    void(CARB_ABI* internalLock)(ActionMappingSetHandle, LockType type);
};

class ScopedRead
{
public:
    ScopedRead(IInput* iface, const ActionMappingSetHandle set)
        : m_iface(iface), m_set(const_cast<ActionMappingSetHandle>(set))
    {
        m_iface->internalLock(m_set, LockType::eRead);
    }
    ~ScopedRead()
    {
        m_iface->internalLock(m_set, LockType::eUnlockRead);
    }
    ScopedRead(ScopedRead&& other) : m_iface(other.m_iface), m_set(std::exchange(other.m_set, nullptr))
    {
    }
    ScopedRead& operator=(ScopedRead&& other)
    {
        std::swap(m_iface, other.m_iface);
        std::swap(m_set, other.m_set);
        return *this;
    }

    CARB_PREVENT_COPY(ScopedRead);

private:
    IInput* m_iface;
    ActionMappingSetHandle m_set;
};

class ScopedWrite
{
public:
    ScopedWrite(IInput* iface, ActionMappingSetHandle set) : m_iface(iface), m_set(set)
    {
        m_iface->internalLock(m_set, LockType::eRead);
    }
    ~ScopedWrite()
    {
        m_iface->internalLock(m_set, LockType::eUnlockRead);
    }
    ScopedWrite(ScopedWrite&& other) : m_iface(other.m_iface), m_set(std::exchange(other.m_set, nullptr))
    {
    }
    ScopedWrite& operator=(ScopedWrite&& other)
    {
        std::swap(m_iface, other.m_iface);
        std::swap(m_set, other.m_set);
        return *this;
    }

    CARB_PREVENT_COPY(ScopedWrite);

private:
    IInput* m_iface;
    ActionMappingSetHandle m_set;
};

} // namespace input
} // namespace carb