/*
 * Copyright 2025 Rive
 */

#include "rive/command_server.hpp"

#include "rive/animation/state_machine_instance.hpp"
#include "rive/assets/audio_asset.hpp"
#include "rive/assets/font_asset.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/file.hpp"
#include "rive/semantic/semantic_manager.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#include "rive/lua/rive_lua_libs.hpp"

namespace rive
{

class CommandServer::CommandFileAssetLoader : public FileAssetLoader
{
public:
    CommandFileAssetLoader(CommandServer* server,
                           rcp<rive::FileAssetLoader> internalLoader) :
        m_server(server), m_internalLoader(internalLoader)
    {}

    virtual bool loadContents(FileAsset& asset,
                              Span<const uint8_t> inBandBytes,
                              Factory* factory) override
    {
        if (m_internalLoader)
        {
            if (m_internalLoader->loadContents(asset, inBandBytes, factory))
                return true;
        }
        if (asset.is<ImageAsset>())
        {
            // No need for another if because as just asserts the above
            // condition anyway
            auto imageAsset = asset.as<ImageAsset>();
            auto itr = m_imageAssets.find(asset.uniqueName());
            if (itr != m_imageAssets.end())
            {
                auto image = m_server->getImage(itr->second);
                if (image)
                {
                    imageAsset->renderImage(ref_rcp(image));
                    return true;
                }
                return false;
            }
        }

        else if (asset.is<AudioAsset>())
        {
            auto audioAsset = asset.as<AudioAsset>();
            auto itr = m_audioAssets.find(asset.uniqueName());
            if (itr != m_audioAssets.end())
            {
                auto audioSource = m_server->getAudioSource(itr->second);
                if (audioSource)
                {
                    audioAsset->audioSource(ref_rcp(audioSource));
                    return true;
                }
                return false;
            }
        }
        else if (asset.is<FontAsset>())
        {
            auto fontAsset = asset.as<FontAsset>();
            auto itr = m_fontAssets.find(asset.uniqueName());
            if (itr != m_fontAssets.end())
            {
                auto font = m_server->getFont(itr->second);
                if (font)
                {
                    fontAsset->font(ref_rcp(font));
                    return true;
                }
                return false;
            }
        }
        else if (asset.is<ScriptAsset>())
        {
            // Script assets cannot currently be added externally.
            // Let the file loader handle it.
            return false;
        }
        else
        {
            fprintf(stderr,
                    "ERROR: CommandFileAssetLoader::loadContents - Unsupported"
                    " asset type for asset: '%s'\n",
                    asset.uniqueFilename().c_str());
            return false;
        }

        return false;
    }

    void addRenderImage(std::string name, RenderImageHandle handle)
    {
        m_imageAssets[name] = handle;
    }

    void addAudioSource(std::string name, AudioSourceHandle handle)
    {
        m_audioAssets[name] = handle;
    }

    void addFont(std::string name, FontHandle handle)
    {
        m_fontAssets[name] = handle;
    }

    void removeRenderImage(RenderImageHandle handle)
    {
        using ItrType = std::pair<std::string, RenderImageHandle>;
        auto itr = std::find_if(
            m_imageAssets.begin(),
            m_imageAssets.end(),
            [handle](const ItrType& p) { return p.second == handle; });
        if (itr != m_imageAssets.end())
            m_imageAssets.erase(itr);
    }

    void removeAudioSource(AudioSourceHandle handle)
    {
        using ItrType = std::pair<std::string, AudioSourceHandle>;
        auto itr = std::find_if(
            m_audioAssets.begin(),
            m_audioAssets.end(),
            [handle](const ItrType& p) { return p.second == handle; });
        if (itr != m_audioAssets.end())
            m_audioAssets.erase(itr);
    }

    void removeFont(FontHandle handle)
    {
        using ItrType = std::pair<std::string, FontHandle>;
        auto itr = std::find_if(
            m_fontAssets.begin(),
            m_fontAssets.end(),
            [handle](const ItrType& p) { return p.second == handle; });
        if (itr != m_fontAssets.end())
            m_fontAssets.erase(itr);
    }

    void removeRenderImage(std::string name) { m_imageAssets.erase(name); }
    void removeAudioSource(std::string name) { m_audioAssets.erase(name); }
    void removeFont(std::string name) { m_fontAssets.erase(name); }

#ifdef TESTING
    RenderImageHandle testing_imageNamed(std::string name)
    {
        auto itr = m_imageAssets.find(name);
        if (itr != m_imageAssets.end())
            return itr->second;
        return nullptr;
    }

    AudioSourceHandle testing_audioNamed(std::string name)
    {
        auto itr = m_audioAssets.find(name);
        if (itr != m_audioAssets.end())
            return itr->second;
        return nullptr;
    }

    FontHandle testing_fontNamed(std::string name)
    {
        auto itr = m_fontAssets.find(name);
        if (itr != m_fontAssets.end())
            return itr->second;
        return nullptr;
    }
#endif

private:
    const CommandServer* m_server;

    std::unordered_map<std::string, RenderImageHandle> m_imageAssets;
    std::unordered_map<std::string, AudioSourceHandle> m_audioAssets;
    std::unordered_map<std::string, FontHandle> m_fontAssets;
    rcp<FileAssetLoader> m_internalLoader;
};

std::ostream& operator<<(std::ostream& os, DataType t)
{
    switch (t)
    {
        case DataType::none:
            os << "None";
            break;
        case DataType::string:
            os << "String";
            break;
        case DataType::number:
            os << "Number";
            break;
        case DataType::boolean:
            os << "Boolean";
            break;
        case DataType::color:
            os << "Color";
            break;
        case DataType::list:
            os << "List";
            break;
        case DataType::enumType:
            os << "Enum";
            break;
        case DataType::trigger:
            os << "Trigger";
            break;
        case DataType::viewModel:
            os << "View Model";
            break;
        case DataType::integer:
            os << "Integer";
            break;
        case DataType::symbolListIndex:
            os << "Symbol List Index";
            break;
        case DataType::assetImage:
            os << "Asset Image";
            break;
        default:
            os << "Unknown DataType";
            break;
    }
    return os;
}

#ifdef TESTING

RenderImageHandle CommandServer::testing_globalImageNamed(std::string name)
{
    return m_fileAssetLoader->testing_imageNamed(name);
}

AudioSourceHandle CommandServer::testing_globalAudioNamed(std::string name)
{
    return m_fileAssetLoader->testing_audioNamed(name);
}

FontHandle CommandServer::testing_globalFontNamed(std::string name)
{
    return m_fileAssetLoader->testing_fontNamed(name);
}

bool CommandServer::testing_globalImageContains(std::string name)
{
    return m_fileAssetLoader->testing_imageNamed(name) != nullptr;
}

bool CommandServer::testing_globalAudioContains(std::string name)
{
    return m_fileAssetLoader->testing_audioNamed(name) != nullptr;
}

bool CommandServer::testing_globalFontContains(std::string name)
{
    return m_fileAssetLoader->testing_fontNamed(name) != nullptr;
}

#endif

CommandServer::CommandServer(rcp<CommandQueue> commandBuffer,
                             Factory* factory,
                             rcp<rive::FileAssetLoader> internalLoader) :
    m_commandQueue(std::move(commandBuffer)),
    m_factory(factory),
#ifndef NDEBUG
    m_threadID(std::this_thread::get_id()),
#endif
    m_fileAssetLoader(
        make_rcp<CommandFileAssetLoader>(this, std::move(internalLoader)))
{}

CommandServer::~CommandServer() {}

rive::HitResult CommandServer::pointerDownSynchronized(
    StateMachineHandle handle,
    const CommandQueue::PointerEvent& pointerEvent)
{
    std::unique_lock<std::mutex> accesLock(m_stateMachineAccessMutex);
    auto it = m_stateMachines.find(handle);
    if (it != m_stateMachines.end())
    {
        auto stateMachine = it->second;
        accesLock.unlock();
        auto pos = cursorPosForPointerEvent(stateMachine->instance.get(),
                                            pointerEvent);
        {
            std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
            auto hitResult =
                stateMachine->instance->pointerDown(pos,
                                                    pointerEvent.pointerId);
            // Process down-driven state changes before a following pointer up.
            if (hitResult != HitResult::none)
            {
                stateMachine->instance->advanceAndApply(0.0f);
            }
            return hitResult;
        }
    }

    return rive::HitResult::none;
}

rive::HitResult CommandServer::pointerMoveSynchronized(
    StateMachineHandle handle,
    const CommandQueue::PointerEvent& pointerEvent)
{
    std::unique_lock<std::mutex> accesLock(m_stateMachineAccessMutex);
    auto it = m_stateMachines.find(handle);
    if (it != m_stateMachines.end())
    {
        auto stateMachine = it->second;
        accesLock.unlock();
        auto pos = cursorPosForPointerEvent(stateMachine->instance.get(),
                                            pointerEvent);
        {
            std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
            return stateMachine->instance->pointerMove(pos,
                                                       0,
                                                       pointerEvent.pointerId);
        }
    }

    return rive::HitResult::none;
}

rive::HitResult CommandServer::pointerUpSynchronized(
    StateMachineHandle handle,
    const CommandQueue::PointerEvent& pointerEvent)
{
    std::unique_lock<std::mutex> accesLock(m_stateMachineAccessMutex);
    auto it = m_stateMachines.find(handle);
    if (it != m_stateMachines.end())
    {
        auto stateMachine = it->second;
        accesLock.unlock();
        auto pos = cursorPosForPointerEvent(stateMachine->instance.get(),
                                            pointerEvent);
        {
            std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
            auto hitResult =
                stateMachine->instance->pointerUp(pos, pointerEvent.pointerId);
            // Process up-driven state changes before any following pointer
            // exit.
            if (hitResult != HitResult::none)
            {
                stateMachine->instance->advanceAndApply(0.0f);
            }
            return hitResult;
        }
    }

    return rive::HitResult::none;
}

File* CommandServer::getFile(FileHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_files.find(handle);
    return it != m_files.end() ? it->second.get() : nullptr;
}

RenderImage* CommandServer::getImage(RenderImageHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_images.find(handle);
    return it != m_images.end() ? it->second.get() : nullptr;
}

AudioSource* CommandServer::getAudioSource(AudioSourceHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_audioSources.find(handle);
    return it != m_audioSources.end() ? it->second.get() : nullptr;
}

Font* CommandServer::getFont(FontHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_fonts.find(handle);
    return it != m_fonts.end() ? it->second.get() : nullptr;
}

ArtboardInstance* CommandServer::getArtboardInstance(
    ArtboardHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_artboards.find(handle);
    return it != m_artboards.end() ? it->second.get()->artboard() : nullptr;
}

rcp<BindableArtboard> CommandServer::getBindableArtboard(
    ArtboardHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_artboards.find(handle);
    return it != m_artboards.end() ? it->second : nullptr;
}

rcp<CommandServer::SynchronizedStateMachine> CommandServer::
    getStateMachineWrapper(StateMachineHandle handle)
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_stateMachines.find(handle);
    return it != m_stateMachines.end() ? it->second : nullptr;
}

StateMachineInstance* CommandServer::getStateMachineInstance(
    StateMachineHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_stateMachines.find(handle);
    return it != m_stateMachines.end() ? it->second->instance.get() : nullptr;
}

ViewModelInstanceRuntime* CommandServer::getViewModelInstance(
    ViewModelInstanceHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_viewModels.find(handle);
    return it != m_viewModels.end() ? it->second.get() : nullptr;
}

ViewModelInstanceHandle CommandServer::getHandleForInstance(
    ViewModelInstanceRuntime* handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    for (auto& itr : m_viewModels)
    {
        if (itr.second.get() == handle)
        {
            return itr.first;
        }
    }
    return RIVE_NULL_HANDLE;
}

Vec2D CommandServer::cursorPosForPointerEvent(
    StateMachineInstance* instance,
    const CommandQueue::PointerEvent& pointerEvent)
{
    AABB artboardBounds = instance->artboard()->bounds();
    AABB surfaceBounds = AABB(Vec2D{0.0f, 0.0f}, pointerEvent.screenBounds);

    if (surfaceBounds == artboardBounds || surfaceBounds.width() == 0.0f ||
        surfaceBounds.height() == 0.0f)
    {
        return pointerEvent.position;
    }

    Mat2D forward = rive::computeAlignment(pointerEvent.fit,
                                           pointerEvent.alignment,
                                           surfaceBounds,
                                           artboardBounds,
                                           pointerEvent.scaleFactor);

    Mat2D inverse = forward.invertOrIdentity();

    return inverse * pointerEvent.position;
}

// Maps a semantics bounds payload from artboard space to view space.
// Templated so the same transform path can be reused for both
// SemanticsDiffNode and SemanticsBoundsUpdate via bounds()/setBounds().
template <typename T>
static void mapSemanticsBounds(T& value, const Mat2D& transform)
{
    value.setBounds(transform.mapBoundingBox(value.bounds()));
}

// Applies artboard->view bounds mapping to all geometry-bearing collections
// in a semantic diff before it is delivered to listeners.
static void mapSemanticsDiffToViewSpace(SemanticsDiff& diff,
                                        const Mat2D& transform)
{
    for (auto& node : diff.added)
    {
        mapSemanticsBounds(node, transform);
    }
    for (auto& node : diff.moved)
    {
        mapSemanticsBounds(node, transform);
    }
    for (auto& node : diff.updatedSemantic)
    {
        mapSemanticsBounds(node, transform);
    }
    for (auto& bounds : diff.updatedGeometry)
    {
        mapSemanticsBounds(bounds, transform);
    }
}

void CommandServer::checkPropertySubscriptions()
{
    for (auto& subscription : m_propertySubscriptions)
    {
        uint64_t requestId = subscription.requestId;
        ViewModelInstanceHandle handle = subscription.rootViewModel;
        CommandQueue::ViewModelInstanceData data;
        data.metaData = subscription.data;

        if (auto viewModel = getViewModelInstance(handle))
        {
            if (auto property = viewModel->property(data.metaData.name))
            {
                if (property->hasChanged())
                {
                    property->clearChanges();
                    switch (data.metaData.type)
                    {
                        // These don't have values but are still valid
                        // subscriptions.
                        case DataType::assetImage:
                        case DataType::trigger:
                        case DataType::list:
                            break;
                        case DataType::boolean:
                            if (auto value = static_cast<
                                    ViewModelInstanceBooleanRuntime*>(property))
                            {
                                data.boolValue = value->value();
                            }
                            break;

                        case DataType::color:
                            if (auto value =
                                    static_cast<ViewModelInstanceColorRuntime*>(
                                        property))
                            {
                                data.colorValue = value->value();
                            }
                            break;

                        case DataType::number:
                            if (auto value = static_cast<
                                    ViewModelInstanceNumberRuntime*>(property))
                            {
                                data.numberValue = value->value();
                            }
                            break;

                        case DataType::enumType:
                            if (auto value =
                                    static_cast<ViewModelInstanceEnumRuntime*>(
                                        property))
                            {
                                data.stringValue = value->value();
                            }
                            break;

                        case DataType::string:
                            if (auto value = static_cast<
                                    ViewModelInstanceStringRuntime*>(property))
                            {
                                data.stringValue = value->value();
                            }
                            break;
                        default:
                            ErrorReporter<ViewModelInstanceHandle>(
                                this,
                                handle,
                                requestId,
                                CommandQueue::Message::viewModelError)
                                << "ERROR : Invalid data type {"
                                << data.metaData.type << "} when checking"
                                << "subscriptions";
                            continue;
                    }

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    m_commandQueue->m_messageStream << CommandQueue::Message::
                            viewModelPropertyValueReceived;
                    m_commandQueue->m_messageStream << handle;
                    m_commandQueue->m_messageStream << data.metaData.type;
                    m_commandQueue->m_messageNames << data.metaData.name;
                    m_commandQueue->m_messageStream << requestId;
                    switch (data.metaData.type)
                    {
                        case DataType::assetImage:
                        case DataType::trigger:
                        case DataType::list:
                            break;
                        case DataType::boolean:
                            m_commandQueue->m_messageStream << data.boolValue;
                            break;
                        case DataType::number:
                            m_commandQueue->m_messageStream << data.numberValue;
                            break;
                        case DataType::color:
                            m_commandQueue->m_messageStream << data.colorValue;
                            break;
                        case DataType::enumType:
                        case DataType::string:
                            m_commandQueue->m_messageNames << data.stringValue;
                            break;
                        default:
                            RIVE_UNREACHABLE();
                    }
                }
            }
        }
    }
}

void CommandServer::serveUntilDisconnect()
{
    while (waitCommands())
    {
    }
}

bool CommandServer::waitCommands()
{
    PODStream& commandStream = m_commandQueue->m_commandStream;
    if (commandStream.empty())
    {
        std::unique_lock<std::mutex> lock(m_commandQueue->m_commandMutex);
        while (commandStream.empty())
        {
            assert(m_commandQueue->m_callbacks.empty());
            assert(m_commandQueue->m_byteVectors.empty());
            assert(m_commandQueue->m_names.empty());
            m_commandQueue->m_commandConditionVariable.wait(lock);
        }
    }

    return processCommands();
}

bool CommandServer::processCommands()
{
    assert(m_wasDisconnectReceived == false);
    assert(std::this_thread::get_id() == m_threadID);

    PODStream& commandStream = m_commandQueue->m_commandStream;
    PODStream& messageStream = m_commandQueue->m_messageStream;
    std::unique_lock<std::mutex> lock(m_commandQueue->m_commandMutex);

    // Early out if we don't have anything to process.
    if (commandStream.empty())
        return !m_wasDisconnectReceived;

    // Ensure we stop processing messages and get to the draw loop.
    // This avoids a race condition where we never stop processing messages and
    // therefore never draw anything.
    commandStream << CommandQueue::Command::commandLoopBreak;

    // The map should be empty at this point.
    assert(m_uniqueDraws.empty());

    bool shouldProcessCommands = true;
    do
    {
        CommandQueue::Command command;
        commandStream >> command;

        switch (command)
        {
            case CommandQueue::Command::loadFile:
            {
                FileHandle handle;
                uint64_t requestId;
                std::vector<uint8_t> rivBytes;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_byteVectors >> rivBytes;
#ifdef WITH_RIVE_SCRIPTING
                ScriptingContextFactory scriptingContextFactory;
                m_commandQueue->m_scriptingContextFactories >>
                    scriptingContextFactory;
#endif
                lock.unlock();
#ifdef WITH_RIVE_SCRIPTING
                std::cout << "Rive: Command Server Scripting Enabled.\n";
                // Use the host-provided scripting context when supplied (e.g.
                // Unreal routes console/error output to UE_LOG); otherwise fall
                // back to the default CPP runtime context.
                std::unique_ptr<ScriptingContext> scriptingContext =
                    scriptingContextFactory ? scriptingContextFactory(m_factory)
                                            : nullptr;
                if (scriptingContext == nullptr)
                {
                    scriptingContext =
                        std::make_unique<CPPRuntimeScriptingContext>(m_factory);
                }
                scriptingContext->setRenderContext(m_factory);
                auto vm = make_rcp<ScriptingVM>(std::move(scriptingContext));
                rcp<rive::File> file = rive::File::import(rivBytes,
                                                          m_factory,
                                                          nullptr,
                                                          m_fileAssetLoader,
                                                          vm.get());

#else
                rcp<rive::File> file = rive::File::import(rivBytes,
                                                          m_factory,
                                                          nullptr,
                                                          m_fileAssetLoader);
#endif

                if (file != nullptr)
                {
                    m_fileDependencies[handle] = {};
                    m_files[handle] = file;

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::fileLoaded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "failed to load Rive file.";
                }
                break;
            }

            case CommandQueue::Command::deleteFile:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_files.erase(handle);
                auto itr = m_fileDependencies.find(handle);
                if (itr != m_fileDependencies.end())
                {
                    auto& artboardVector = itr->second;
                    for (auto artboardHandle : artboardVector)
                    {
                        cleanupArtboard(artboardHandle, requestId);
                    }

                    m_fileDependencies.erase(itr);
                }
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::fileDeleted;
                messageStream << handle;
                messageStream << requestId;
                break;
            }

            case CommandQueue::Command::decodeImage:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                std::vector<uint8_t> bytes;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_byteVectors >> bytes;
                lock.unlock();

                auto image = factory()->decodeImage(bytes);
                if (image)
                {
                    m_images[handle] = std::move(image);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::imageDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<RenderImageHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::imageError)
                        << "Command Server failed to decode image";
                }

                break;
            }

            case CommandQueue::Command::externalImage:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                rcp<RenderImage> image;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_externalImages >> image;
                lock.unlock();

                if (image)
                {
                    m_images[handle] = std::move(image);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::imageDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<RenderImageHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::imageError)
                        << "External image was empty";
                }

                break;
            }

            case CommandQueue::Command::deleteImage:
            {
                RenderImageHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_images.erase(handle);
                m_fileAssetLoader->removeRenderImage(handle);
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::imageDeleted;
                messageStream << handle;
                messageStream << requestId;
                break;
            }

            case CommandQueue::Command::decodeAudio:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                std::vector<uint8_t> bytes;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_byteVectors >> bytes;
                lock.unlock();

                auto audio = factory()->decodeAudio(bytes);
                if (audio)
                {
                    m_audioSources[handle] = std::move(audio);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::audioDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<AudioSourceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::audioError)
                        << "Command Server failed to decode audio";
                }

                break;
            }

            case CommandQueue::Command::externalAudio:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                rcp<AudioSource> audio;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_externalAudioSources >> audio;
                lock.unlock();

                if (audio)
                {
                    m_audioSources[handle] = std::move(audio);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::audioDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<AudioSourceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::audioError)
                        << "External audio source was invalid";
                }

                break;
            }

            case CommandQueue::Command::deleteAudio:
            {
                AudioSourceHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_audioSources.erase(handle);
                m_fileAssetLoader->removeAudioSource(handle);
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::audioDeleted;
                messageStream << handle;
                messageStream << requestId;
                break;
            }

            case CommandQueue::Command::decodeFont:
            {
                FontHandle handle;
                uint64_t requestId;
                std::vector<uint8_t> bytes;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_byteVectors >> bytes;
                lock.unlock();

                auto font = factory()->decodeFont(bytes);
                if (font)
                {
                    m_fonts[handle] = std::move(font);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::fontDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<FontHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fontError)
                        << "Command Server failed to decode font";
                }

                break;
            }

            case CommandQueue::Command::externalFont:
            {
                FontHandle handle;
                uint64_t requestId;
                rcp<Font> font;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_externalFonts >> font;
                lock.unlock();

                if (font)
                {
                    m_fonts[handle] = std::move(font);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::fontDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<FontHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fontError)
                        << "Command Server failed to decode font";
                }

                break;
            }

            case CommandQueue::Command::deleteFont:
            {
                FontHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_fonts.erase(handle);
                m_fileAssetLoader->removeFont(handle);
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::fontDeleted;
                messageStream << handle;
                messageStream << requestId;
                break;
            }

            case CommandQueue::Command::instantiateArtboard:
            {
                ArtboardHandle handle;
                FileHandle fileHandle;
                uint64_t requestId;
                std::string name;
                commandStream >> handle;
                commandStream >> fileHandle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                if (rive::File* file = getFile(fileHandle))
                {
                    if (auto artboard = name.empty()
                                            ? file->bindableArtboardDefault()
                                            : file->bindableArtboardNamed(name))
                    {
                        m_artboardDependencies[handle] = {};
                        m_artboards[handle] = std::move(artboard);

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::artboardInstantiated;
                        messageStream << fileHandle;
                        messageStream << handle;
                        messageStream << requestId;
                    }
                    else
                    {
                        ErrorReporter<FileHandle>(
                            this,
                            fileHandle,
                            requestId,
                            CommandQueue::Message::fileError)
                            << "artboard \"" << name << "\" not found.";
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              fileHandle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "file " << fileHandle
                        << " not found when trying to create artboard";
                }
                break;
            }

            case CommandQueue::Command::setArtboardSize:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                float width, height;
                commandStream >> handle;
                commandStream >> width;
                commandStream >> height;
                commandStream >> requestId;
                lock.unlock();

                if (auto artboardInstance = getArtboardInstance(handle))
                {
                    artboardInstance->width(width);
                    artboardInstance->height(height);
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "artboard " << handle
                        << " not found when trying to set artboard size";
                }
            }
            break;

            case CommandQueue::Command::resetArtboardSize:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();

                if (auto artboardInstance = getArtboardInstance(handle))
                {
                    artboardInstance->resetSize();
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "artboard " << handle
                        << " not found when trying to reset artboard size";
                }
            }
            break;

            case CommandQueue::Command::setArtboardVolume:
            {
                ArtboardHandle handle;
                float volume;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> volume;
                commandStream >> requestId;
                lock.unlock();

                if (auto artboardInstance = getArtboardInstance(handle))
                {
                    artboardInstance->volume(volume);
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "artboard " << handle
                        << " not found when trying to set artboard volume";
                }
            }
            break;

            case CommandQueue::Command::getArtboardVolume:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto artboard = getArtboardInstance(handle);
                if (artboard)
                {
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream
                        << CommandQueue::Message::artboardVolumeReceived;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << artboard->volume();
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "Invalid artboard handle " << handle
                        << " when getting artboard volume";
                }
                break;
            }

            case CommandQueue::Command::deleteArtboard:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                cleanupArtboard(handle, requestId);
                // We don't remove from the file dependencies here because
                // calling erase on a non existent key is fine.
                break;
            }

            case CommandQueue::Command::instantiateViewModel:
            case CommandQueue::Command::instantiateBlankViewModel:
            case CommandQueue::Command::instantiateViewModelForArtboard:
            case CommandQueue::Command::instantiateBlankViewModelForArtboard:
            {
                bool usesInstanceName =
                    command == CommandQueue::Command::instantiateViewModel ||
                    command ==
                        CommandQueue::Command::instantiateViewModelForArtboard;
                bool usesArtboard =
                    command == CommandQueue::Command::
                                   instantiateBlankViewModelForArtboard ||
                    command ==
                        CommandQueue::Command::instantiateViewModelForArtboard;

                FileHandle fileHandle;
                ArtboardHandle artboardHandle;
                ViewModelInstanceHandle viewHandle;
                uint64_t requestId;
                std::string viewModelName;
                std::string viewModelInstanceName;
                commandStream >> fileHandle;
                if (usesArtboard)
                {
                    commandStream >> artboardHandle;
                }
                commandStream >> viewHandle;
                commandStream >> requestId;
                if (!usesArtboard)
                {
                    m_commandQueue->m_names >> viewModelName;
                }
                if (usesInstanceName)
                {
                    m_commandQueue->m_names >> viewModelInstanceName;
                }
                lock.unlock();
                if (auto file = getFile(fileHandle))
                {
                    ViewModelRuntime* viewModel = nullptr;

                    if (usesArtboard)
                    {
                        if (auto artboardInstance =
                                getArtboardInstance(artboardHandle))
                        {
                            viewModel = file->defaultArtboardViewModel(
                                artboardInstance);
                            if (viewModel == nullptr)
                            {
                                ErrorReporter<FileHandle>(
                                    this,
                                    fileHandle,
                                    requestId,
                                    CommandQueue::Message::fileError)
                                    << "No view model found for artboard "
                                    << artboardHandle;
                            }
                        }
                        else
                        {
                            if (usesInstanceName)
                            {
                                if (viewModelInstanceName.empty())
                                {
                                    ErrorReporter<FileHandle>(
                                        this,
                                        fileHandle,
                                        requestId,
                                        CommandQueue::Message::fileError)
                                        << "ArtboardInstance " << artboardHandle
                                        << " Not found when trying to create"
                                        << " default view model with default "
                                           "view "
                                        << "model instance";
                                }
                                else
                                {
                                    ErrorReporter<FileHandle>(
                                        this,
                                        fileHandle,
                                        requestId,
                                        CommandQueue::Message::fileError)
                                        << "ArtboardInstance " << artboardHandle
                                        << " Not found when trying to create "
                                        << "default view model with "
                                        << "view model instance name "
                                        << viewModelInstanceName;
                                }
                            }
                            else
                            {
                                ErrorReporter<FileHandle>(
                                    this,
                                    fileHandle,
                                    requestId,
                                    CommandQueue::Message::fileError)
                                    << "ArtboardInstance " << artboardHandle
                                    << " Not found when trying to create "
                                    << "default view model with blank view "
                                    << "model instance";
                            }
                        }
                    }
                    else
                    {
                        viewModel = file->viewModelByName(viewModelName);
                        if (viewModel == nullptr)
                        {
                            ErrorReporter<FileHandle>(
                                this,
                                fileHandle,
                                requestId,
                                CommandQueue::Message::fileError)
                                << "View model " << viewModelName
                                << " not found";
                        }
                    }

                    if (viewModel)
                    {
                        rcp<ViewModelInstanceRuntime> instance;

                        if (usesInstanceName)
                        {
                            if (viewModelInstanceName.empty())
                            {
                                instance = viewModel->createDefaultInstance();
                                if (instance == nullptr)
                                {
                                    ErrorReporter<FileHandle>(
                                        this,
                                        fileHandle,
                                        requestId,
                                        CommandQueue::Message::fileError)
                                        << "Could not create "
                                        << "default view model instance "
                                        << "from view model " << viewModelName;
                                }
                            }
                            else
                            {
                                instance = viewModel->createInstanceFromName(
                                    viewModelInstanceName);
                                if (instance == nullptr)
                                {
                                    ErrorReporter<FileHandle>(
                                        this,
                                        fileHandle,
                                        requestId,
                                        CommandQueue::Message::fileError)
                                        << "Could not create "
                                           "view model instance named "
                                        << viewModelInstanceName
                                        << "from view model " << viewModelName;
                                }
                            }
                        }
                        else
                        {
                            instance = viewModel->createInstance();
                            if (instance == nullptr)
                            {
                                ErrorReporter<FileHandle>(
                                    this,
                                    fileHandle,
                                    requestId,
                                    CommandQueue::Message::fileError)
                                    << "Could not create "
                                    << "blank view model instance "
                                    << "from view model " << viewModelName;
                            }
                        }

                        if (instance)
                        {
                            m_viewModels[viewHandle] = std::move(instance);

                            std::unique_lock<std::mutex> messageLock(
                                m_commandQueue->m_messageMutex);
                            messageStream << CommandQueue::Message::
                                    viewModelInstanceInstantiated;
                            messageStream << fileHandle;
                            messageStream << viewHandle;
                            messageStream << requestId;
                        }
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              fileHandle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "File " << fileHandle
                        << " not found when creating view model instance ";
                }
                break;
            }

            case CommandQueue::Command::addViewModelListValue:
            {
                ViewModelInstanceHandle rootHandle;
                ViewModelInstanceHandle viewHandle;
                uint64_t requestId;
                std::string path;
                int index;
                commandStream >> rootHandle;
                commandStream >> viewHandle;
                commandStream >> index;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto root = getViewModelInstance(rootHandle))
                {
                    if (auto viewModel = getViewModelInstance(viewHandle))
                    {
                        if (auto property = root->propertyList(path))
                        {
                            if (index >= 0)
                                property->addInstanceAt(viewModel, index);
                            else
                                property->addInstance(viewModel);
                        }
                        else
                        {
                            ErrorReporter<ViewModelInstanceHandle>(
                                this,
                                rootHandle,
                                requestId,
                                CommandQueue::Message::viewModelError)
                                << "failed to find list at path " << path
                                << " when trying to add to a list";
                        }
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            rootHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "failed to find value view model " << viewHandle
                            << "isntance for add list";
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        rootHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "failed to find root view model isntance "
                        << rootHandle << "for add list";
                }

                break;
            }

            case CommandQueue::Command::removeViewModelListValue:
            {
                ViewModelInstanceHandle rootHandle;
                ViewModelInstanceHandle viewHandle;
                uint64_t requestId;
                std::string path;
                int index;
                commandStream >> rootHandle;
                commandStream >> viewHandle;
                commandStream >> index;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto root = getViewModelInstance(rootHandle))
                {
                    if (auto property = root->propertyList(path))
                    {
                        if (index >= 0)
                        {
                            property->removeInstanceAt(index);
                        }
                        else if (auto viewModel =
                                     getViewModelInstance(viewHandle))
                        {
                            property->removeInstance(viewModel);
                        }
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            rootHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "failed to find list on view model "
                               "isntance for "
                               "remove at path "
                            << path;
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        rootHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "failed to find view model instance " << rootHandle
                        << " for remove list";
                }

                break;
            }

            case CommandQueue::Command::swapViewModelListValue:
            {
                ViewModelInstanceHandle rootHandle;
                uint64_t requestId;
                std::string path;
                int indexa, indexb;
                commandStream >> rootHandle;
                commandStream >> indexa;
                commandStream >> indexb;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();
                if (auto viewModel = getViewModelInstance(rootHandle))
                {
                    if (auto list = viewModel->propertyList(path))
                    {
                        list->swap(indexa, indexb);
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            rootHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "failed to find list on view model "
                               "isntance for "
                               "swap at path "
                            << path;
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        rootHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "failed to find view model instance " << rootHandle
                        << " for swap";
                }
                break;
            }

            case CommandQueue::Command::subscribeViewModelProperty:
            case CommandQueue::Command::unsubscribeViewModelProperty:
            {
                ViewModelInstanceHandle rootHandle;
                PropertyData data;
                uint64_t requestId;
                commandStream >> rootHandle;
                commandStream >> data.type;
                commandStream >> requestId;
                m_commandQueue->m_names >> data.name;
                lock.unlock();

                if (command ==
                    CommandQueue::Command::subscribeViewModelProperty)
                {
                    // Validate that this is a valid thing to subscribe to.

                    if (auto view = getViewModelInstance(rootHandle))
                    {
                        if (data.type != DataType::viewModel &&
                            data.type != DataType::integer &&
                            data.type != DataType::none &&
                            data.type != DataType::symbolListIndex)
                        {
                            if (view->property(data.name) != nullptr)
                            {
                                m_propertySubscriptions.push_back(
                                    {requestId, data, rootHandle});
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    rootHandle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Property " << data.name
                                    << " not found when subscribing";
                            }
                        }
                        else
                        {
                            ErrorReporter<ViewModelInstanceHandle>(
                                this,
                                rootHandle,
                                requestId,
                                CommandQueue::Message::viewModelError)
                                << "Property type " << data.type
                                << " is not valid when subscribing";
                        }
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            rootHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "Root view model " << rootHandle
                            << " not found when subscribing "
                               "to property "
                            << data.name;
                    }
                }
                else
                {
                    auto itr = std::remove_if(
                        m_propertySubscriptions.begin(),
                        m_propertySubscriptions.end(),
                        [data, rootHandle](const Subscription& val) {
                            return val.data.name == data.name &&
                                   val.data.type == data.type &&
                                   val.rootViewModel == rootHandle;
                        });

                    m_propertySubscriptions.erase(
                        itr,
                        m_propertySubscriptions.end());
                }

                break;
            }

            case CommandQueue::Command::refNestedViewModel:
            {
                ViewModelInstanceHandle rootViewHandle;
                ViewModelInstanceHandle nestedViewHandle;
                uint64_t requestId;
                std::string path;
                commandStream >> rootViewHandle;
                commandStream >> nestedViewHandle;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto rootViewInstance =
                        getViewModelInstance(rootViewHandle))
                {
                    if (auto nestedViewModel =
                            rootViewInstance->propertyViewModel(path))
                    {
                        m_viewModels[nestedViewHandle] = nestedViewModel;
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            nestedViewHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "Nested view not found at path" << path
                            << " when refing nested "
                               "view model";
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        nestedViewHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Root view model " << rootViewHandle
                        << " not found when refing nested "
                           "view model at path "
                        << path;
                }
                break;
            }

            case CommandQueue::Command::refListViewModel:
            {
                ViewModelInstanceHandle rootViewHandle;
                ViewModelInstanceHandle listViewHandle;
                int index;
                uint64_t requestId;
                std::string path;
                commandStream >> rootViewHandle;
                commandStream >> index;
                commandStream >> listViewHandle;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto rootViewInstance =
                        getViewModelInstance(rootViewHandle))
                {
                    if (auto list = rootViewInstance->propertyList(path))
                    {
                        auto viewModelInstance = list->instanceAt(index);
                        if (viewModelInstance)
                        {
                            m_viewModels[listViewHandle] = viewModelInstance;
                        }
                        else
                        {
                            ErrorReporter<ViewModelInstanceHandle>(
                                this,
                                rootViewHandle,
                                requestId,
                                CommandQueue::Message::viewModelError)
                                << "View model not found on list " << path
                                << " at index " << index;
                        }
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            rootViewHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "List not found at path " << path
                            << " when refing  view model at index " << index;
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        rootViewHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Root view model" << rootViewHandle
                        << " not found when refing nested "
                           "view model at path "
                        << path;
                }
                break;
            }

            case CommandQueue::Command::deleteViewModel:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_viewModels.erase(handle);
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::viewModelDeleted;
                messageStream << handle;
                messageStream << requestId;
                break;
            }
            case CommandQueue::Command::instantiateStateMachine:
            {
                StateMachineHandle handle;
                ArtboardHandle artboardHandle;
                uint64_t requestId;
                std::string name;
                commandStream >> handle;
                commandStream >> artboardHandle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                if (rive::ArtboardInstance* artboard =
                        getArtboardInstance(artboardHandle))
                {
                    if (auto stateMachine =
                            name.empty() ? artboard->defaultStateMachine()
                                         : artboard->stateMachineNamed(name))
                    {
                        std::unique_lock<std::mutex> accesLock(
                            m_stateMachineAccessMutex);
                        m_stateMachines[handle] =
                            make_rcp<SynchronizedStateMachine>(
                                std::move(stateMachine));
                        accesLock.unlock();
                        assert(m_artboardDependencies.find(artboardHandle) !=
                               m_artboardDependencies.end());
                        m_artboardDependencies[artboardHandle].push_back(
                            handle);

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::stateMachineInstantiated;
                        messageStream << artboardHandle;
                        messageStream << handle;
                        messageStream << requestId;
                    }
                    else
                    {
                        ErrorReporter<ArtboardHandle>(
                            this,
                            artboardHandle,
                            requestId,
                            CommandQueue::Message::artboardError)
                            << "Could not create state "
                               "machine with name \""
                            << name << "\" because it was not found.";
                    }
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        artboardHandle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "Could not create state "
                           "machine with name \""
                        << name << "\" because the owning artboard "
                        << artboardHandle << " was not found.";
                }
                break;
            }

            case CommandQueue::Command::bindViewModelInstance:
            {
                StateMachineHandle handle;
                ViewModelInstanceHandle viewModel;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> viewModel;
                commandStream >> requestId;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    if (auto viewModelInstance =
                            getViewModelInstance(viewModel))
                    {
                        std::unique_lock<std::mutex> accesLock(
                            stateMachineWrapper->m_mutex);
                        stateMachineWrapper->instance->bindViewModelInstance(
                            viewModelInstance->instance());
                    }
                    else
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "View model instance " << viewModel
                            << " not found for when trying to bind "
                               "to a state machine";
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for binding view model.";
                }
                break;
            }

            case CommandQueue::Command::setViewModelInstance:
            {
                StateMachineHandle handle;
                ViewModelInstanceHandle viewModel;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> viewModel;
                commandStream >> requestId;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    if (auto viewModelInstance =
                            getViewModelInstance(viewModel))
                    {
                        std::unique_lock<std::mutex> accesLock(
                            stateMachineWrapper->m_mutex);
                        stateMachineWrapper->instance->setViewModelInstance(
                            viewModelInstance->instance());
                    }
                    else
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "View model instance " << viewModel
                            << " not found when trying to set the main view "
                               "model instance on a state machine";
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for setting view model instance.";
                }
                break;
            }

            case CommandQueue::Command::setGlobalViewModelInstance:
            {
                StateMachineHandle handle;
                ViewModelInstanceHandle viewModel;
                uint64_t requestId;
                std::string name;
                commandStream >> handle;
                commandStream >> viewModel;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    if (auto viewModelInstance =
                            getViewModelInstance(viewModel))
                    {
                        std::unique_lock<std::mutex> accesLock(
                            stateMachineWrapper->m_mutex);
                        if (!stateMachineWrapper->instance
                                 ->setGlobalViewModelInstance(
                                     name,
                                     viewModelInstance->instance()))
                        {
                            ErrorReporter<StateMachineHandle>(
                                this,
                                handle,
                                requestId,
                                CommandQueue::Message::stateMachineError)
                                << "Could not set global view model instance "
                                << viewModel << " under name " << name
                                << " on a state machine";
                        }
                    }
                    else
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "View model instance " << viewModel
                            << " not found when trying to set a global view "
                               "model instance on a state machine";
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for setting global view model instance.";
                }
                break;
            }

            case CommandQueue::Command::getGlobalViewModelInstance:
            {
                StateMachineHandle handle;
                ViewModelInstanceHandle viewHandle;
                uint64_t requestId;
                std::string name;
                commandStream >> handle;
                commandStream >> viewHandle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    rcp<ViewModelInstance> viewModelInstance;
                    {
                        std::unique_lock<std::mutex> accesLock(
                            stateMachineWrapper->m_mutex);
                        viewModelInstance = stateMachineWrapper->instance
                                                ->globalViewModelInstance(name);
                    }
                    if (viewModelInstance != nullptr)
                    {
                        m_viewModels[viewHandle] =
                            make_rcp<ViewModelInstanceRuntime>(
                                viewModelInstance);
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            viewHandle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "No global view model instance bound under name "
                            << name << " on a state machine";
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        viewHandle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "State machine " << handle
                        << " not found for getting global view model instance.";
                }
                break;
            }

            case CommandQueue::Command::bind:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> accesLock(
                        stateMachineWrapper->m_mutex);
                    stateMachineWrapper->instance->bind();
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for binding data context.";
                }
                break;
            }

            case CommandQueue::Command::advanceStateMachine:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                float timeToAdvance;
                commandStream >> handle;
                commandStream >> requestId;
                commandStream >> timeToAdvance;
                lock.unlock();

                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> advanceLock(wrapper->m_mutex);
                    if (!wrapper->instance->advanceAndApply(timeToAdvance))
                    {
                        advanceLock.unlock();
                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::stateMachineSettled;
                        messageStream << handle;
                        messageStream << requestId;
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for "
                           "advance.";
                }

                break;
            }

            case CommandQueue::Command::deleteStateMachine:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto it = m_stateMachines.find(handle);
                if (it != m_stateMachines.end())
                {
                    std::unique_lock<std::mutex> accesLock(
                        m_stateMachineAccessMutex);
                    m_stateMachines.erase(it);
                    accesLock.unlock();
                }
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::stateMachineDeleted;
                messageStream << handle;
                messageStream << requestId;
                // We don't remove from the artboard dependencies here because
                // calling erase on a non existent key is fine.
                break;
            }

            case CommandQueue::Command::enableSemantics:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> stateMachineLock(
                        wrapper->m_mutex);
                    wrapper->instance->enableSemantics();
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for enableSemantics.";
                }
                break;
            }

            case CommandQueue::Command::drainSemanticsDiff:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                Fit fit;
                float alignmentX;
                float alignmentY;
                float scaleFactor;
                Vec2D viewBounds;
                commandStream >> handle;
                commandStream >> requestId;
                commandStream >> fit;
                commandStream >> alignmentX;
                commandStream >> alignmentY;
                commandStream >> scaleFactor;
                commandStream >> viewBounds;
                lock.unlock();
                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> stateMachineLock(
                        wrapper->m_mutex);
                    auto* manager = wrapper->instance->semanticManager();
                    if (manager == nullptr)
                    {
                        stateMachineLock.unlock();
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "Semantics not enabled on state machine "
                            << handle
                            << "; call enableSemantics before "
                               "drainSemanticsDiff.";
                    }
                    else
                    {
                        SemanticsDiff diff = manager->drainDiff();
                        if (!diff.empty())
                        {
                            // Compute the transform while locked (it reads the
                            // artboard); identity means no mapping.
                            Mat2D transform;
                            if (auto* artboard = wrapper->instance->artboard())
                            {
                                AABB artboardBounds = artboard->bounds();
                                AABB surfaceBounds =
                                    AABB(Vec2D{0.0f, 0.0f}, viewBounds);
                                if (surfaceBounds.width() != 0.0f &&
                                    surfaceBounds.height() != 0.0f)
                                {
                                    Alignment alignment(alignmentX, alignmentY);
                                    transform =
                                        rive::computeAlignment(fit,
                                                               alignment,
                                                               surfaceBounds,
                                                               artboardBounds,
                                                               scaleFactor);
                                }
                            }

                            // Map the owned diff outside the lock.
                            stateMachineLock.unlock();
                            if (transform != Mat2D())
                            {
                                mapSemanticsDiffToViewSpace(diff, transform);
                            }

                            std::unique_lock<std::mutex> messageLock(
                                m_commandQueue->m_messageMutex);
                            messageStream
                                << CommandQueue::Message::semanticsDiffReceived;
                            messageStream << handle;
                            messageStream << requestId;
                            m_commandQueue->m_messageSemanticsDiffs
                                << std::move(diff);
                        }
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for drainSemanticsDiff.";
                }
                break;
            }

            case CommandQueue::Command::fireSemanticAction:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                uint32_t semanticNodeId;
                SemanticActionType actionType;
                commandStream >> handle;
                commandStream >> requestId;
                commandStream >> semanticNodeId;
                commandStream >> actionType;
                lock.unlock();
                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> stateMachineLock(
                        wrapper->m_mutex);
                    if (wrapper->instance->semanticManager() == nullptr)
                    {
                        stateMachineLock.unlock();
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "Semantics not enabled on state machine "
                            << handle
                            << "; call enableSemantics before "
                               "fireSemanticAction.";
                    }
                    else
                    {
                        wrapper->instance->fireSemanticAction(semanticNodeId,
                                                              actionType);
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for fireSemanticAction.";
                }
                break;
            }

            case CommandQueue::Command::requestSemanticFocus:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                uint32_t semanticNodeId;
                commandStream >> handle;
                commandStream >> requestId;
                commandStream >> semanticNodeId;
                lock.unlock();
                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> stateMachineLock(
                        wrapper->m_mutex);
                    auto* manager = wrapper->instance->semanticManager();
                    if (manager == nullptr)
                    {
                        stateMachineLock.unlock();
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "Semantics not enabled on state machine "
                            << handle
                            << "; call enableSemantics before "
                               "requestSemanticFocus.";
                    }
                    else
                    {
                        // A missing/non-focusable node is a silent no-op.
                        manager->requestFocus(semanticNodeId);
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for requestSemanticFocus.";
                }
                break;
            }

            case CommandQueue::Command::clearSemanticFocus:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                if (auto wrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> stateMachineLock(
                        wrapper->m_mutex);
                    if (auto* focusManager = wrapper->instance->focusManager())
                    {
                        focusManager->clearFocus();
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for clearSemanticFocus.";
                }
                break;
            }

            case CommandQueue::Command::runOnce:
            {
                CommandServerCallback callback;
                m_commandQueue->m_callbacks >> callback;
                lock.unlock();
                callback(this);
                break;
            }

            case CommandQueue::Command::draw:
            {
                DrawKey drawKey;
                CommandServerDrawCallback drawCallback;
                commandStream >> drawKey;
                m_commandQueue->m_drawCallbacks >> drawCallback;
                lock.unlock();
                m_uniqueDraws[drawKey] = std::move(drawCallback);
                break;
            }

            case CommandQueue::Command::cancelDraw:
            {
                DrawKey drawKey;
                commandStream >> drawKey;
                lock.unlock();
                m_uniqueDraws.erase(drawKey);
                break;
            }

            case CommandQueue::Command::commandLoopBreak:
            {
                lock.unlock();
                shouldProcessCommands = false;
                break;
            }

            case CommandQueue::Command::listArtboards:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto artboards = file->artboards();

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::artboardsListed;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << artboards.size();
                    for (auto artboard : artboards)
                    {
                        m_commandQueue->m_messageNames << artboard->name();
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of artboards";
                }

                break;
            }

            case CommandQueue::Command::listFileAssets:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto fileAssets = file->assets();

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::fileAssetsListed;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << fileAssets.size();
                    for (const auto& asset : fileAssets)
                    {
                        messageStream << asset->assetId();
                        messageStream << asset->coreType();
                        m_commandQueue->m_messageNames << asset->name();
                        m_commandQueue->m_messageNames << asset->cdnUuidStr();
                        m_commandQueue->m_messageNames << asset->cdnBaseUrl();
                        m_commandQueue->m_messageNames
                            << asset->fileExtension();
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of file assets";
                }

                break;
            }

            case CommandQueue::Command::getViewModelInstanceViewModelName:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto viewModelInstance = getViewModelInstance(handle);
                if (viewModelInstance)
                {
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::
                            viewModelInstanceViewModelNameReceived;
                    messageStream << handle;
                    messageStream << requestId;
                    m_commandQueue->m_messageNames
                        << viewModelInstance->viewModelName();
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Invalid view model instance handle " << handle;
                }
                break;
            }

            case CommandQueue::Command::getViewModelInstanceName:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto viewModelInstance = getViewModelInstance(handle);
                if (viewModelInstance)
                {
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream
                        << CommandQueue::Message::viewModelInstanceNameReceived;
                    messageStream << handle;
                    messageStream << requestId;
                    m_commandQueue->m_messageNames << viewModelInstance->name();
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Invalid view model instance handle " << handle;
                }
                break;
            }

            case CommandQueue::Command::listViewModelEnums:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto enums = file->enums();
                    std::vector<ViewModelEnum> enumDatas;

                    for (auto tenum : enums)
                    {
                        ViewModelEnum data;
                        data.name = tenum->enumName();
                        auto values = tenum->values();
                        for (auto value : values)
                        {
                            data.enumerants.push_back(value->key());
                        }

                        enumDatas.push_back(data);
                    }

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream
                        << CommandQueue::Message::viewModelEnumsListed;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << enumDatas.size();
                    for (auto& enumData : enumDatas)
                    {
                        m_commandQueue->m_messageNames << enumData.name;
                        messageStream << enumData.enumerants.size();
                        for (auto& enumValueName : enumData.enumerants)
                            m_commandQueue->m_messageNames << enumValueName;
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of enums";
                }
                break;
            }

            case CommandQueue::Command::listStateMachines:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto artboard = getArtboardInstance(handle);
                if (artboard)
                {
                    auto numStateMachines = artboard->stateMachineCount();
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::stateMachinesListed;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << numStateMachines;
                    for (int i = 0; i < numStateMachines; ++i)
                    {
                        m_commandQueue->m_messageNames
                            << artboard->stateMachineNameAt(i);
                    }
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "Invalid artboard handle " << handle
                        << " when getting list of state machines";
                }
                break;
            }

            case CommandQueue::Command::getArtboardSize:
            {
                ArtboardHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto artboard = getArtboardInstance(handle);
                if (artboard)
                {
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream
                        << CommandQueue::Message::artboardSizeReceived;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << artboard->width();
                    messageStream << artboard->height();
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "Invalid artboard handle " << handle
                        << " when getting artboard size";
                }
                break;
            }

            case CommandQueue::Command::getDefaultViewModel:
            {
                FileHandle fileHandle;
                ArtboardHandle artboardHandle;
                uint64_t requestId;
                commandStream >> fileHandle;
                commandStream >> artboardHandle;
                commandStream >> requestId;
                lock.unlock();
                auto artboard = getArtboardInstance(artboardHandle);
                if (artboard)
                {
                    auto file = getFile(fileHandle);
                    if (file)
                    {
                        auto defaultViewModel =
                            file->defaultArtboardViewModel(artboard);

                        if (defaultViewModel)
                        {
                            auto defaultInstance =
                                defaultViewModel->createDefaultInstance();
                            if (defaultInstance)
                            {
                                std::unique_lock<std::mutex> messageLock(
                                    m_commandQueue->m_messageMutex);
                                messageStream << CommandQueue::Message::
                                        defaultViewModelReceived;
                                messageStream << artboardHandle;
                                messageStream << requestId;
                                m_commandQueue->m_messageNames
                                    << defaultViewModel->name();
                                m_commandQueue->m_messageNames
                                    << defaultInstance->name();
                            }
                            else
                            {
                                ErrorReporter<ArtboardHandle>(
                                    this,
                                    artboardHandle,
                                    requestId,
                                    CommandQueue::Message::artboardError)
                                    << "Could not find default view model "
                                       "instance for "
                                       "artboard"
                                    << " when getting default view model info";
                            }
                        }
                        else
                        {
                            ErrorReporter<ArtboardHandle>(
                                this,
                                artboardHandle,
                                requestId,
                                CommandQueue::Message::artboardError)
                                << "Could not find default view model for "
                                   "artboard"
                                << " when getting default view model info";
                        }
                    }
                    else
                    {
                        ErrorReporter<ArtboardHandle>(
                            this,
                            artboardHandle,
                            requestId,
                            CommandQueue::Message::artboardError)
                            << "Invalid file handle " << fileHandle
                            << " when getting default view model info";
                    }
                }
                else
                {
                    ErrorReporter<ArtboardHandle>(
                        this,
                        artboardHandle,
                        requestId,
                        CommandQueue::Message::artboardError)
                        << "Invalid artboard handle " << artboardHandle
                        << " when getting default view model info";
                }
                break;
            }

            case CommandQueue::Command::listViewModels:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto numViewModels = file->viewModelCount();

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::viewModelsListend;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << numViewModels;
                    for (int i = 0; i < numViewModels; ++i)
                    {
                        m_commandQueue->m_messageNames
                            << file->viewModelByIndex(i)->name();
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of view models";
                }
                break;
            }

            case CommandQueue::Command::listGlobalViewModelNames:
            {
                FileHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto names = file->globalViewModelNames();

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream
                        << CommandQueue::Message::globalViewModelNamesListed;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << names.size();
                    for (auto& name : names)
                    {
                        m_commandQueue->m_messageNames << name;
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of global view models";
                }
                break;
            }

            case CommandQueue::Command::listViewModelInstanceNames:
            {
                FileHandle handle;
                uint64_t requestId;
                std::string viewModelName;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> viewModelName;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto model = file->viewModelByName(viewModelName);
                    if (model)
                    {
                        auto names = model->instanceNames();

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream << CommandQueue::Message::
                                viewModelInstanceNamesListed;
                        messageStream << handle;
                        messageStream << requestId;
                        messageStream << names.size();
                        m_commandQueue->m_messageNames << viewModelName;
                        for (auto& name : names)
                        {
                            m_commandQueue->m_messageNames << name;
                        }
                    }
                    else
                    {
                        ErrorReporter<FileHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "Invalid view model name " << viewModelName
                            << " when getting list of view model instance "
                               "names";
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Invalid file handle " << handle
                        << " when getting list of view model instance names";
                }
                break;
            }

            case CommandQueue::Command::listViewModelProperties:
            {
                FileHandle handle;
                uint64_t requestId;
                std::string viewModelName;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> viewModelName;
                lock.unlock();
                auto file = getFile(handle);
                if (file)
                {
                    auto model = file->viewModelByName(viewModelName);
                    if (model)
                    {
                        // Used to get meta data about enums.
                        auto modelInstance = model->createDefaultInstance();
                        auto properties = model->properties();

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::viewModelPropertiesListed;
                        messageStream << handle;
                        messageStream << requestId;
                        messageStream << properties.size();
                        m_commandQueue->m_messageNames << viewModelName;
                        for (auto& property : properties)
                        {
                            messageStream << property.type;
                            m_commandQueue->m_messageNames << property.name;
                            if (property.type == DataType::enumType)
                            {
                                auto enumProperty =
                                    modelInstance->propertyEnum(property.name);
                                m_commandQueue->m_messageNames
                                    << enumProperty->enumType();
                            }
                            if (property.type == DataType::viewModel)
                            {
                                // Get the type of the view model property
                                auto viewModelTmp =
                                    modelInstance->propertyViewModel(
                                        property.name);
                                if (viewModelTmp)
                                {
                                    m_commandQueue->m_messageNames
                                        << viewModelTmp->instance()
                                               ->viewModel()
                                               ->name();
                                }
                                else
                                {
                                    // If we can't determine the name we still
                                    // need to send something because the
                                    // command queue is expecting a name.
                                    m_commandQueue->m_messageNames << "Unkown";
                                }
                            }
                        }
                    }
                    else
                    {
                        ErrorReporter<FileHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::fileError)
                            << "Invalid view model name " << viewModelName
                            << " when getting list of view model properties";
                    }
                }
                else
                {
                    ErrorReporter<FileHandle>(this,
                                              handle,
                                              requestId,
                                              CommandQueue::Message::fileError)
                        << "Invalid file handle " << handle
                        << " when getting list of view model properties";
                }
                break;
            }

            case CommandQueue::Command::setViewModelInstanceValue:
            {
                ViewModelInstanceHandle handle = RIVE_NULL_HANDLE;
                ViewModelInstanceHandle nestedHandle = RIVE_NULL_HANDLE;
                RenderImageHandle imageHandle = RIVE_NULL_HANDLE;
                ArtboardHandle artboardHandle = RIVE_NULL_HANDLE;
                uint64_t requestId;
                CommandQueue::ViewModelInstanceData value;

                commandStream >> handle;
                commandStream >> value.metaData.type;
                commandStream >> requestId;
                m_commandQueue->m_names >> value.metaData.name;

                switch (value.metaData.type)
                {
                    // Triggers are valid but have no data.
                    case DataType::trigger:
                        break;
                    case DataType::boolean:
                        commandStream >> value.boolValue;
                        break;
                    case DataType::number:
                        commandStream >> value.numberValue;
                        break;
                    case DataType::color:
                        commandStream >> value.colorValue;
                        break;
                    case DataType::string:
                    case DataType::enumType:
                        m_commandQueue->m_names >> value.stringValue;
                        break;
                    case DataType::viewModel:
                        commandStream >> nestedHandle;
                        break;
                    case DataType::assetImage:
                        commandStream >> imageHandle;
                        break;
                    case DataType::artboard:
                        commandStream >> artboardHandle;
                        break;
                    default:
                        RIVE_UNREACHABLE();
                }
                lock.unlock();

                if (auto viewModelInstance = getViewModelInstance(handle))
                {
                    switch (value.metaData.type)
                    {
                        case DataType::trigger:
                        {
                            if (auto property =
                                    viewModelInstance->propertyTrigger(
                                        value.metaData.name))
                            {
                                property->trigger();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::boolean:
                        {
                            if (auto property =
                                    viewModelInstance->propertyBoolean(
                                        value.metaData.name))
                            {
                                property->value(value.boolValue);
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::number:
                        {
                            if (auto property =
                                    viewModelInstance->propertyNumber(
                                        value.metaData.name))
                            {
                                property->value(value.numberValue);
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::color:
                        {
                            if (auto property =
                                    viewModelInstance->propertyColor(
                                        value.metaData.name))
                            {
                                property->value(value.colorValue);
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::string:
                        {
                            if (auto property =
                                    viewModelInstance->propertyString(
                                        value.metaData.name))
                            {
                                property->value(value.stringValue);
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::enumType:
                        {
                            if (auto property = viewModelInstance->propertyEnum(
                                    value.metaData.name))
                            {
                                // As far as I can tell, there is no built in
                                // way to do this from the core runtime. So we
                                // just verify manually ourselves.
                                auto values = property->values();
                                if (std::find(values.begin(),
                                              values.end(),
                                              value.stringValue) !=
                                    values.end())
                                {
                                    property->value(value.stringValue);
                                }
                                else
                                {
                                    ErrorReporter<ViewModelInstanceHandle>(
                                        this,
                                        handle,
                                        requestId,
                                        CommandQueue::Message::viewModelError)
                                        << "Invalid enum value for "
                                           "property "
                                        << value.metaData.name
                                        << " when trying to set enum to "
                                        << value.stringValue
                                        << " possible values " << values;
                                }
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when setting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::viewModel:
                        {
                            if (auto nestedViewModel =
                                    getViewModelInstance(nestedHandle))
                            {
                                if (!viewModelInstance->replaceViewModel(
                                        value.metaData.name,
                                        nestedViewModel))
                                {
                                    ErrorReporter<ViewModelInstanceHandle>(
                                        this,
                                        handle,
                                        requestId,
                                        CommandQueue::Message::viewModelError)
                                        << "Could not replace "
                                           "view model at path "
                                        << value.metaData.name;
                                }
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find nested view "
                                       "model "
                                       "with handle "
                                    << nestedHandle
                                    << " to set for view model instance when "
                                       "setting property with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::assetImage:
                        {
                            if (auto imageProperty =
                                    viewModelInstance->propertyImage(
                                        value.metaData.name))
                            {
                                if (imageHandle == RIVE_NULL_HANDLE)
                                {
                                    imageProperty->value(nullptr);
                                }
                                else if (auto image = getImage(imageHandle))
                                {
                                    imageProperty->value(image);
                                }
                                else
                                {
                                    ErrorReporter<ViewModelInstanceHandle>(
                                        this,
                                        handle,
                                        requestId,
                                        CommandQueue::Message::viewModelError)
                                        << "Could not find image "
                                        << imageHandle
                                        << " to set for view model instance "
                                           "when setting property with path "
                                        << value.metaData.name;
                                }
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find "
                                       "image property at path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::artboard:
                        {
                            if (auto artboardProperty =
                                    viewModelInstance->propertyArtboard(
                                        value.metaData.name))
                            {
                                if (artboardHandle == RIVE_NULL_HANDLE)
                                {
                                    artboardProperty->value(nullptr);
                                }
                                else if (auto bindableArtboard =
                                             getBindableArtboard(
                                                 artboardHandle))
                                {
                                    artboardProperty->value(bindableArtboard);
                                }
                                else
                                {
                                    ErrorReporter<ViewModelInstanceHandle>(
                                        this,
                                        handle,
                                        requestId,
                                        CommandQueue::Message::viewModelError)
                                        << "Could not find artboard "
                                        << artboardHandle
                                        << " to set for view model instance "
                                           "when setting property with path "
                                        << value.metaData.name;
                                }
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find "
                                       "artboard property at path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        default:
                            RIVE_UNREACHABLE();
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Could not find view model instance when "
                           "setting property type "
                        << value.metaData.type << " with path "
                        << value.metaData.name;
                }
                break;
            }

            case CommandQueue::Command::listViewModelPropertyValue:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                CommandQueue::ViewModelInstanceData value;
                commandStream >> value.metaData.type;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> value.metaData.name;
                lock.unlock();

                if (auto viewModelInstance = getViewModelInstance(handle))
                {
                    switch (value.metaData.type)
                    {
                        case DataType::boolean:
                        {
                            if (auto property =
                                    viewModelInstance->propertyBoolean(
                                        value.metaData.name))
                            {
                                value.boolValue = property->value();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when getting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::number:
                        {
                            if (auto property =
                                    viewModelInstance->propertyNumber(
                                        value.metaData.name))
                            {
                                value.numberValue = property->value();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when getting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::color:
                        {
                            if (auto property =
                                    viewModelInstance->propertyColor(
                                        value.metaData.name))
                            {
                                value.colorValue = property->value();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when getting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::string:
                        {
                            if (auto property =
                                    viewModelInstance->propertyString(
                                        value.metaData.name))
                            {
                                value.stringValue = property->value();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when getting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        case DataType::enumType:
                        {
                            if (auto property = viewModelInstance->propertyEnum(
                                    value.metaData.name))
                            {
                                value.stringValue = property->value();
                            }
                            else
                            {
                                ErrorReporter<ViewModelInstanceHandle>(
                                    this,
                                    handle,
                                    requestId,
                                    CommandQueue::Message::viewModelError)
                                    << "Could not find view model "
                                       "property "
                                       "instance when getting property type "
                                    << value.metaData.type << " with path "
                                    << value.metaData.name;
                            }
                            break;
                        }
                        default:
                            RIVE_UNREACHABLE();
                    }

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::
                            viewModelPropertyValueReceived;
                    messageStream << handle;
                    messageStream << value.metaData.type;
                    m_commandQueue->m_messageNames << value.metaData.name;
                    messageStream << requestId;
                    switch (value.metaData.type)
                    {
                        case DataType::boolean:
                            messageStream << value.boolValue;
                            break;
                        case DataType::number:
                            messageStream << value.numberValue;
                            break;
                        case DataType::color:
                            messageStream << value.colorValue;
                            break;
                        case DataType::enumType:
                        case DataType::string:
                            m_commandQueue->m_messageNames << value.stringValue;
                            break;
                        default:
                            RIVE_UNREACHABLE();
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "Could not find view model instance when "
                           "getting property type "
                        << value.metaData.type << " with path "
                        << value.metaData.name;
                }
                break;
            }

            case CommandQueue::Command::getViewModelListSize:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                std::string path;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto viewModel = getViewModelInstance(handle))
                {
                    if (auto property = viewModel->propertyList(path))
                    {
                        auto size = property->size();
                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::viewModelListSizeReceived;
                        messageStream << handle;
                        messageStream << size;
                        messageStream << requestId;
                        m_commandQueue->m_messageNames << path;
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "failed to get list at path " << path
                            << " when getting list size";
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "failed to get view model " << handle
                        << " when getting list size";
                }

                break;
            }

            case CommandQueue::Command::clearViewModelList:
            {
                ViewModelInstanceHandle handle;
                uint64_t requestId;
                std::string path;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> path;
                lock.unlock();

                if (auto viewModel = getViewModelInstance(handle))
                {
                    if (auto property = viewModel->propertyList(path))
                    {
                        property->removeAllInstances();

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream
                            << CommandQueue::Message::viewModelListCleared;
                        messageStream << handle;
                        messageStream << requestId;
                        m_commandQueue->m_messageNames << path;
                        messageLock.unlock();
                    }
                    else
                    {
                        ErrorReporter<ViewModelInstanceHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::viewModelError)
                            << "failed to get list at path " << path
                            << " when clearing list";
                    }
                }
                else
                {
                    ErrorReporter<ViewModelInstanceHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::viewModelError)
                        << "failed to get view model " << handle
                        << " when clearing list";
                }
                break;
            }

            case CommandQueue::Command::pointerMove:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_pointerEvents >> pointerEvent;
                lock.unlock();
                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    Vec2D position = cursorPosForPointerEvent(
                        stateMachineWrapper->instance.get(),
                        pointerEvent);
                    std::unique_lock<std::mutex> stateMachineLock(
                        stateMachineWrapper->m_mutex);
                    stateMachineWrapper->instance->pointerMove(
                        position,
                        0.0f,
                        pointerEvent.pointerId);
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine \"" << handle
                        << "\" not found for pointerMove.";
                }
                break;
            }

            case CommandQueue::Command::pointerDown:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_pointerEvents >> pointerEvent;
                lock.unlock();
                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    Vec2D position = cursorPosForPointerEvent(
                        stateMachineWrapper->instance.get(),
                        pointerEvent);
                    std::unique_lock<std::mutex> stateMachineLock(
                        stateMachineWrapper->m_mutex);
                    auto hitResult = stateMachineWrapper->instance->pointerDown(
                        position,
                        pointerEvent.pointerId);
                    // Process down-driven state changes before a following
                    // pointer up.
                    if (hitResult != HitResult::none)
                    {
                        stateMachineWrapper->instance->advanceAndApply(0.0f);
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine \"" << handle
                        << "\" not found for pointerDown.";
                }
                break;
            }

            case CommandQueue::Command::pointerUp:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_pointerEvents >> pointerEvent;
                lock.unlock();
                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    Vec2D position = cursorPosForPointerEvent(
                        stateMachineWrapper->instance.get(),
                        pointerEvent);
                    std::unique_lock<std::mutex> stateMachineLock(
                        stateMachineWrapper->m_mutex);
                    auto hitResult = stateMachineWrapper->instance->pointerUp(
                        position,
                        pointerEvent.pointerId);
                    // Process up-driven state changes before any following
                    // pointer exit.
                    if (hitResult != HitResult::none)
                    {
                        stateMachineWrapper->instance->advanceAndApply(0.0f);
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine \"" << handle
                        << "\" not found for pointerUp.";
                }
                break;
            }

            case CommandQueue::Command::pointerExit:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_pointerEvents >> pointerEvent;
                lock.unlock();
                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    Vec2D position = cursorPosForPointerEvent(
                        stateMachineWrapper->instance.get(),
                        pointerEvent);
                    std::unique_lock<std::mutex> stateMachineLock(
                        stateMachineWrapper->m_mutex);
                    stateMachineWrapper->instance->pointerExit(
                        position,
                        pointerEvent.pointerId);
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine \"" << handle
                        << "\" not found for pointerExit.";
                }
                break;
            }

            case CommandQueue::Command::addImageFileAsset:
            {
                RenderImageHandle handle;
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                if (handle && getImage(handle) != nullptr)
                {
                    m_fileAssetLoader->addRenderImage(std::move(name), handle);
                }
                break;
            }

            case CommandQueue::Command::removeImageFileAsset:
            {
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                m_fileAssetLoader->removeRenderImage(std::move(name));
                break;
            }

            case CommandQueue::Command::addAudioFileAsset:
            {
                AudioSourceHandle handle;
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                if (handle && getAudioSource(handle) != nullptr)
                {
                    m_fileAssetLoader->addAudioSource(std::move(name), handle);
                }
                break;
            }

            case CommandQueue::Command::removeAudioFileAsset:
            {
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                m_fileAssetLoader->removeAudioSource(std::move(name));
                break;
            }

            case CommandQueue::Command::addFontFileAsset:
            {
                FontHandle handle;
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                if (handle && getFont(handle) != nullptr)
                {
                    m_fileAssetLoader->addFont(std::move(name), handle);
                }
                break;
            }

            case CommandQueue::Command::removeFontFileAsset:
            {
                std::string name;
                uint64_t requestId;
                CommandQueue::PointerEvent pointerEvent;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();
                m_fileAssetLoader->removeFont(std::move(name));
                break;
            }

            case CommandQueue::Command::disconnect:
            {
                lock.unlock();
                m_wasDisconnectReceived = true;
                return false;
            }
        }

        // Should have unlocked by now.
        assert(!lock.owns_lock());
        lock.lock();
    } while (!commandStream.empty() && shouldProcessCommands);

    // Since we always retake the lock at the end of the do while we need to
    // unlock here.
    lock.unlock();

    for (const auto& drawPair : m_uniqueDraws)
    {
        drawPair.second(drawPair.first, this);
    }

    m_uniqueDraws.clear();

    checkPropertySubscriptions();

    return !m_wasDisconnectReceived;
}
CommandServer::SynchronizedStateMachine::~SynchronizedStateMachine()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    instance->dispose();
}
}; // namespace rive
