/*
 * Copyright 2025 Rive
 */

#include "rive/command_queue.hpp"

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)
{
    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);

    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::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::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;
}

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

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::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::requestViewModelInstanceViewModelName(
    ViewModelInstanceHandle viewModelInstanceHandle,
    uint64_t requestId)
{
    AutoLockAndNotify lock(m_commandMutex, m_commandConditionVariable);
    m_commandStream << Command::getViewModelInstanceViewModelName;
    m_commandStream << viewModelInstanceHandle;
    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::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::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.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::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::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::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::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::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::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::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;
            }
        }

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

}; // namespace rive
