/*
 * Copyright 2025 Rive
 */

#include "rive/command_queue.hpp"
#include "rive/command_server.hpp"

#include <future>

namespace rive
{
namespace
{
// RAII utility to lock a mutex, and call notify_one() on a condition variable
// immediately before unlocking.
class AutoLockAndNotify
{
public:
    AutoLockAndNotify(std::mutex& mutex, std::condition_variable& cv) :
        m_mutex(mutex), m_cv(cv)
    {
        m_mutex.lock();
    }

    ~AutoLockAndNotify()
    {
        m_cv.notify_one();
        m_mutex.unlock();
    }

private:
    std::mutex& m_mutex;
    std::condition_variable& m_cv;
};
}; // namespace

CommandQueue::CommandQueue() {}

CommandQueue::~CommandQueue() {}

FileHandle CommandQueue::loadFile(
    std::vector<uint8_t> rivBytes,
    FileListener* listener,
    uint64_t requestId
#ifdef WITH_RIVE_SCRIPTING
    ,
    ScriptingContextFactory scriptingContextFactory
#endif
)
{
    auto handle = reinterpret_cast<FileHandle>(++m_currentFileHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::loadFile;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_byteVectors << std::move(rivBytes);
#ifdef WITH_RIVE_SCRIPTING
    m_scriptingContextFactories << std::move(scriptingContextFactory);
#endif

    return handle;
}

void CommandQueue::deleteFile(FileHandle fileHandle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteFile;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::addGlobalImageAsset(std::string name,
                                       RenderImageHandle handle,
                                       uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::addImageFileAsset;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::addGlobalFontAsset(std::string name,
                                      FontHandle handle,
                                      uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::addFontFileAsset;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::addGlobalAudioAsset(std::string name,
                                       AudioSourceHandle handle,
                                       uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::addAudioFileAsset;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::removeGlobalImageAsset(std::string name, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::removeImageFileAsset;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::removeGlobalFontAsset(std::string name, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::removeFontFileAsset;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::removeGlobalAudioAsset(std::string name, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::removeAudioFileAsset;
    m_commandStream << requestId;
    m_names << name;
}

ArtboardHandle CommandQueue::instantiateArtboardNamed(
    FileHandle fileHandle,
    std::string name,
    ArtboardListener* listener,
    uint64_t requestId)
{
    auto handle =
        reinterpret_cast<ArtboardHandle>(++m_currentArtboardHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateArtboard;
    m_commandStream << handle;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
    m_names << std::move(name);

    return handle;
}

void CommandQueue::setArtboardSize(ArtboardHandle artboardHandle,
                                   float width,
                                   float height,
                                   float scale,
                                   uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setArtboardSize;
    m_commandStream << artboardHandle;
    m_commandStream << width / scale;
    m_commandStream << height / scale;
    m_commandStream << requestId;
}

void CommandQueue::resetArtboardSize(ArtboardHandle artboardHandle,
                                     uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::resetArtboardSize;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

void CommandQueue::setArtboardVolume(ArtboardHandle artboardHandle,
                                     float volume,
                                     uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setArtboardVolume;
    m_commandStream << artboardHandle;
    m_commandStream << volume;
    m_commandStream << requestId;
}

void CommandQueue::requestArtboardVolume(ArtboardHandle artboardHandle,
                                         uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getArtboardVolume;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

void CommandQueue::deleteArtboard(ArtboardHandle artboardHandle,
                                  uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteArtboard;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

ViewModelInstanceHandle CommandQueue::instantiateBlankViewModelInstance(
    FileHandle fileHandle,
    ArtboardHandle artboardHandle,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateBlankViewModelForArtboard;
    m_commandStream << fileHandle;
    m_commandStream << artboardHandle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;

    return viewHandle;
}

ViewModelInstanceHandle CommandQueue::instantiateBlankViewModelInstance(
    FileHandle fileHandle,
    std::string viewModelName,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateBlankViewModel;
    m_commandStream << fileHandle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << viewModelName;

    return viewHandle;
}

ViewModelInstanceHandle CommandQueue::instantiateViewModelInstanceNamed(
    FileHandle fileHandle,
    ArtboardHandle artboardHandle,
    std::string viewModelInstanceName,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateViewModelForArtboard;
    m_commandStream << fileHandle;
    m_commandStream << artboardHandle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << viewModelInstanceName;

    return viewHandle;
}

ViewModelInstanceHandle CommandQueue::instantiateViewModelInstanceNamed(
    FileHandle fileHandle,
    std::string viewModelName,
    std::string viewModelInstanceName,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateViewModel;
    m_commandStream << fileHandle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << viewModelName;
    m_names << viewModelInstanceName;

    return viewHandle;
}

ViewModelInstanceHandle CommandQueue::referenceNestedViewModelInstance(
    ViewModelInstanceHandle handle,
    std::string path,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::refNestedViewModel;
    m_commandStream << handle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << path;

    return viewHandle;
}

ViewModelInstanceHandle CommandQueue::referenceListViewModelInstance(
    ViewModelInstanceHandle handle,
    std::string path,
    int index,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::refListViewModel;
    m_commandStream << handle;
    m_commandStream << index;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << path;

    return viewHandle;
}

void CommandQueue::fireViewModelTrigger(ViewModelInstanceHandle handle,
                                        std::string path,
                                        uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::trigger;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::setViewModelInstanceBool(ViewModelInstanceHandle handle,
                                            std::string path,
                                            bool value,
                                            uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::boolean;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceNumber(ViewModelInstanceHandle handle,
                                              std::string path,
                                              float value,
                                              uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::number;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceColor(ViewModelInstanceHandle handle,
                                             std::string path,
                                             ColorInt value,
                                             uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::color;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceEnum(ViewModelInstanceHandle handle,
                                            std::string path,
                                            std::string value,
                                            uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::enumType;
    m_commandStream << requestId;
    m_names << path;
    m_names << value;
}

void CommandQueue::setViewModelInstanceString(ViewModelInstanceHandle handle,
                                              std::string path,
                                              std::string value,
                                              uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::string;
    m_commandStream << requestId;
    m_names << path;
    m_names << value;
}

void CommandQueue::setViewModelInstanceImage(ViewModelInstanceHandle handle,
                                             std::string path,
                                             RenderImageHandle value,
                                             uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::assetImage;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceBlob(ViewModelInstanceHandle handle,
                                            std::string path,
                                            BlobAssetHandle value,
                                            uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::assetBlob;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceArtboard(ViewModelInstanceHandle handle,
                                                std::string path,
                                                ArtboardHandle value,
                                                uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::artboard;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::setViewModelInstanceNestedViewModel(
    ViewModelInstanceHandle handle,
    std::string path,
    ViewModelInstanceHandle value,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstanceValue;
    m_commandStream << handle;
    m_commandStream << DataType::viewModel;
    m_commandStream << requestId;
    m_commandStream << value;
    m_names << path;
}

void CommandQueue::insertViewModelInstanceListViewModel(
    ViewModelInstanceHandle handle,
    std::string path,
    ViewModelInstanceHandle value,
    int index,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::addViewModelListValue;
    m_commandStream << handle;
    m_commandStream << value;
    m_commandStream << index;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::removeViewModelInstanceListViewModel(
    ViewModelInstanceHandle handle,
    std::string path,
    int index,
    ViewModelInstanceHandle value,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::removeViewModelListValue;
    m_commandStream << handle;
    m_commandStream << value;
    m_commandStream << index;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::swapViewModelInstanceListValues(
    ViewModelInstanceHandle handle,
    std::string path,
    int indexa,
    int indexb,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::swapViewModelListValue;
    m_commandStream << handle;
    m_commandStream << indexa;
    m_commandStream << indexb;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::subscribeToViewModelProperty(ViewModelInstanceHandle handle,
                                                std::string path,
                                                DataType type,
                                                uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::subscribeViewModelProperty;
    m_commandStream << handle;
    m_commandStream << type;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::unsubscribeToViewModelProperty(
    ViewModelInstanceHandle handle,
    std::string path,
    DataType type,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::unsubscribeViewModelProperty;
    m_commandStream << handle;
    m_commandStream << type;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::deleteViewModelInstance(ViewModelInstanceHandle handle,
                                           uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteViewModel;
    m_commandStream << handle;
    m_commandStream << requestId;
}

StateMachineHandle CommandQueue::instantiateStateMachineNamed(
    ArtboardHandle artboardHandle,
    std::string name,
    StateMachineListener* listener,
    uint64_t requestId)
{
    auto handle =
        reinterpret_cast<StateMachineHandle>(++m_currentStateMachineHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::instantiateStateMachine;
    m_commandStream << handle;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
    m_names << std::move(name);

    return handle;
}

void CommandQueue::pointerMove(StateMachineHandle stateMachineHandle,
                               PointerEvent pointerEvent,
                               uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::pointerMove;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_pointerEvents << std::move(pointerEvent);
}

void CommandQueue::pointerDown(StateMachineHandle stateMachineHandle,
                               PointerEvent pointerEvent,
                               uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::pointerDown;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_pointerEvents << std::move(pointerEvent);
}

void CommandQueue::pointerUp(StateMachineHandle stateMachineHandle,
                             PointerEvent pointerEvent,
                             uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::pointerUp;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_pointerEvents << std::move(pointerEvent);
}

void CommandQueue::pointerExit(StateMachineHandle stateMachineHandle,
                               PointerEvent pointerEvent,
                               uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::pointerExit;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_pointerEvents << std::move(pointerEvent);
}

void CommandQueue::bindViewModelInstance(StateMachineHandle handle,
                                         ViewModelInstanceHandle viewModel,
                                         uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::bindViewModelInstance;
    m_commandStream << handle;
    m_commandStream << viewModel;
    m_commandStream << requestId;
}

void CommandQueue::setViewModelInstance(StateMachineHandle handle,
                                        ViewModelInstanceHandle viewModel,
                                        uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setViewModelInstance;
    m_commandStream << handle;
    m_commandStream << viewModel;
    m_commandStream << requestId;
}

ViewModelInstanceHandle CommandQueue::mainViewModelInstance(
    StateMachineHandle handle,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getMainViewModelInstance;
    m_commandStream << handle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;

    return viewHandle;
}

void CommandQueue::clearViewModelInstance(StateMachineHandle handle,
                                          uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::clearViewModelInstance;
    m_commandStream << handle;
    m_commandStream << requestId;
}

void CommandQueue::setGlobalViewModelInstance(StateMachineHandle handle,
                                              std::string name,
                                              ViewModelInstanceHandle viewModel,
                                              uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::setGlobalViewModelInstance;
    m_commandStream << handle;
    m_commandStream << viewModel;
    m_commandStream << requestId;
    m_names << name;
}

void CommandQueue::clearGlobalViewModelInstance(StateMachineHandle handle,
                                                std::string name,
                                                uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::clearGlobalViewModelInstance;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << name;
}

ViewModelInstanceHandle CommandQueue::globalViewModelInstance(
    StateMachineHandle handle,
    std::string name,
    ViewModelInstanceListener* listener,
    uint64_t requestId)
{
    auto viewHandle = reinterpret_cast<ViewModelInstanceHandle>(
        ++m_currentViewModelHandleIdx);
    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = viewHandle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(viewHandle, listener);
    }
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getGlobalViewModelInstance;
    m_commandStream << handle;
    m_commandStream << viewHandle;
    m_commandStream << requestId;
    m_names << name;

    return viewHandle;
}

void CommandQueue::bind(StateMachineHandle handle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::bind;
    m_commandStream << handle;
    m_commandStream << requestId;
}

void CommandQueue::advanceStateMachine(StateMachineHandle stateMachineHandle,
                                       float timeToAdvance,
                                       uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::advanceStateMachine;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_commandStream << timeToAdvance;
}

void CommandQueue::deleteStateMachine(StateMachineHandle stateMachineHandle,
                                      uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteStateMachine;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::enableSemantics(StateMachineHandle stateMachineHandle,
                                   uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::enableSemantics;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::drainSemanticsDiff(StateMachineHandle stateMachineHandle,
                                      Fit fit,
                                      Alignment alignment,
                                      float scaleFactor,
                                      Vec2D viewBounds,
                                      uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::drainSemanticsDiff;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_commandStream << fit;
    m_commandStream << alignment.x();
    m_commandStream << alignment.y();
    m_commandStream << scaleFactor;
    m_commandStream << viewBounds;
}

void CommandQueue::fireSemanticAction(StateMachineHandle stateMachineHandle,
                                      uint32_t semanticNodeId,
                                      SemanticActionType actionType,
                                      uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::fireSemanticAction;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_commandStream << semanticNodeId;
    m_commandStream << actionType;
}

void CommandQueue::requestSemanticFocus(StateMachineHandle stateMachineHandle,
                                        uint32_t semanticNodeId,
                                        uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::requestSemanticFocus;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
    m_commandStream << semanticNodeId;
}

void CommandQueue::clearSemanticFocus(StateMachineHandle stateMachineHandle,
                                      uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::clearSemanticFocus;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

RenderImageHandle CommandQueue::decodeImage(
    std::vector<uint8_t> imageEncodedBytes,
    RenderImageListener* listener,
    uint64_t requestId)
{
    auto handle =
        reinterpret_cast<RenderImageHandle>(++m_currentRenderImageHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::decodeImage;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_byteVectors << std::move(imageEncodedBytes);
    return handle;
}

RenderImageHandle CommandQueue::addExternalImage(rcp<RenderImage> externalImage,
                                                 RenderImageListener* listener,
                                                 uint64_t requestId)
{
    auto handle =
        reinterpret_cast<RenderImageHandle>(++m_currentRenderImageHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::externalImage;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_externalImages << std::move(externalImage);
    return handle;
}

void CommandQueue::deleteImage(RenderImageHandle handle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteImage;
    m_commandStream << handle;
    m_commandStream << requestId;
}

AudioSourceHandle CommandQueue::decodeAudio(
    std::vector<uint8_t> imageEncodedBytes,
    AudioSourceListener* listener,
    uint64_t requestId)
{
    auto handle =
        reinterpret_cast<AudioSourceHandle>(++m_currentAudioSourceHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::decodeAudio;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_byteVectors << std::move(imageEncodedBytes);
    return handle;
}

AudioSourceHandle CommandQueue::addExternalAudio(rcp<AudioSource> externalAudio,
                                                 AudioSourceListener* listener,
                                                 uint64_t requestId)
{
    auto handle =
        reinterpret_cast<AudioSourceHandle>(++m_currentAudioSourceHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::externalAudio;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_externalAudioSources << std::move(externalAudio);
    return handle;
}

void CommandQueue::deleteAudio(AudioSourceHandle handle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteAudio;
    m_commandStream << handle;
    m_commandStream << requestId;
}

FontHandle CommandQueue::decodeFont(std::vector<uint8_t> imageEncodedBytes,
                                    FontListener* listener,
                                    uint64_t requestId)
{
    auto handle = reinterpret_cast<FontHandle>(++m_currentFontHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::decodeFont;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_byteVectors << std::move(imageEncodedBytes);
    return handle;
}

FontHandle CommandQueue::addExternalFont(rcp<Font> externalFont,
                                         FontListener* listener,
                                         uint64_t requestId)
{
    auto handle = reinterpret_cast<FontHandle>(++m_currentFontHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::externalFont;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_externalFonts << std::move(externalFont);
    return handle;
}

void CommandQueue::deleteFont(FontHandle handle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteFont;
    m_commandStream << handle;
    m_commandStream << requestId;
}

BlobAssetHandle CommandQueue::decodeBlob(std::vector<uint8_t> blobBytes,
                                         BlobAssetListener* listener,
                                         uint64_t requestId)
{
    auto handle =
        reinterpret_cast<BlobAssetHandle>(++m_currentBlobAssetHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::decodeBlob;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_byteVectors << std::move(blobBytes);
    return handle;
}

BlobAssetHandle CommandQueue::addExternalBlob(rcp<BlobAsset> externalBlob,
                                              BlobAssetListener* listener,
                                              uint64_t requestId)
{
    auto handle =
        reinterpret_cast<BlobAssetHandle>(++m_currentBlobAssetHandleIdx);

    if (listener)
    {
        assert(listener->m_handle == RIVE_NULL_HANDLE);
        listener->m_handle = handle;
        listener->m_owningQueue = ref_rcp(this);
        registerListener(handle, listener);
    }

    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::externalBlob;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_externalBlobs << std::move(externalBlob);
    return handle;
}

void CommandQueue::deleteBlob(BlobAssetHandle handle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::deleteBlob;
    m_commandStream << handle;
    m_commandStream << requestId;
}

DrawKey CommandQueue::createDrawKey()
{
    // lock here so we can do this from several threads safely
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    auto key = reinterpret_cast<DrawKey>(++m_currentDrawKeyIdx);
    return key;
}

void CommandQueue::draw(DrawKey drawKey, CommandServerDrawCallback callback)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::draw;
    m_commandStream << drawKey;
    m_drawCallbacks << std::move(callback);
}

void CommandQueue::cancelDraw(DrawKey drawKey)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::cancelDraw;
    m_commandStream << drawKey;
}

#ifdef TESTING
void CommandQueue::testing_commandLoopBreak()
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::commandLoopBreak;
}

CommandQueue::FileListener* CommandQueue::testing_getFileListener(
    FileHandle handle)
{
    auto iter = m_fileListeners.find(handle);
    if (iter != m_fileListeners.end())
        return iter->second;
    return nullptr;
}

CommandQueue::ArtboardListener* CommandQueue::testing_getArtboardListener(
    ArtboardHandle handle)
{
    auto iter = m_artboardListeners.find(handle);
    if (iter != m_artboardListeners.end())
        return iter->second;
    return nullptr;
}

CommandQueue::StateMachineListener* CommandQueue::
    testing_getStateMachineListener(StateMachineHandle handle)
{
    auto iter = m_stateMachineListeners.find(handle);
    if (iter != m_stateMachineListeners.end())
        return iter->second;
    return nullptr;
}

#endif
void CommandQueue::runOnce(CommandServerCallback callback)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::runOnce;
    m_callbacks << std::move(callback);
}

void CommandQueue::disconnect()
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::disconnect;
}

void CommandQueue::requestViewModelNames(FileHandle fileHandle,
                                         uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModels;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestGlobalViewModelNames(FileHandle fileHandle,
                                               uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listGlobalViewModelNames;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestArtboardNames(FileHandle fileHandle,
                                        uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listArtboards;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestFileAssets(FileHandle fileHandle, uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listFileAssets;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestViewModelEnums(FileHandle fileHandle,
                                         uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelEnums;
    m_commandStream << fileHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestViewModelPropertyDefinitions(
    FileHandle handle,
    std::string viewModelName,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelProperties;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << viewModelName;
}

void CommandQueue::requestViewModelInstanceNames(FileHandle handle,
                                                 std::string viewModelName,
                                                 uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelInstanceNames;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << viewModelName;
}

void CommandQueue::requestViewModelInstanceViewModelName(
    ViewModelInstanceHandle viewModelInstanceHandle,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getViewModelInstanceViewModelName;
    m_commandStream << viewModelInstanceHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestViewModelInstanceName(
    ViewModelInstanceHandle viewModelInstanceHandle,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getViewModelInstanceName;
    m_commandStream << viewModelInstanceHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestViewModelInstanceBool(ViewModelInstanceHandle handle,
                                                std::string path,
                                                uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelPropertyValue;
    m_commandStream << DataType::boolean;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceNumber(
    ViewModelInstanceHandle handle,
    std::string path,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelPropertyValue;
    m_commandStream << DataType::number;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceColor(ViewModelInstanceHandle handle,
                                                 std::string path,
                                                 uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelPropertyValue;
    m_commandStream << DataType::color;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceEnum(ViewModelInstanceHandle handle,
                                                std::string path,
                                                uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelPropertyValue;
    m_commandStream << DataType::enumType;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceString(
    ViewModelInstanceHandle handle,
    std::string path,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listViewModelPropertyValue;
    m_commandStream << DataType::string;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceListSize(
    ViewModelInstanceHandle handle,
    std::string path,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getViewModelListSize;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestViewModelInstanceListClear(
    ViewModelInstanceHandle handle,
    std::string path,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::clearViewModelList;
    m_commandStream << handle;
    m_commandStream << requestId;
    m_names << path;
}

void CommandQueue::requestArtboardSize(ArtboardHandle artboardHandle,
                                       uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getArtboardSize;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestStateMachineNames(ArtboardHandle artboardHandle,
                                            uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::listStateMachines;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestDefaultViewModelInfo(ArtboardHandle artboardHandle,
                                               FileHandle fileHandle,
                                               uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getDefaultViewModel;
    m_commandStream << fileHandle;
    m_commandStream << artboardHandle;
    m_commandStream << requestId;
}

void CommandQueue::processMessages()
{
    std::unique_lock<std::mutex> lock(m_messageMutex);

    if (m_messageStream.empty())
        return;

    // Mark where we will end processing messages. This way if new messages come
    // in while we're processing the existing ones, we won't loop forever.
    m_messageStream << Message::messageLoopBreak;

    do
    {
        Message message;
        m_messageStream >> message;

        switch (message)
        {
            case Message::messageLoopBreak:
                lock.unlock();
                return;
            case Message::viewModelEnumsListed:
            {
                size_t numEnums;
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numEnums;
                std::vector<ViewModelEnum> enums(numEnums);
                for (auto& enumData : enums)
                {
                    size_t numEnumDataValue;
                    m_messageStream >> numEnumDataValue;
                    m_messageNames >> enumData.name;
                    enumData.enumerants.resize(numEnumDataValue);
                    for (auto& enumDataValue : enumData.enumerants)
                    {
                        m_messageNames >> enumDataValue;
                    }
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onViewModelEnumsListed(
                        handle,
                        requestId,
                        std::move(enums));
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onViewModelEnumsListed(itr->first,
                                                        requestId,
                                                        std::move(enums));
                }
                break;
            }
            case Message::artboardsListed:
            {
                size_t numArtboards;
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numArtboards;
                std::vector<std::string> artboardNames(numArtboards);
                for (auto& name : artboardNames)
                {
                    m_messageNames >> name;
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onArtboardsListed(handle,
                                                            requestId,
                                                            artboardNames);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onArtboardsListed(itr->first,
                                                   requestId,
                                                   std::move(artboardNames));
                }
                break;
            }
            case Message::fileAssetsListed:
            {
                size_t numAssets;
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numAssets;
                std::vector<FileListener::FileAssetData> assets(numAssets);
                for (auto& asset : assets)
                {
                    m_messageStream >> asset.assetID;
                    m_messageStream >> asset.type;
                    m_messageNames >> asset.name;
                    m_messageNames >> asset.uniqueName;
                    m_messageNames >> asset.cdnUUID;
                    m_messageNames >> asset.cdnBaseURL;
                    m_messageNames >> asset.fileExtension;
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onFileAssetsListed(handle,
                                                             requestId,
                                                             assets);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onFileAssetsListed(itr->first,
                                                    requestId,
                                                    std::move(assets));
                }
                break;
            }
            case Message::stateMachinesListed:
            {
                size_t numStateMachines;
                ArtboardHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numStateMachines;
                std::vector<std::string> stateMachineNames(numStateMachines);
                for (auto& name : stateMachineNames)
                {
                    m_messageNames >> name;
                }
                lock.unlock();

                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onStateMachinesListed(
                        handle,
                        requestId,
                        stateMachineNames);
                }

                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onStateMachinesListed(
                        itr->first,
                        requestId,
                        std::move(stateMachineNames));
                }

                break;
            }
            case Message::defaultViewModelReceived:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                std::string defaultViewModel;
                std::string defaultViewModelInstance;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> defaultViewModel;
                m_messageNames >> defaultViewModelInstance;
                lock.unlock();

                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onDefaultViewModelInfoReceived(
                        handle,
                        requestId,
                        defaultViewModel,
                        defaultViewModelInstance);
                }

                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onDefaultViewModelInfoReceived(
                        itr->first,
                        requestId,
                        std::move(defaultViewModel),
                        std::move(defaultViewModelInstance));
                }

                break;
            }
            case Message::artboardVolumeReceived:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                float volume;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> volume;
                lock.unlock();

                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onArtboardVolumeReceived(
                        handle,
                        requestId,
                        volume);
                }

                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onArtboardVolumeReceived(itr->first,
                                                          requestId,
                                                          volume);
                }

                break;
            }
            case Message::viewModelInstanceViewModelNameReceived:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                std::string viewModelName;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> viewModelName;

                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener
                        ->onViewModelInstanceViewModelNameReceived(
                            handle,
                            requestId,
                            viewModelName);
                }
                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelInstanceViewModelNameReceived(
                        handle,
                        requestId,
                        viewModelName);
                }
                break;
            }
            case Message::viewModelInstanceNameReceived:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                std::string instanceName;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> instanceName;

                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelInstanceNameReceived(
                        handle,
                        requestId,
                        instanceName);
                }
                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelInstanceNameReceived(
                        handle,
                        requestId,
                        std::move(instanceName));
                }
                break;
            }
            case Message::viewModelsListend:
            {
                size_t numViewModels;
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numViewModels;
                std::vector<std::string> viewModelNames(numViewModels);
                for (auto& name : viewModelNames)
                {
                    m_messageNames >> name;
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onViewModelsListed(handle,
                                                             requestId,
                                                             viewModelNames);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onViewModelsListed(itr->first,
                                                    requestId,
                                                    std::move(viewModelNames));
                }

                break;
            }
            case Message::globalViewModelNamesListed:
            {
                size_t numViewModels;
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numViewModels;
                std::vector<std::string> globalViewModelNames(numViewModels);
                for (auto& name : globalViewModelNames)
                {
                    m_messageNames >> name;
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onGlobalViewModelNamesListed(
                        handle,
                        requestId,
                        globalViewModelNames);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onGlobalViewModelNamesListed(
                        itr->first,
                        requestId,
                        std::move(globalViewModelNames));
                }

                break;
            }

            case Message::viewModelInstanceNamesListed:
            {
                size_t numViewModels;
                FileHandle handle;
                uint64_t requestId;
                std::string viewModelName;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numViewModels;
                m_messageNames >> viewModelName;
                std::vector<std::string> viewModelInstanceNames(numViewModels);
                for (auto& name : viewModelInstanceNames)
                {
                    m_messageNames >> name;
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onViewModelInstanceNamesListed(
                        handle,
                        requestId,
                        viewModelName,
                        viewModelInstanceNames);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onViewModelInstanceNamesListed(
                        itr->first,
                        requestId,
                        std::move(viewModelName),
                        std::move(viewModelInstanceNames));
                }
                break;
            }

            case Message::viewModelPropertiesListed:
            {
                size_t numViewProperties;
                FileHandle handle;
                uint64_t requestId;
                std::string viewModelName;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> numViewProperties;
                m_messageNames >> viewModelName;
                std::vector<CommandQueue::FileListener::ViewModelPropertyData>
                    viewModelProperties(numViewProperties);

                for (auto& property : viewModelProperties)
                {
                    m_messageStream >> property.type;
                    m_messageNames >> property.name;
                    if (property.type == DataType::enumType ||
                        property.type == DataType::viewModel)
                    {
                        m_messageNames >> property.metaData;
                    }
                }
                lock.unlock();

                if (m_globalFileListener)
                {
                    m_globalFileListener->onViewModelPropertiesListed(
                        handle,
                        requestId,
                        viewModelName,
                        viewModelProperties);
                }

                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onViewModelPropertiesListed(
                        itr->first,
                        requestId,
                        std::move(viewModelName),
                        std::move(viewModelProperties));
                }

                break;
            }

            case Message::viewModelPropertyValueReceived:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                ViewModelInstanceData value;

                m_messageStream >> handle;
                m_messageStream >> value.metaData.type;
                m_messageStream >> requestId;
                m_messageNames >> value.metaData.name;

                switch (value.metaData.type)
                {
                    case DataType::assetImage:
                    case DataType::assetBlob:
                    case DataType::list:
                    case DataType::trigger:
                        break;
                    case DataType::boolean:
                        m_messageStream >> value.boolValue;
                        break;
                    case DataType::number:
                        m_messageStream >> value.numberValue;
                        break;
                    case DataType::color:
                        m_messageStream >> value.colorValue;
                        break;
                    case DataType::enumType:
                    case DataType::string:
                        m_messageNames >> value.stringValue;
                        break;
                    default:
                        RIVE_UNREACHABLE();
                }

                lock.unlock();

                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelDataReceived(
                        handle,
                        requestId,
                        value);
                }

                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelDataReceived(handle,
                                                         requestId,
                                                         value);
                }

                break;
            }

            case Message::viewModelListSizeReceived:
            {
                ViewModelInstanceHandle handle;
                std::string path;
                size_t size;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> size;
                m_messageStream >> requestId;
                m_messageNames >> path;
                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelListSizeReceived(
                        handle,
                        requestId,
                        path,
                        size);
                }
                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelListSizeReceived(handle,
                                                             requestId,
                                                             std::move(path),
                                                             size);
                }
                break;
            }

            case Message::viewModelListCleared:
            {
                ViewModelInstanceHandle handle;
                std::string path;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> path;
                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelListCleared(handle,
                                                                      requestId,
                                                                      path);
                }

                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelListCleared(handle,
                                                        requestId,
                                                        std::move(path));
                }
            }
            break;

            case Message::fileLoaded:
            {
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFileListener)
                {
                    m_globalFileListener->onFileLoaded(handle, requestId);
                }
                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onFileLoaded(handle, requestId);
                }
                break;
            }

            case Message::artboardInstantiated:
            {
                FileHandle fileHandle;
                ArtboardHandle handle;
                uint64_t requestId;
                m_messageStream >> fileHandle;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFileListener)
                {
                    m_globalFileListener->onArtboardInstantiated(fileHandle,
                                                                 requestId,
                                                                 handle);
                }
                auto itr = m_fileListeners.find(fileHandle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onArtboardInstantiated(fileHandle,
                                                        requestId,
                                                        handle);
                }
                break;
            }

            case Message::stateMachineInstantiated:
            {
                ArtboardHandle artboardHandle;
                StateMachineHandle handle;
                uint64_t requestId;
                m_messageStream >> artboardHandle;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onStateMachineInstantiated(
                        artboardHandle,
                        requestId,
                        handle);
                }
                auto itr = m_artboardListeners.find(artboardHandle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onStateMachineInstantiated(artboardHandle,
                                                            requestId,
                                                            handle);
                }
                break;
            }

            case Message::viewModelInstanceInstantiated:
            {
                FileHandle fileHandle;
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                m_messageStream >> fileHandle;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFileListener)
                {
                    m_globalFileListener->onViewModelInstanceInstantiated(
                        fileHandle,
                        requestId,
                        handle);
                }
                auto itr = m_fileListeners.find(fileHandle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onViewModelInstanceInstantiated(fileHandle,
                                                                 requestId,
                                                                 handle);
                }
                break;
            }

            case Message::fileDeleted:
            {
                FileHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFileListener)
                {
                    m_globalFileListener->onFileDeleted(handle, requestId);
                }
                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onFileDeleted(handle, requestId);
                }
                break;
            }
            case Message::imageDecoded:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalImageListener)
                {
                    m_globalImageListener->onRenderImageDecoded(handle,
                                                                requestId);
                }
                auto itr = m_imageListeners.find(handle);
                if (itr != m_imageListeners.end())
                {
                    itr->second->onRenderImageDecoded(handle, requestId);
                }
                break;
            }
            case Message::imageDeleted:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalImageListener)
                {
                    m_globalImageListener->onRenderImageDeleted(handle,
                                                                requestId);
                }
                auto itr = m_imageListeners.find(handle);
                if (itr != m_imageListeners.end())
                {
                    itr->second->onRenderImageDeleted(handle, requestId);
                }
                break;
            }
            case Message::audioDecoded:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalAudioListener)
                {
                    m_globalAudioListener->onAudioSourceDecoded(handle,
                                                                requestId);
                }
                auto itr = m_audioListeners.find(handle);
                if (itr != m_audioListeners.end())
                {
                    itr->second->onAudioSourceDecoded(handle, requestId);
                }
                break;
            }
            case Message::audioDeleted:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalAudioListener)
                {
                    m_globalAudioListener->onAudioSourceDeleted(handle,
                                                                requestId);
                }
                auto itr = m_audioListeners.find(handle);
                if (itr != m_audioListeners.end())
                {
                    itr->second->onAudioSourceDeleted(handle, requestId);
                }
                break;
            }
            case Message::fontDecoded:
            {
                FontHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFontListener)
                {
                    m_globalFontListener->onFontDecoded(handle, requestId);
                }
                auto itr = m_fontListeners.find(handle);
                if (itr != m_fontListeners.end())
                {
                    itr->second->onFontDecoded(handle, requestId);
                }
                break;
            }
            case Message::fontDeleted:
            {
                FontHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalFontListener)
                {
                    m_globalFontListener->onFontDeleted(handle, requestId);
                }
                auto itr = m_fontListeners.find(handle);
                if (itr != m_fontListeners.end())
                {
                    itr->second->onFontDeleted(handle, requestId);
                }
                break;
            }
            case Message::blobDecoded:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalBlobListener)
                {
                    m_globalBlobListener->onBlobAssetDecoded(handle, requestId);
                }
                auto itr = m_blobListeners.find(handle);
                if (itr != m_blobListeners.end())
                {
                    itr->second->onBlobAssetDecoded(handle, requestId);
                }
                break;
            }
            case Message::blobDeleted:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalBlobListener)
                {
                    m_globalBlobListener->onBlobAssetDeleted(handle, requestId);
                }
                auto itr = m_blobListeners.find(handle);
                if (itr != m_blobListeners.end())
                {
                    itr->second->onBlobAssetDeleted(handle, requestId);
                }
                break;
            }
            case Message::artboardDeleted:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onArtboardDeleted(handle,
                                                                requestId);
                }
                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onArtboardDeleted(handle, requestId);
                }
                break;
            }
            case Message::viewModelDeleted:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelDeleted(handle,
                                                                  requestId);
                }
                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelDeleted(handle, requestId);
                }
                break;
            }
            case Message::stateMachineViewModelInstanceReceived:
            {
                StateMachineHandle stateMachineHandle;
                ViewModelInstanceHandle viewModelInstanceHandle;
                uint64_t requestId;
                m_messageStream >> stateMachineHandle;
                m_messageStream >> viewModelInstanceHandle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onViewModelInstanceReceived(
                        stateMachineHandle,
                        requestId,
                        viewModelInstanceHandle);
                }
                auto itr = m_stateMachineListeners.find(stateMachineHandle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onViewModelInstanceReceived(
                        stateMachineHandle,
                        requestId,
                        viewModelInstanceHandle);
                }
                break;
            }
            case Message::stateMachineSettled:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onStateMachineSettled(
                        handle,
                        requestId);
                }
                auto itr = m_stateMachineListeners.find(handle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onStateMachineSettled(handle, requestId);
                }
                break;
            }
            case Message::stateMachineDeleted:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onStateMachineDeleted(
                        handle,
                        requestId);
                }
                auto itr = m_stateMachineListeners.find(handle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onStateMachineDeleted(handle, requestId);
                }
                break;
            }
            case Message::semanticsDiffReceived:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                SemanticsDiff diff;
                m_messageSemanticsDiffs >> diff;
                lock.unlock();
                auto itr = m_stateMachineListeners.find(handle);
                const bool hasPerHandleListener =
                    itr != m_stateMachineListeners.end();
                if (m_globalStateMachineListener)
                {
                    // Copy to the global listener only when a per-handle
                    // listener also needs the diff; otherwise move.
                    if (hasPerHandleListener)
                    {
                        m_globalStateMachineListener->onSemanticsDiffReceived(
                            handle,
                            requestId,
                            diff);
                    }
                    else
                    {
                        m_globalStateMachineListener->onSemanticsDiffReceived(
                            handle,
                            requestId,
                            std::move(diff));
                    }
                }
                if (hasPerHandleListener)
                {
                    itr->second->onSemanticsDiffReceived(handle,
                                                         requestId,
                                                         std::move(diff));
                }
                break;
            }
            case Message::artboardSizeReceived:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                float width, height;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> width;
                m_messageStream >> height;
                lock.unlock();
                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onArtboardSizeReceived(handle,
                                                                     requestId,
                                                                     width,
                                                                     height);
                }
                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onArtboardSizeReceived(handle,
                                                        requestId,
                                                        width,
                                                        height);
                }
                break;
            }

            case Message::fileError:
            {
                FileHandle handle;
                std::string error;
                uint64_t requestId;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalFileListener)
                {
                    m_globalFileListener->onFileError(handle, requestId, error);
                }
                auto itr = m_fileListeners.find(handle);
                if (itr != m_fileListeners.end())
                {
                    itr->second->onFileError(handle,
                                             requestId,
                                             std::move(error));
                }

                break;
            }
            case Message::viewModelError:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;

                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalViewModelListener)
                {
                    m_globalViewModelListener->onViewModelInstanceError(
                        handle,
                        requestId,
                        error);
                }
                auto itr = m_viewModelListeners.find(handle);
                if (itr != m_viewModelListeners.end())
                {
                    itr->second->onViewModelInstanceError(handle,
                                                          requestId,
                                                          std::move(error));
                }
                break;
            }
            case Message::imageError:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalImageListener)
                {
                    m_globalImageListener->onRenderImageError(handle,
                                                              requestId,
                                                              error);
                }
                auto itr = m_imageListeners.find(handle);
                if (itr != m_imageListeners.end())
                {
                    itr->second->onRenderImageError(handle,
                                                    requestId,
                                                    std::move(error));
                }
                break;
            }

            case Message::audioError:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalAudioListener)
                {
                    m_globalAudioListener->onAudioSourceError(handle,
                                                              requestId,
                                                              error);
                }
                auto itr = m_audioListeners.find(handle);
                if (itr != m_audioListeners.end())
                {
                    itr->second->onAudioSourceError(handle,
                                                    requestId,
                                                    std::move(error));
                }
                break;
            }
            case Message::fontError:
            {
                FontHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalFontListener)
                {
                    m_globalFontListener->onFontError(handle, requestId, error);
                }
                auto itr = m_fontListeners.find(handle);
                if (itr != m_fontListeners.end())
                {
                    itr->second->onFontError(handle,
                                             requestId,
                                             std::move(error));
                }
                break;
            }

            case Message::blobError:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalBlobListener)
                {
                    m_globalBlobListener->onBlobAssetError(handle,
                                                           requestId,
                                                           error);
                }
                auto itr = m_blobListeners.find(handle);
                if (itr != m_blobListeners.end())
                {
                    itr->second->onBlobAssetError(handle,
                                                  requestId,
                                                  std::move(error));
                }
                break;
            }

            case Message::stateMachineError:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onStateMachineError(handle,
                                                                      requestId,
                                                                      error);
                }
                auto itr = m_stateMachineListeners.find(handle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onStateMachineError(handle,
                                                     requestId,
                                                     std::move(error));
                }
                break;
            }
            case Message::artboardError:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                std::string error;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageNames >> error;
                lock.unlock();
                if (m_globalArtboardListener)
                {
                    m_globalArtboardListener->onArtboardError(handle,
                                                              requestId,
                                                              error);
                }
                auto itr = m_artboardListeners.find(handle);
                if (itr != m_artboardListeners.end())
                {
                    itr->second->onArtboardError(handle,
                                                 requestId,
                                                 std::move(error));
                }
                break;
            }
            case Message::hasFocusNodesReceived:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                bool hasFocusNodes;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> hasFocusNodes;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onHasFocusNodesReceived(
                        handle,
                        requestId,
                        hasFocusNodes);
                }
                auto itr = m_stateMachineListeners.find(handle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onHasFocusNodesReceived(handle,
                                                         requestId,
                                                         hasFocusNodes);
                }
                break;
            }
            case Message::focusStateReceived:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                FocusState focusState;
                m_messageStream >> handle;
                m_messageStream >> requestId;
                m_messageStream >> focusState.hasFocus;
                m_messageStream >> focusState.expectsKeyboardInput;
                lock.unlock();
                if (m_globalStateMachineListener)
                {
                    m_globalStateMachineListener->onFocusStateReceived(
                        handle,
                        requestId,
                        focusState);
                }
                auto itr = m_stateMachineListeners.find(handle);
                if (itr != m_stateMachineListeners.end())
                {
                    itr->second->onFocusStateReceived(handle,
                                                      requestId,
                                                      focusState);
                }
                break;
            }
        }

        assert(!lock.owns_lock());
        lock.lock();
    } while (!m_messageStream.empty());
}

bool CommandQueue::focusNextSynchronized(StateMachineHandle handle)
{
    auto result = std::make_shared<std::promise<bool>>();
    auto future = result->get_future();
    runOnce([handle, result](CommandServer* server) {
        result->set_value(server->focusNextSynchronized(handle));
    });
    return future.get();
}

bool CommandQueue::focusPreviousSynchronized(StateMachineHandle handle)
{
    auto result = std::make_shared<std::promise<bool>>();
    auto future = result->get_future();
    runOnce([handle, result](CommandServer* server) {
        result->set_value(server->focusPreviousSynchronized(handle));
    });
    return future.get();
}

void CommandQueue::focusNext(StateMachineHandle stateMachineHandle,
                             uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::focusNext;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::focusPrevious(StateMachineHandle stateMachineHandle,
                                 uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::focusPrevious;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestHasFocusNodes(StateMachineHandle stateMachineHandle,
                                        uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::requestHasFocusNodes;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::clearFocus(StateMachineHandle stateMachineHandle,
                              uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::clearFocus;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

void CommandQueue::requestFocusState(StateMachineHandle stateMachineHandle,
                                     uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::requestFocusState;
    m_commandStream << stateMachineHandle;
    m_commandStream << requestId;
}

}; // namespace rive
