/*
 * Copyright 2025 Rive
 */

#pragma once

#include "rive/object_stream.hpp"
#include "rive/input/focusable.hpp"
#include "rive/refcnt.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/pointer_button.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#include "rive/animation/semantic_listener_group.hpp"
#include "rive/semantic/semantic_snapshot.hpp"

#include <condition_variable>
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <unordered_map>
#include "file_asset_loader.hpp"

// Macros for defining and working with command buffer handles.
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(void*) == 8, "expected a 64-bit environment");
// Define handles as pointers to forward-declared types for type safety.
#define RIVE_DEFINE_HANDLE(NAME) using NAME = struct NAME##_HandlePlaceholder*;
#define RIVE_NULL_HANDLE nullptr
#elif INTPTR_MAX == INT32_MAX
static_assert(sizeof(void*) == 4, "expected a 32-bit environment");
#define RIVE_DEFINE_HANDLE(NAME) using NAME = uint64_t;
#define RIVE_NULL_HANDLE 0
#else
#error "environment not 32 or 64-bit."
#endif

namespace rive
{
enum class Direction : uint8_t;
class Factory;
class File;
class ArtboardInstance;
class StateMachineInstance;
class CommandServer;
class ScriptingContext;

RIVE_DEFINE_HANDLE(FontHandle);
RIVE_DEFINE_HANDLE(FileHandle);
RIVE_DEFINE_HANDLE(ArtboardHandle);
RIVE_DEFINE_HANDLE(AudioSourceHandle);
RIVE_DEFINE_HANDLE(RenderImageHandle);
RIVE_DEFINE_HANDLE(BlobAssetHandle);
RIVE_DEFINE_HANDLE(StateMachineHandle);
RIVE_DEFINE_HANDLE(ViewModelInstanceHandle);
RIVE_DEFINE_HANDLE(DrawKey);

// Function poimter that gets called back from the server thread.
using CommandServerCallback = std::function<void(CommandServer*)>;
using CommandServerDrawCallback = std::function<void(DrawKey, CommandServer*)>;

// Creates the ScriptingContext used for a loaded file's Lua VM. Invoked on the
// command server thread with the server's Factory so the context is built with
// the correct factory on the correct thread. Return nullptr (or leave the
// factory empty) to fall back to the default CPPRuntimeScriptingContext. Used
// by hosts (e.g. Unreal) to redirect Lua console/error output to their own
// logging.
using ScriptingContextFactory =
    std::function<std::unique_ptr<ScriptingContext>(Factory*)>;

struct ViewModelEnum
{
    std::string name;
    std::vector<std::string> enumerants;
};

// Client-side recorder for commands that will be executed by a CommandServer.
// Synchronized operations require an active CommandServer processing this
// queue on another thread and must not be called after disconnect(); otherwise,
// they block indefinitely.
class CommandQueue : public RefCnt<CommandQueue>
{
public:
    template <typename ListenerType, typename HandleType> class ListenerBase
    {
    public:
        friend class CommandQueue;

        ListenerBase(const ListenerBase&) = delete;
        ListenerBase& operator=(const ListenerBase&) = delete;
        ListenerBase(ListenerBase&& other) :
            m_owningQueue(std::move(other.m_owningQueue)),
            m_handle(std::move(other.m_handle))
        {
            if (m_owningQueue)
            {
                m_owningQueue->unregisterListener(
                    m_handle,
                    static_cast<ListenerType*>(&other));
                m_owningQueue->registerListener(
                    m_handle,
                    static_cast<ListenerType*>(this));
            }
        }
        ~ListenerBase()
        {
            if (m_owningQueue)
                m_owningQueue->unregisterListener(
                    m_handle,
                    static_cast<ListenerType*>(this));
        }
        ListenerBase() : m_handle(RIVE_NULL_HANDLE) {}

    private:
        rcp<CommandQueue> m_owningQueue;
        HandleType m_handle;
    };

    class FileListener
        : public CommandQueue::ListenerBase<FileListener, FileHandle>
    {
    public:
        virtual void onFileError(const FileHandle,
                                 uint64_t requestId,
                                 std::string error)
        {}

        virtual void onFileDeleted(const FileHandle, uint64_t requestId) {}

        virtual void onFileLoaded(const FileHandle, uint64_t requestId) {}

        /**
         * Called after an artboard instance is created.
         *
         * @param fileHandle The file from which the artboard was instantiated.
         * @param requestId The request that created the artboard handle.
         * @param artboardHandle The confirmed artboard handle.
         */
        virtual void onArtboardInstantiated(const FileHandle fileHandle,
                                            uint64_t requestId,
                                            ArtboardHandle artboardHandle)
        {}

        /**
         * Called after a view model instance or instance reference is created.
         *
         * @param fileHandle The source file for a newly instantiated view
         * model, or RIVE_NULL_HANDLE when the new handle references an existing
         * nested or list-item instance. Confirmations with RIVE_NULL_HANDLE are
         * delivered only to a FileListener registered for RIVE_NULL_HANDLE.
         * @param requestId The request that created the instance handle.
         * @param viewModelInstanceHandle The confirmed instance handle.
         */
        virtual void onViewModelInstanceInstantiated(
            const FileHandle fileHandle,
            uint64_t requestId,
            ViewModelInstanceHandle viewModelInstanceHandle)
        {}

        virtual void onArtboardsListed(const FileHandle,
                                       uint64_t requestId,
                                       std::vector<std::string> artboardNames)
        {}

        virtual void onViewModelsListed(const FileHandle,
                                        uint64_t requestId,
                                        std::vector<std::string> viewModelNames)
        {}

        virtual void onGlobalViewModelNamesListed(
            const FileHandle,
            uint64_t requestId,
            std::vector<std::string> globalViewModelNames)
        {}

        virtual void onViewModelInstanceNamesListed(
            const FileHandle,
            uint64_t requestId,
            std::string viewModelName,
            std::vector<std::string> instanceNames)
        {}

        struct ViewModelPropertyData
        {
            DataType type = DataType::none;
            std::string name = "";
            std::string metaData = "";
        };

        virtual void onViewModelPropertiesListed(
            const FileHandle,
            uint64_t requestId,
            std::string viewModelName,
            std::vector<ViewModelPropertyData> properties)
        {}

        virtual void onViewModelEnumsListed(const FileHandle,
                                            uint64_t requestId,
                                            std::vector<ViewModelEnum> enums)
        {}

        struct FileAssetData
        {
            std::string name;
            std::string uniqueName;
            uint32_t assetID = 0;
            std::string cdnUUID;
            std::string cdnBaseURL;
            std::string fileExtension;
            uint16_t type = 0;
        };

        virtual void onFileAssetsListed(const FileHandle,
                                        uint64_t requestId,
                                        std::vector<FileAssetData> assets)
        {}
    };

    class RenderImageListener
        : public CommandQueue::ListenerBase<RenderImageListener,
                                            RenderImageHandle>
    {
    public:
        virtual void onRenderImageDecoded(const RenderImageHandle,
                                          uint64_t requestId)
        {}

        virtual void onRenderImageError(const RenderImageHandle,
                                        uint64_t requestId,
                                        std::string error)
        {}

        virtual void onRenderImageDeleted(const RenderImageHandle,
                                          uint64_t requestId)
        {}
    };

    class AudioSourceListener
        : public CommandQueue::ListenerBase<AudioSourceListener,
                                            AudioSourceHandle>
    {
    public:
        virtual void onAudioSourceDecoded(const AudioSourceHandle,
                                          uint64_t requestId)
        {}

        virtual void onAudioSourceError(const AudioSourceHandle,
                                        uint64_t requestId,
                                        std::string error)
        {}

        virtual void onAudioSourceDeleted(const AudioSourceHandle,
                                          uint64_t requestId)
        {}
    };

    class FontListener
        : public CommandQueue::ListenerBase<FontListener, FontHandle>
    {
    public:
        virtual void onFontDecoded(const FontHandle, uint64_t requestId) {}

        virtual void onFontError(const FontHandle,
                                 uint64_t requestId,
                                 std::string error)
        {}

        virtual void onFontDeleted(const FontHandle, uint64_t requestId) {}
    };

    class BlobAssetListener
        : public CommandQueue::ListenerBase<BlobAssetListener, BlobAssetHandle>
    {
    public:
        virtual void onBlobAssetDecoded(const BlobAssetHandle,
                                        uint64_t requestId)
        {}

        virtual void onBlobAssetError(const BlobAssetHandle,
                                      uint64_t requestId,
                                      std::string error)
        {}

        virtual void onBlobAssetDeleted(const BlobAssetHandle,
                                        uint64_t requestId)
        {}
    };

    class ArtboardListener
        : public CommandQueue::ListenerBase<ArtboardListener, ArtboardHandle>
    {
    public:
        virtual void onArtboardError(const ArtboardHandle,
                                     uint64_t requestId,
                                     std::string error)
        {}

        virtual void onDefaultViewModelInfoReceived(const ArtboardHandle,
                                                    uint64_t requestId,
                                                    std::string viewModelName,
                                                    std::string instanceName)
        {}

        virtual void onArtboardDeleted(const ArtboardHandle, uint64_t requestId)
        {}

        /**
         * Called after a state machine instance is created.
         *
         * @param artboardHandle The artboard from which the state machine was
         * instantiated.
         * @param requestId The request that created the state machine handle.
         * @param stateMachineHandle The confirmed state machine handle.
         */
        virtual void onStateMachineInstantiated(
            const ArtboardHandle artboardHandle,
            uint64_t requestId,
            StateMachineHandle stateMachineHandle)
        {}

        virtual void onStateMachinesListed(
            const ArtboardHandle,
            uint64_t requestId,
            std::vector<std::string> stateMachineNames)
        {}

        virtual void onArtboardVolumeReceived(const ArtboardHandle,
                                              uint64_t requestId,
                                              float volume)
        {}

        virtual void onArtboardSizeReceived(const ArtboardHandle,
                                            uint64_t requestId,
                                            float width,
                                            float height)
        {}
    };

    struct ViewModelInstanceData
    {
        // The path and type of this property
        PropertyData metaData;

        // The specific value of this property, you must use the correct union
        // member base on type in metaData, both enumType and string use
        // stringValue

        // std::string is non trival, so it stays outside the union
        std::string stringValue;
        union
        {
            bool boolValue;
            float numberValue;
            ColorInt colorValue;
        };
    };

    // Mirrors StateMachineInstance::FocusState for command queue responses.
    struct FocusState
    {
        bool hasFocus = false;
        bool expectsKeyboardInput = false;
    };

    /** Traversal and its resulting state, observed under the same lock. */
    struct FocusTraversalResult
    {
        /** Whether traversal moved focus, including entry into the focus tree.
         */
        bool moved = false;
        /** The focus state immediately after traversal, even when it did not
         * move. */
        FocusState focusState = {};
    };

    class ViewModelInstanceListener
        : public CommandQueue::ListenerBase<ViewModelInstanceListener,
                                            ViewModelInstanceHandle>
    {
    public:
        virtual void onViewModelInstanceError(const ViewModelInstanceHandle,
                                              uint64_t requestId,
                                              std::string error)
        {}

        virtual void onViewModelInstanceViewModelNameReceived(
            const ViewModelInstanceHandle,
            uint64_t requestId,
            std::string viewModelName)
        {}
        virtual void onViewModelInstanceNameReceived(
            const ViewModelInstanceHandle handle,
            uint64_t requestId,
            std::string instanceName)
        {}

        virtual void onViewModelDeleted(const ViewModelInstanceHandle,
                                        uint64_t requestId)
        {}

        virtual void onViewModelDataReceived(const ViewModelInstanceHandle,
                                             uint64_t requestId,
                                             ViewModelInstanceData)
        {}

        virtual void onViewModelListSizeReceived(const ViewModelInstanceHandle,
                                                 uint64_t requestId,
                                                 std::string path,
                                                 size_t size)
        {}

        virtual void onViewModelListCleared(const ViewModelInstanceHandle,
                                            uint64_t requestId,
                                            std::string path)
        {}
    };

    class StateMachineListener
        : public CommandQueue::ListenerBase<StateMachineListener,
                                            StateMachineHandle>
    {
    public:
        virtual void onStateMachineError(const StateMachineHandle,
                                         uint64_t requestId,
                                         std::string error)
        {}

        virtual void onStateMachineDeleted(const StateMachineHandle,
                                           uint64_t requestId)
        {}
        // requestId in this case is the specific request that caused the
        // statemachine to settle
        virtual void onStateMachineSettled(const StateMachineHandle,
                                           uint64_t requestId)
        {}

        /**
         * Called after mainViewModelInstance or globalViewModelInstance
         * successfully retrieves a view model instance bound to a state
         * machine. Lookup failures are reported through onStateMachineError.
         *
         * @param stateMachineHandle The state machine from which the view model
         * instance was retrieved.
         * @param requestId The request that retrieved the view model instance.
         * @param viewModelInstanceHandle The confirmed view model instance
         * handle.
         */
        virtual void onViewModelInstanceReceived(
            const StateMachineHandle stateMachineHandle,
            uint64_t requestId,
            ViewModelInstanceHandle viewModelInstanceHandle)
        {}

        /**
         * Reports whether a focused node or its ancestor handled a key event.
         * A handled input need not change text. Invalid handles are reported
         * through onStateMachineError instead.
         *
         * @param stateMachineHandle The state machine that received the input.
         * @param requestId The input command's request identifier.
         * @param handled Whether a recipient claimed the input.
         */
        virtual void onKeyInputHandled(
            const StateMachineHandle stateMachineHandle,
            uint64_t requestId,
            bool handled)
        {}

        /**
         * Reports whether a focused node or its ancestor handled committed
         * text. A handled input need not change text. Invalid handles are
         * reported through onStateMachineError instead.
         *
         * @param stateMachineHandle The state machine that received the input.
         * @param requestId The input command's request identifier.
         * @param handled Whether a recipient claimed the input.
         */
        virtual void onTextInputHandled(
            const StateMachineHandle stateMachineHandle,
            uint64_t requestId,
            bool handled)
        {}

        // Delivered when an incremental semantic diff is available for this
        // state machine. Emitted only when drainSemanticsDiff produces a
        // non-empty diff. Bounds inside the diff are reported in view space
        // using the fit/alignment/scale/view-bounds arguments provided to the
        // drain command.
        virtual void onSemanticsDiffReceived(const StateMachineHandle,
                                             uint64_t requestId,
                                             SemanticsDiff diff)
        {}

        virtual void onHasFocusNodesReceived(const StateMachineHandle,
                                             uint64_t requestId,
                                             bool hasFocusNodes)
        {}

        virtual void onFocusStateReceived(const StateMachineHandle,
                                          uint64_t requestId,
                                          FocusState focusState)
        {}
    };

    class RuntimeMessageListener
    {
    public:
        virtual ~RuntimeMessageListener() = default;

        /**
         * Receives runtime-defined messages posted by the command server.
         *
         * Called on the thread running processMessages(), with the message
         * mutex released. The callback owns the payload and may retain it.
         *
         * @param tag Runtime-owned message type identifier.
         * @param payload Runtime-owned serialized message bytes.
         */
        virtual void onRuntimeMessage(uint32_t tag,
                                      std::vector<uint8_t> payload)
        {}
    };

    CommandQueue();
    ~CommandQueue();

    FileHandle loadFile(
        std::vector<uint8_t> rivBytes,
        FileListener* listener = nullptr,
        uint64_t requestId = 0
#ifdef WITH_RIVE_SCRIPTING
        ,
        ScriptingContextFactory scriptingContextFactory = nullptr
#endif
    );

    void deleteFile(FileHandle, uint64_t requestId = 0);

    /**
     * Registers a global image asset that provides the contents for any file's
     * out-of-band image asset with the same unique name.
     *
     * The change reaches files that are already open as well as files loaded
     * afterward. Registering a name that is already registered replaces its
     * resource everywhere.
     *
     * Assets with embedded contents and assets claimed by a host-supplied file
     * asset loader are never overridden. Reports an error on the matching
     * asset listener if the handle is invalid.
     *
     * @param name The unique asset name to register.
     * @param handle The decoded image resource to provide.
     * @param requestId The request identifier used for an error callback.
     */
    void addGlobalImageAsset(std::string name,
                             RenderImageHandle handle,
                             uint64_t requestId = 0);
    /**
     * Registers a global font asset that provides the contents for any file's
     * out-of-band font asset with the same unique name.
     *
     * The change reaches files that are already open as well as files loaded
     * afterward. Registering a name that is already registered replaces its
     * resource everywhere.
     *
     * Assets with embedded contents and assets claimed by a host-supplied file
     * asset loader are never overridden. Reports an error on the matching
     * asset listener if the handle is invalid.
     *
     * @param name The unique asset name to register.
     * @param handle The decoded font resource to provide.
     * @param requestId The request identifier used for an error callback.
     */
    void addGlobalFontAsset(std::string name,
                            FontHandle handle,
                            uint64_t requestId = 0);
    /**
     * Registers a global audio asset that provides the contents for any file's
     * out-of-band audio asset with the same unique name.
     *
     * The change reaches files that are already open as well as files loaded
     * afterward. Registering a name that is already registered replaces its
     * resource everywhere.
     *
     * Assets with embedded contents and assets claimed by a host-supplied file
     * asset loader are never overridden. Reports an error on the matching
     * asset listener if the handle is invalid.
     *
     * @param name The unique asset name to register.
     * @param handle The decoded audio resource to provide.
     * @param requestId The request identifier used for an error callback.
     */
    void addGlobalAudioAsset(std::string name,
                             AudioSourceHandle handle,
                             uint64_t requestId = 0);

    /**
     * Unregisters the global image asset with the given unique name, clearing
     * it from every open file it was applied to. Deleting the backing image
     * resource has the same effect for every name that resource was registered
     * under.
     *
     * @param name The unique asset name to unregister.
     * @param requestId The request identifier.
     */
    void removeGlobalImageAsset(std::string name, uint64_t requestId = 0);
    /**
     * Unregisters the global font asset with the given unique name, clearing it
     * from every open file it was applied to. Deleting the backing font
     * resource has the same effect for every name that resource was registered
     * under.
     *
     * @param name The unique asset name to unregister.
     * @param requestId The request identifier.
     */
    void removeGlobalFontAsset(std::string name, uint64_t requestId = 0);
    /**
     * Unregisters the global audio asset with the given unique name, clearing
     * it from every open file it was applied to. Deleting the backing audio
     * resource has the same effect for every name that resource was registered
     * under.
     *
     * @param name The unique asset name to unregister.
     * @param requestId The request identifier.
     */
    void removeGlobalAudioAsset(std::string name, uint64_t requestId = 0);

    ArtboardHandle instantiateArtboardNamed(
        FileHandle,
        std::string name,
        ArtboardListener* listener = nullptr,
        uint64_t requestId = 0);
    ArtboardHandle instantiateDefaultArtboard(
        FileHandle fileHandle,
        ArtboardListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateArtboardNamed(fileHandle, "", listener, requestId);
    }

    void setArtboardSize(ArtboardHandle,
                         float width,
                         float height,
                         float scale = 1,
                         uint64_t requestId = 0);

    void resetArtboardSize(ArtboardHandle, uint64_t requestId = 0);

    void deleteArtboard(ArtboardHandle, uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateBlankViewModelInstance(
        FileHandle fileHandle,
        ArtboardHandle artboardHandle,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateBlankViewModelInstance(
        FileHandle fileHandle,
        std::string viewModelName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateDefaultViewModelInstance(
        FileHandle fileHandle,
        ArtboardHandle artboardHandle,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateViewModelInstanceNamed(fileHandle,
                                                 artboardHandle,
                                                 "",
                                                 listener,
                                                 requestId);
    }

    ViewModelInstanceHandle instantiateDefaultViewModelInstance(
        FileHandle fileHandle,
        std::string viewModelName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateViewModelInstanceNamed(fileHandle,
                                                 viewModelName,
                                                 "",
                                                 listener,
                                                 requestId);
    }

    ViewModelInstanceHandle instantiateViewModelInstanceNamed(
        FileHandle,
        ArtboardHandle,
        std::string viewModelInstanceName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle instantiateViewModelInstanceNamed(
        FileHandle,
        std::string viewModelName,
        std::string viewModelInstanceName,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle referenceNestedViewModelInstance(
        ViewModelInstanceHandle,
        std::string path,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    ViewModelInstanceHandle referenceListViewModelInstance(
        ViewModelInstanceHandle,
        std::string path,
        int index,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    void fireViewModelTrigger(ViewModelInstanceHandle,
                              std::string path,
                              uint64_t requestId = 0);

    void setViewModelInstanceBool(ViewModelInstanceHandle,
                                  std::string path,
                                  bool value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceNumber(ViewModelInstanceHandle,
                                    std::string path,
                                    float value,
                                    uint64_t requestId = 0);
    void setViewModelInstanceColor(ViewModelInstanceHandle,
                                   std::string path,
                                   ColorInt value,
                                   uint64_t requestId = 0);
    void setViewModelInstanceEnum(ViewModelInstanceHandle,
                                  std::string path,
                                  std::string value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceString(ViewModelInstanceHandle,
                                    std::string path,
                                    std::string value,
                                    uint64_t requestId = 0);
    void setViewModelInstanceImage(ViewModelInstanceHandle,
                                   std::string path,
                                   RenderImageHandle value,
                                   uint64_t requestId = 0);
    void setViewModelInstanceFont(ViewModelInstanceHandle,
                                  std::string path,
                                  FontHandle value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceBlob(ViewModelInstanceHandle,
                                  std::string path,
                                  BlobAssetHandle value,
                                  uint64_t requestId = 0);
    void setViewModelInstanceArtboard(ViewModelInstanceHandle,
                                      std::string path,
                                      ArtboardHandle value,
                                      uint64_t requestId = 0);
    void setViewModelInstanceNestedViewModel(ViewModelInstanceHandle,
                                             std::string path,
                                             ViewModelInstanceHandle value,
                                             uint64_t requestId = 0);
    void insertViewModelInstanceListViewModel(ViewModelInstanceHandle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              int index,
                                              uint64_t requestId = 0);

    void appendViewModelInstanceListViewModel(ViewModelInstanceHandle handle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              uint64_t requestId = 0)
    {
        insertViewModelInstanceListViewModel(handle,
                                             std::move(path),
                                             value,
                                             -1,
                                             requestId);
    }

    void removeViewModelInstanceListViewModel(
        ViewModelInstanceHandle,
        std::string path,
        int index,
        ViewModelInstanceHandle value = RIVE_NULL_HANDLE,
        uint64_t requestId = 0);

    void removeViewModelInstanceListViewModel(ViewModelInstanceHandle handle,
                                              std::string path,
                                              ViewModelInstanceHandle value,
                                              uint64_t requestId = 0)
    {
        removeViewModelInstanceListViewModel(handle,
                                             std::move(path),
                                             -1,
                                             value,
                                             requestId);
    }

    void swapViewModelInstanceListValues(ViewModelInstanceHandle handle,
                                         std::string path,
                                         int indexa,
                                         int indexb,
                                         uint64_t requestId = 0);

    void subscribeToViewModelProperty(ViewModelInstanceHandle handle,
                                      std::string path,
                                      DataType type,
                                      uint64_t requestId = 0);

    void unsubscribeToViewModelProperty(ViewModelInstanceHandle handle,
                                        std::string path,
                                        DataType type,
                                        uint64_t requestId = 0);

    void deleteViewModelInstance(ViewModelInstanceHandle,
                                 uint64_t requestId = 0);

    StateMachineHandle instantiateStateMachineNamed(
        ArtboardHandle,
        std::string name,
        StateMachineListener* listener = nullptr,
        uint64_t requestId = 0);
    StateMachineHandle instantiateDefaultStateMachine(
        ArtboardHandle artboardHandle,
        StateMachineListener* listener = nullptr,
        uint64_t requestId = 0)
    {
        return instantiateStateMachineNamed(artboardHandle,
                                            "",
                                            listener,
                                            requestId);
    }

    void bindViewModelInstance(StateMachineHandle,
                               ViewModelInstanceHandle,
                               uint64_t requestId = 0);

    // Sets the main (non-global) view model instance without rebinding. Call
    // bind() to apply.
    void setViewModelInstance(StateMachineHandle,
                              ViewModelInstanceHandle,
                              uint64_t requestId = 0);

    /**
     * Returns a handle to the main view model instance currently bound to the
     * state machine. This lookup never creates an instance.
     *
     * A successful lookup is reported through
     * StateMachineListener::onViewModelInstanceReceived. If no main instance
     * is bound, or if the state machine handle is invalid, the lookup reports
     * through StateMachineListener::onStateMachineError and the returned handle
     * maps to nothing.
     *
     * The optional ViewModelInstanceListener is associated with the returned
     * handle for subsequent view model instance operations. It is not notified
     * of lookup success or failure.
     *
     * @param stateMachineHandle The state machine whose main instance should
     * be retrieved.
     * @param listener The listener to associate with the returned view model
     * instance handle.
     * @param requestId The identifier reported with the asynchronous result.
     */
    ViewModelInstanceHandle mainViewModelInstance(
        StateMachineHandle stateMachineHandle,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    /**
     * Removes the main (non-global) view model instance from a state machine
     * without rebinding. Call bind() to create and apply its default main
     * instance.
     *
     * @param stateMachineHandle The state machine whose main instance should
     * be cleared.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void clearViewModelInstance(StateMachineHandle stateMachineHandle,
                                uint64_t requestId = 0);

    // Sets/replaces the global view model instance bound under the given global
    // view model name without rebinding. Call bind() to apply. Reports a state
    // machine error if the name does not match a global view model.
    void setGlobalViewModelInstance(StateMachineHandle,
                                    std::string name,
                                    ViewModelInstanceHandle,
                                    uint64_t requestId = 0);

    /**
     * Removes the instance occupying a named global slot without rebinding,
     * preserving the main instance and every other global slot. Call bind() to
     * create and apply that slot's default instance. Reports a state machine
     * error if name does not identify a global view model.
     *
     * @param stateMachineHandle The state machine whose global slot should be
     * cleared.
     * @param name The global view model slot to clear.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void clearGlobalViewModelInstance(StateMachineHandle stateMachineHandle,
                                      std::string name,
                                      uint64_t requestId = 0);

    /**
     * Returns a handle to the global view model instance currently bound under
     * the given name. This lookup never creates an instance.
     *
     * A successful lookup is reported through
     * StateMachineListener::onViewModelInstanceReceived. If no instance is
     * bound under the name, or if the state machine handle is invalid, the
     * lookup reports through StateMachineListener::onStateMachineError and the
     * returned handle maps to nothing.
     *
     * The optional ViewModelInstanceListener is associated with the returned
     * handle for subsequent view model instance operations. It is not notified
     * of lookup success or failure.
     *
     * @param stateMachineHandle The state machine whose global instance should
     * be retrieved.
     * @param name The global view model name to look up.
     * @param listener The listener to associate with the returned view model
     * instance handle.
     * @param requestId The identifier reported with the asynchronous result.
     */
    ViewModelInstanceHandle globalViewModelInstance(
        StateMachineHandle stateMachineHandle,
        std::string name,
        ViewModelInstanceListener* listener = nullptr,
        uint64_t requestId = 0);

    /**
     * Applies the state machine's current data context to its artboard and
     * state machine data binds in a single pass. Any missing main or global
     * view model instances are created from their defaults before binding.
     * Reports a state machine error asynchronously if the handle is invalid.
     *
     * @param stateMachineHandle The state machine whose data context should be
     * applied.
     * @param requestId The identifier reported with any asynchronous error.
     */
    void bind(StateMachineHandle stateMachineHandle, uint64_t requestId = 0);

    void advanceStateMachine(StateMachineHandle,
                             float timeToAdvance,
                             uint64_t requestId = 0);

    // Enable the semantic subsystem on the given state machine. Must be
    // called before diffs are delivered. Safe to call multiple times.
    void enableSemantics(StateMachineHandle, uint64_t requestId = 0);

    // Drain the current semantic diff for the given state machine.
    // The response is delivered via
    // StateMachineListener::onSemanticsDiffReceived when the diff is non-empty.
    // Output bounds are mapped to view space using the provided fit/alignment/
    // scale/view-bounds parameters.
    void drainSemanticsDiff(StateMachineHandle,
                            Fit fit,
                            Alignment alignment,
                            float scaleFactor,
                            Vec2D viewBounds,
                            uint64_t requestId = 0);

    // Pointer events
    struct PointerEvent
    {
        Fit fit = Fit::none; // the fit the artboard is drawn with
        Alignment alignment; // the alignment the artboard is drawn with
        Vec2D screenBounds;  // the bounds of coordinate system of the cursor
        Vec2D position;      // the cursor position
        float scaleFactor = 1.0f; // scale factor for things like retina display
        int pointerId = 0;        // stable pointer identifier for multitouch
        PointerButton button = PointerButton::primary; // mouse button for
                                                       // down/up events
    };

    // All pointer events will automatically convert between artboard and screen
    // space for you based on the values passed in the PointerEvent struct.

    void pointerMove(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerDown(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerUp(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
    void pointerExit(StateMachineHandle, PointerEvent, uint64_t requestId = 0);

    /**
     * Enqueues a key event for the state machine's focused node and ancestors.
     * Reports consumption asynchronously through
     * StateMachineListener::onKeyInputHandled, or an invalid handle through
     * StateMachineListener::onStateMachineError. Printable text must be sent
     * separately with textInput; a key event does not insert its character.
     *
     * @param stateMachineHandle The state machine receiving the event.
     * @param key The Rive key code to dispatch.
     * @param modifiers The active modifier flags.
     * @param isPressed Whether the key is pressed rather than released.
     * @param isRepeat Whether this is a repeated key press.
     * @param requestId Identifier returned with the result or error.
     */
    void keyInput(StateMachineHandle stateMachineHandle,
                  Key key,
                  KeyModifiers modifiers,
                  bool isPressed,
                  bool isRepeat,
                  uint64_t requestId = 0);

    /**
     * Enqueues committed UTF-8 text for the focused node and its ancestors.
     * A focused TextInput inserts it at the caret, replacing any selection.
     * Reports consumption asynchronously through
     * StateMachineListener::onTextInputHandled, or an invalid handle through
     * StateMachineListener::onStateMachineError. This does not set an IME
     * composing range or replace the field's entire value.
     *
     * @param stateMachineHandle The state machine receiving the text.
     * @param text The committed text, owned by the queue until dispatch.
     * @param requestId Identifier returned with the result or error.
     */
    void textInput(StateMachineHandle stateMachineHandle,
                   std::string text,
                   uint64_t requestId = 0);

    void deleteStateMachine(StateMachineHandle, uint64_t requestId = 0);

    // Fire a semantic action (tap / increase / decrease) on the given node.
    // Fire-and-forget; reports a stateMachineError if the handle is unknown or
    // semantics isn't enabled. An unknown node id is a silent no-op.
    void fireSemanticAction(StateMachineHandle,
                            uint32_t semanticNodeId,
                            SemanticActionType actionType,
                            uint64_t requestId = 0);

    // Request focus on the given semantic node. Fire-and-forget; reports a
    // stateMachineError if the handle is unknown or semantics isn't enabled.
    // An unknown or non-focusable node id is a silent no-op.
    void requestSemanticFocus(StateMachineHandle,
                              uint32_t semanticNodeId,
                              uint64_t requestId = 0);

    // Clear all semantic focus. Called when the screen reader moves
    // focus entirely away from the hosting view.
    void clearSemanticFocus(StateMachineHandle, uint64_t requestId = 0);

    RenderImageHandle decodeImage(std::vector<uint8_t> imageEncodedBytes,
                                  RenderImageListener* listener = nullptr,
                                  uint64_t requestId = 0);
    // This is needed for unreal rhi because all images come pre-decoded and
    // uploaded to gpu.
    RenderImageHandle addExternalImage(rcp<RenderImage> externalImage,
                                       RenderImageListener* listener = nullptr,
                                       uint64_t requestId = 0);

    void deleteImage(RenderImageHandle, uint64_t requestId = 0);

    AudioSourceHandle decodeAudio(std::vector<uint8_t> imageEncodedBytes,
                                  AudioSourceListener* listener = nullptr,
                                  uint64_t requestId = 0);

    AudioSourceHandle addExternalAudio(rcp<AudioSource> externalAudio,
                                       AudioSourceListener* listener = nullptr,
                                       uint64_t requestId = 0);

    void deleteAudio(AudioSourceHandle, uint64_t requestId = 0);

    FontHandle decodeFont(std::vector<uint8_t> imageEncodedBytes,
                          FontListener* listener = nullptr,
                          uint64_t requestId = 0);

    FontHandle addExternalFont(rcp<Font> externalFont,
                               FontListener* listener = nullptr,
                               uint64_t requestId = 0);

    void deleteFont(FontHandle, uint64_t requestId = 0);

    BlobAssetHandle decodeBlob(std::vector<uint8_t> blobBytes,
                               BlobAssetListener* listener = nullptr,
                               uint64_t requestId = 0);

    BlobAssetHandle addExternalBlob(rcp<BlobAsset> externalBlob,
                                    BlobAssetListener* listener = nullptr,
                                    uint64_t requestId = 0);

    void deleteBlob(BlobAssetHandle, uint64_t requestId = 0);

    // Create unique draw key for draw.
    DrawKey createDrawKey();

    /**
     * Executes a one-time callback directly on the command server.
     *
     * This is an escape hatch for tests and runtime-specific operations that
     * cannot be represented by the shared command and message protocol. Do not
     * use it to implement capabilities common to multiple runtimes; add a
     * canonical command, message, and listener callback instead.
     *
     * @param callback The callback to execute on the command server.
     */
    void runOnce(CommandServerCallback);

    // Run draw function for given draw key, only the latest function passed
    // will be run per pollCommands.
    void draw(DrawKey, CommandServerDrawCallback);

    // Cancel a pending draw for the given key if it has already been admitted
    // to the current coalesced draw batch.
    void cancelDraw(DrawKey);

#ifdef TESTING
    // Sends a commandLoopBreak command to the server. This will cause the
    // processCommands to return even if there are more commands to consume.
    // This does not shutdown the server, it only causes processCommands to
    // return. To continue processing commands, another call to processCommands
    // is required.
    void testing_commandLoopBreak();
    FileListener* testing_getFileListener(FileHandle);
    ArtboardListener* testing_getArtboardListener(ArtboardHandle);
    StateMachineListener* testing_getStateMachineListener(StateMachineHandle);
#endif

    void disconnect();

    void requestViewModelNames(FileHandle, uint64_t requestId = 0);
    void requestGlobalViewModelNames(FileHandle, uint64_t requestId = 0);
    void requestArtboardNames(FileHandle, uint64_t requestId = 0);
    void requestFileAssets(FileHandle, uint64_t requestId = 0);
    void requestViewModelEnums(FileHandle, uint64_t requestId = 0);
    void requestViewModelPropertyDefinitions(FileHandle,
                                             std::string viewModelName,
                                             uint64_t requestId = 0);

    void requestViewModelInstanceNames(FileHandle,
                                       std::string viewModelName,
                                       uint64_t requestId = 0);

    void requestViewModelInstanceViewModelName(ViewModelInstanceHandle,
                                               uint64_t requestId = 0);

    void requestViewModelInstanceName(ViewModelInstanceHandle handle,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceBool(ViewModelInstanceHandle,
                                      std::string path,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceNumber(ViewModelInstanceHandle,
                                        std::string path,
                                        uint64_t requestId = 0);

    void requestViewModelInstanceColor(ViewModelInstanceHandle,
                                       std::string path,
                                       uint64_t requestId = 0);

    void requestViewModelInstanceEnum(ViewModelInstanceHandle,
                                      std::string path,
                                      uint64_t requestId = 0);

    void requestViewModelInstanceString(ViewModelInstanceHandle,
                                        std::string path,
                                        uint64_t requestId = 0);

    void requestViewModelInstanceListSize(ViewModelInstanceHandle,
                                          std::string path,
                                          uint64_t requestId = 0);

    void requestViewModelInstanceListClear(ViewModelInstanceHandle,
                                           std::string path,
                                           uint64_t requestId = 0);

    void setArtboardVolume(ArtboardHandle,
                           float volume,
                           uint64_t requestId = 0);
    void requestArtboardVolume(ArtboardHandle, uint64_t requestId = 0);

    void requestArtboardSize(ArtboardHandle, uint64_t requestId = 0);
    void requestStateMachineNames(ArtboardHandle, uint64_t requestId = 0);
    void requestDefaultViewModelInfo(ArtboardHandle,
                                     FileHandle,
                                     uint64_t requestId = 0);

    // Consume all messages received from the server.
    void processMessages();

    void setGlobalFileListener(FileListener* listener)
    {
        m_globalFileListener = listener;
    }
    void setGlobalArtboardListener(ArtboardListener* listener)
    {
        m_globalArtboardListener = listener;
    }
    void setGlobalStateMachineListener(StateMachineListener* listener)
    {
        m_globalStateMachineListener = listener;
    }
    void setGlobalViewModelInstanceListener(ViewModelInstanceListener* listener)
    {
        m_globalViewModelListener = listener;
    }
    void setGlobalRenderImageListener(RenderImageListener* listener)
    {
        m_globalImageListener = listener;
    }
    void setGlobalAudioSourceListener(AudioSourceListener* listener)
    {
        m_globalAudioListener = listener;
    }
    void setGlobalFontListener(FontListener* listener)
    {
        m_globalFontListener = listener;
    }
    void setGlobalBlobAssetListener(BlobAssetListener* listener)
    {
        m_globalBlobListener = listener;
    }

    bool focusNextSynchronized(StateMachineHandle);
    bool focusPreviousSynchronized(StateMachineHandle);
    void focusNext(StateMachineHandle, uint64_t requestId = 0);
    void focusPrevious(StateMachineHandle, uint64_t requestId = 0);
    void requestHasFocusNodes(StateMachineHandle, uint64_t requestId = 0);
    void clearFocus(StateMachineHandle, uint64_t requestId = 0);
    void requestFocusState(StateMachineHandle, uint64_t requestId = 0);

    /**
     * Synchronously traverses forward and captures the resulting focus state.
     * A traversal that does not move may still retain focus, such as at a stop
     * boundary. The returned state distinguishes retained focus from exit.
     *
     * @param stateMachineHandle The state machine whose focus tree to traverse.
     * @return Movement and post-traversal state, or a default-initialized
     * result if the state machine does not exist.
     */
    FocusTraversalResult focusNextWithResultSynchronized(
        StateMachineHandle stateMachineHandle);

    /**
     * Synchronously traverses backward and captures the resulting focus state.
     * A traversal that does not move may still retain focus, such as at a stop
     * boundary. The returned state distinguishes retained focus from exit.
     *
     * @param stateMachineHandle The state machine whose focus tree to traverse.
     * @return Movement and post-traversal state, or a default-initialized
     * result if the state machine does not exist.
     */
    FocusTraversalResult focusPreviousWithResultSynchronized(
        StateMachineHandle stateMachineHandle);

    /**
     * Delivers a key synchronously to the focused node and its ancestors.
     *
     * @param stateMachineHandle The state machine receiving the event.
     * @param key The Rive key code to dispatch.
     * @param modifiers The active modifier flags.
     * @param isPressed Whether the key is pressed rather than released.
     * @param isRepeat Whether this is a repeated key press.
     * @return Whether the event was handled. Returns false for a missing
     * state machine or when no focused node or ancestor handles the event.
     */
    bool keyInputSynchronized(StateMachineHandle stateMachineHandle,
                              Key key,
                              KeyModifiers modifiers,
                              bool isPressed,
                              bool isRepeat);

    /**
     * Synchronously attempts spatial focus traversal in the given direction.
     *
     * @param stateMachineHandle The state machine whose focus tree to traverse.
     * @param direction The direction in root artboard space.
     * @return Whether traversal moved focus. Returns false for a missing
     * state machine, missing focus manager, or unsuccessful traversal.
     */
    bool focusInDirectionSynchronized(StateMachineHandle stateMachineHandle,
                                      Direction direction);

    /**
     * Sets the listener for runtime-defined command server messages.
     *
     * Registration is non-owning. The listener must remain alive until it is
     * replaced or cleared and any callback in progress has completed. Calls to
     * this setter must be serialized with processMessages(), typically by
     * using the same thread.
     *
     * The listener registered when a message is processed receives it. Messages
     * processed without a listener are discarded, not retained for a later
     * registration.
     *
     * @param listener Listener to receive runtime messages, or nullptr to clear
     * the listener.
     */
    void setGlobalRuntimeMessageListener(RuntimeMessageListener* listener)
    {
        m_globalRuntimeMessageListener = listener;
    }

private:
    void registerListener(FileHandle handle, FileListener* listener)
    {
        assert(listener);
        assert(m_fileListeners.find(handle) == m_fileListeners.end());
        m_fileListeners.insert({handle, listener});
    }

    void registerListener(RenderImageHandle handle,
                          RenderImageListener* listener)
    {
        assert(listener);
        assert(m_imageListeners.find(handle) == m_imageListeners.end());
        m_imageListeners.insert({handle, listener});
    }

    void registerListener(AudioSourceHandle handle,
                          AudioSourceListener* listener)
    {
        assert(listener);
        assert(m_audioListeners.find(handle) == m_audioListeners.end());
        m_audioListeners.insert({handle, listener});
    }

    void registerListener(FontHandle handle, FontListener* listener)
    {
        assert(listener);
        assert(m_fontListeners.find(handle) == m_fontListeners.end());
        m_fontListeners.insert({handle, listener});
    }

    void registerListener(BlobAssetHandle handle, BlobAssetListener* listener)
    {
        assert(listener);
        assert(m_blobListeners.find(handle) == m_blobListeners.end());
        m_blobListeners.insert({handle, listener});
    }

    void registerListener(ArtboardHandle handle, ArtboardListener* listener)
    {
        assert(listener);
        assert(m_artboardListeners.find(handle) == m_artboardListeners.end());
        m_artboardListeners.insert({handle, listener});
    }

    void registerListener(ViewModelInstanceHandle handle,
                          ViewModelInstanceListener* listener)
    {
        assert(listener);
        assert(m_viewModelListeners.find(handle) == m_viewModelListeners.end());
        m_viewModelListeners.insert({handle, listener});
    }

    void registerListener(StateMachineHandle handle,
                          StateMachineListener* listener)
    {
        assert(listener);
        assert(m_stateMachineListeners.find(handle) ==
               m_stateMachineListeners.end());
        m_stateMachineListeners.insert({handle, listener});
    }

    // On 32-bit architectures, Handles are all uint64_t (not unique types), so
    // it will think we are re-declaring unregisterListener 3 times if we don't
    // add the listener pointer (even though it is not needed).

    void unregisterListener(FileHandle handle, FileListener* listener)
    {
        m_fileListeners.erase(handle);
    }

    void unregisterListener(RenderImageHandle handle,
                            RenderImageListener* listener)
    {
        m_imageListeners.erase(handle);
    }

    void unregisterListener(AudioSourceHandle handle,
                            AudioSourceListener* listener)
    {
        m_audioListeners.erase(handle);
    }

    void unregisterListener(FontHandle handle, FontListener* listener)
    {
        m_fontListeners.erase(handle);
    }

    void unregisterListener(BlobAssetHandle handle, BlobAssetListener* listener)
    {
        m_blobListeners.erase(handle);
    }

    void unregisterListener(ArtboardHandle handle, ArtboardListener* listener)
    {
        m_artboardListeners.erase(handle);
    }

    void unregisterListener(ViewModelInstanceHandle handle,
                            ViewModelInstanceListener* listener)
    {
        m_viewModelListeners.erase(handle);
    }

    void unregisterListener(StateMachineHandle handle,
                            StateMachineListener* listener)
    {
        m_stateMachineListeners.erase(handle);
    }

    enum class Command
    {
        loadFile,
        deleteFile,
        decodeImage,
        externalImage,
        decodeAudio,
        externalAudio,
        decodeFont,
        externalFont,
        decodeBlob,
        externalBlob,
        deleteImage,
        deleteAudio,
        deleteFont,
        deleteBlob,
        addImageFileAsset,
        addAudioFileAsset,
        addFontFileAsset,
        removeImageFileAsset,
        removeAudioFileAsset,
        removeFontFileAsset,
        instantiateArtboard,
        deleteArtboard,
        setArtboardSize,
        resetArtboardSize,
        instantiateViewModel,
        refNestedViewModel,
        refListViewModel,
        instantiateBlankViewModel,
        instantiateViewModelForArtboard,
        instantiateBlankViewModelForArtboard,
        setViewModelInstanceValue,
        addViewModelListValue,
        removeViewModelListValue,
        swapViewModelListValue,
        subscribeViewModelProperty,
        unsubscribeViewModelProperty,
        deleteViewModel,
        instantiateStateMachine,
        deleteStateMachine,
        advanceStateMachine,
        enableSemantics,
        drainSemanticsDiff,
        fireSemanticAction,
        requestSemanticFocus,
        clearSemanticFocus,
        bindViewModelInstance,
        setViewModelInstance,
        getMainViewModelInstance,
        clearViewModelInstance,
        setGlobalViewModelInstance,
        clearGlobalViewModelInstance,
        getGlobalViewModelInstance,
        bind,
        runOnce,
        draw,
        cancelDraw,
        pointerMove,
        pointerDown,
        pointerUp,
        pointerExit,
        keyInput,
        textInput,
        disconnect,
        // This will cause processCommands to return once received. We want to
        // ensure that we do not indefinetly block the calling thread. This is
        // how we achieve that.
        commandLoopBreak,
        // messages
        listViewModelEnums,
        listArtboards,
        listStateMachines,
        getDefaultViewModel,
        listViewModels,
        listGlobalViewModelNames,
        listViewModelInstanceNames,
        listViewModelProperties,
        listViewModelPropertyValue,
        getViewModelInstanceViewModelName,
        getViewModelInstanceName,
        getViewModelListSize,
        clearViewModelList,
        listFileAssets,
        setArtboardVolume,
        getArtboardVolume,
        getArtboardSize,
        focusNext,
        focusPrevious,
        requestHasFocusNodes,
        clearFocus,
        requestFocusState
    };

    enum class Message
    {
        // Same as commandLoopBreak for processMessages
        messageLoopBreak,
        viewModelEnumsListed,
        artboardsListed,
        stateMachinesListed,
        defaultViewModelReceived,
        viewModelInstanceViewModelNameReceived,
        viewModelInstanceNameReceived,
        viewModelsListend,
        globalViewModelNamesListed,
        viewModelInstanceNamesListed,
        viewModelPropertiesListed,
        viewModelPropertyValueReceived,
        viewModelListSizeReceived,
        viewModelListCleared,
        fileLoaded,
        fileDeleted,
        artboardInstantiated,
        stateMachineInstantiated,
        viewModelInstanceInstantiated,
        imageDecoded,
        imageDeleted,
        audioDecoded,
        audioDeleted,
        fontDecoded,
        fontDeleted,
        blobDecoded,
        blobDeleted,
        artboardDeleted,
        viewModelDeleted,
        stateMachineDeleted,
        stateMachineSettled,
        stateMachineViewModelInstanceReceived,
        keyInputHandled,
        textInputHandled,
        semanticsDiffReceived,
        fileAssetsListed,
        artboardSizeReceived,
        fileError,
        artboardError,
        viewModelError,
        imageError,
        audioError,
        fontError,
        blobError,
        stateMachineError,
        artboardVolumeReceived,
        hasFocusNodesReceived,
        focusStateReceived,
        runtimeMessage
    };

    friend class CommandServer;

    uint64_t m_currentFileHandleIdx = 0;
    uint64_t m_currentListHandleIdx = 0;
    uint64_t m_currentFontHandleIdx = 0;
    uint64_t m_currentArtboardHandleIdx = 0;
    uint64_t m_currentViewModelHandleIdx = 0;
    uint64_t m_currentRenderImageHandleIdx = 0;
    uint64_t m_currentBlobAssetHandleIdx = 0;
    uint64_t m_currentAudioSourceHandleIdx = 0;
    uint64_t m_currentStateMachineHandleIdx = 0;
    uint64_t m_currentDrawKeyIdx = 0;

    std::mutex m_commandMutex;
    std::condition_variable m_commandConditionVariable;
    PODStream m_commandStream;
    ObjectStream<rcp<RenderImage>> m_externalImages;
    ObjectStream<rcp<AudioSource>> m_externalAudioSources;
    ObjectStream<rcp<Font>> m_externalFonts;
    ObjectStream<rcp<BlobAsset>> m_externalBlobs;
    ObjectStream<std::vector<uint8_t>> m_byteVectors;
#ifdef WITH_RIVE_SCRIPTING
    ObjectStream<ScriptingContextFactory> m_scriptingContextFactories;
#endif
    ObjectStream<PointerEvent> m_pointerEvents;
    ObjectStream<std::string> m_names;
    ObjectStream<CommandServerCallback> m_callbacks;
    ObjectStream<CommandServerDrawCallback> m_drawCallbacks;

    // Messages streams
    std::mutex m_messageMutex;
    PODStream m_messageStream;
    ObjectStream<std::string> m_messageNames;
    ObjectStream<std::vector<uint8_t>> m_messageByteVectors;
    ObjectStream<SemanticsDiff> m_messageSemanticsDiffs;

    // Listeners
    FileListener* m_globalFileListener = nullptr;
    RenderImageListener* m_globalImageListener = nullptr;
    AudioSourceListener* m_globalAudioListener = nullptr;
    FontListener* m_globalFontListener = nullptr;
    BlobAssetListener* m_globalBlobListener = nullptr;
    ArtboardListener* m_globalArtboardListener = nullptr;
    ViewModelInstanceListener* m_globalViewModelListener = nullptr;
    StateMachineListener* m_globalStateMachineListener = nullptr;
    RuntimeMessageListener* m_globalRuntimeMessageListener = nullptr;

    std::unordered_map<FileHandle, FileListener*> m_fileListeners;
    std::unordered_map<RenderImageHandle, RenderImageListener*>
        m_imageListeners;
    std::unordered_map<AudioSourceHandle, AudioSourceListener*>
        m_audioListeners;
    std::unordered_map<FontHandle, FontListener*> m_fontListeners;
    std::unordered_map<BlobAssetHandle, BlobAssetListener*> m_blobListeners;
    std::unordered_map<ArtboardHandle, ArtboardListener*> m_artboardListeners;
    std::unordered_map<ViewModelInstanceHandle, ViewModelInstanceListener*>
        m_viewModelListeners;
    std::unordered_map<StateMachineHandle, StateMachineListener*>
        m_stateMachineListeners;
};

}; // namespace rive
