/*
 * 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/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
    };

    // 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
