/*
 * Copyright 2025 Rive
 */

#include "rive/command_server.hpp"

#include "rive/animation/state_machine_instance.hpp"
#include "rive/assets/audio_asset.hpp"
#include "rive/assets/blob_asset.hpp"
#include "rive/assets/font_asset.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/assets/manifest_asset.hpp"
#include "rive/assets/script_module_asset.hpp"
#include "rive/assets/text_asset.hpp"
#include "rive/file.hpp"
#include "rive/semantic/semantic_manager.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#ifdef WITH_RIVE_SCRIPTING_LUAU
#include "rive/lua/rive_lua_libs.hpp"
#endif

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<TextAsset>() || asset.is<ScriptModuleAsset>() ||
                 asset.is<BlobAsset>() || asset.is<ManifestAsset>())
        {
            // These assets cannot be registered externally with the command
            // server. Returning false lets the importer decode their in-band
            // contents. TextAsset includes ScriptAsset and ShaderAsset.
            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;
        case DataType::assetBlob:
            os << "Asset Blob";
            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;
}

BlobAsset* CommandServer::getBlob(BlobAssetHandle handle) const
{
    assert(std::this_thread::get_id() == m_threadID);
    auto it = m_blobs.find(handle);
    return it != m_blobs.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::assetBlob:
                        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::assetBlob:
                        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();
#if defined(WITH_RIVE_SCRIPTING) && defined(WITH_RIVE_SCRIPTING_LUAU)
                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);
                }
                auto vm = make_rcp<ScriptingVM>(std::move(scriptingContext));
                rcp<rive::File> file = rive::File::import(rivBytes,
                                                          m_factory,
                                                          nullptr,
                                                          m_fileAssetLoader,
                                                          vm.get());

#else
#ifdef WITH_RIVE_SCRIPTING
                // Wasm script modules need no host-created VM; the factory
                // only serves the Luau backend.
                (void)scriptingContextFactory;
#endif
                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::decodeBlob:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                std::vector<uint8_t> bytes;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_byteVectors >> bytes;
                lock.unlock();

                auto blob = make_rcp<BlobAsset>();
                SimpleArray<uint8_t> blobBytes(bytes.data(), bytes.size());
                if (blob->decode(blobBytes, m_factory))
                {
                    m_blobs[handle] = std::move(blob);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::blobDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<BlobAssetHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::blobError)
                        << "Command Server failed to decode blob";
                }

                break;
            }

            case CommandQueue::Command::externalBlob:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                rcp<BlobAsset> blob;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_externalBlobs >> blob;
                lock.unlock();

                if (blob)
                {
                    m_blobs[handle] = std::move(blob);
                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::blobDecoded;
                    messageStream << handle;
                    messageStream << requestId;
                }
                else
                {
                    ErrorReporter<BlobAssetHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::blobError)
                        << "External blob was empty";
                }

                break;
            }

            case CommandQueue::Command::deleteBlob:
            {
                BlobAssetHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();
                m_blobs.erase(handle);
                std::unique_lock<std::mutex> messageLock(
                    m_commandQueue->m_messageMutex);
                messageStream << CommandQueue::Message::blobDeleted;
                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;

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        FileHandle fileHandle = RIVE_NULL_HANDLE;
                        messageStream << CommandQueue::Message::
                                viewModelInstanceInstantiated;
                        messageStream << fileHandle;
                        messageStream << nestedViewHandle;
                        messageStream << requestId;
                    }
                    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;

                            std::unique_lock<std::mutex> messageLock(
                                m_commandQueue->m_messageMutex);
                            FileHandle fileHandle = RIVE_NULL_HANDLE;
                            messageStream << CommandQueue::Message::
                                    viewModelInstanceInstantiated;
                            messageStream << fileHandle;
                            messageStream << listViewHandle;
                            messageStream << requestId;
                        }
                        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::clearViewModelInstance:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                commandStream >> handle;
                commandStream >> requestId;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> accessLock(
                        stateMachineWrapper->m_mutex);
                    if (auto dataContext =
                            stateMachineWrapper->instance->dataContext())
                    {
                        dataContext->setMainViewModelInstance(nullptr);
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for clearing 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::clearGlobalViewModelInstance:
            {
                StateMachineHandle handle;
                uint64_t requestId;
                std::string name;
                commandStream >> handle;
                commandStream >> requestId;
                m_commandQueue->m_names >> name;
                lock.unlock();

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    std::unique_lock<std::mutex> accessLock(
                        stateMachineWrapper->m_mutex);
                    if (!stateMachineWrapper->instance
                             ->setGlobalViewModelInstance(name, nullptr))
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "Could not clear global view model instance "
                            << "under name " << name << " on a state machine";
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for clearing 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);

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream << CommandQueue::Message::
                                stateMachineViewModelInstanceReceived;
                        messageStream << handle;
                        messageStream << viewHandle;
                        messageStream << requestId;
                    }
                    else
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "No global view model instance named " << name
                            << " bound to state machine " << handle;
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for getting global view model instance.";
                }
                break;
            }

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

                if (auto stateMachineWrapper = getStateMachineWrapper(handle))
                {
                    rcp<ViewModelInstance> viewModelInstance;
                    {
                        std::unique_lock<std::mutex> accessLock(
                            stateMachineWrapper->m_mutex);
                        if (auto dataContext =
                                stateMachineWrapper->instance->dataContext())
                        {
                            viewModelInstance =
                                dataContext->mainViewModelInstance();
                        }
                    }
                    if (viewModelInstance != nullptr)
                    {
                        m_viewModels[viewHandle] =
                            make_rcp<ViewModelInstanceRuntime>(
                                viewModelInstance);

                        std::unique_lock<std::mutex> messageLock(
                            m_commandQueue->m_messageMutex);
                        messageStream << CommandQueue::Message::
                                stateMachineViewModelInstanceReceived;
                        messageStream << handle;
                        messageStream << viewHandle;
                        messageStream << requestId;
                    }
                    else
                    {
                        ErrorReporter<StateMachineHandle>(
                            this,
                            handle,
                            requestId,
                            CommandQueue::Message::stateMachineError)
                            << "No main view model instance bound to state "
                               "machine "
                            << handle;
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for getting main 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();
                        // Compute the transform while locked because it reads
                        // the artboard bounds.
                        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);
                            }
                        }

                        const bool transformChanged =
                            wrapper->m_hasLastSemanticsTransform &&
                            wrapper->m_lastSemanticsTransform != transform;
                        wrapper->m_lastSemanticsTransform = transform;
                        wrapper->m_hasLastSemanticsTransform = true;
                        if (transformChanged)
                        {
                            // Viewport-only diffs bypass SemanticManager's
                            // normal metadata population.
                            diff.frameNumber = Artboard::frameId();
                            diff.updatedGeometry = manager->boundsSnapshot();
                            diff.treeVersion = manager->version();
                            diff.rootId = manager->rootId();
                        }

                        if (!diff.empty())
                        {
                            // 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->uniqueName();
                        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;
                BlobAssetHandle blobHandle = 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::assetBlob:
                        commandStream >> blobHandle;
                        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::assetBlob:
                        {
                            if (auto blobProperty =
                                    viewModelInstance->propertyBlob(
                                        value.metaData.name))
                            {
                                if (blobHandle == RIVE_NULL_HANDLE)
                                {
                                    blobProperty->value(nullptr);
                                }
                                else if (auto blob = getBlob(blobHandle))
                                {
                                    blobProperty->value(blob);
                                }
                                else
                                {
                                    ErrorReporter<ViewModelInstanceHandle>(
                                        this,
                                        handle,
                                        requestId,
                                        CommandQueue::Message::viewModelError)
                                        << "Could not find blob " << blobHandle
                                        << " 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 "
                                       "blob 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;
            }

            case CommandQueue::Command::focusNext:
            case CommandQueue::Command::focusPrevious:
            {
                const bool moveNext =
                    command == CommandQueue::Command::focusNext;
                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 (moveNext)
                    {
                        wrapper->instance->focusNext();
                    }
                    else
                    {
                        wrapper->instance->focusPrevious();
                    }
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle << " not found for "
                        << (moveNext ? "focusNext" : "focusPrevious") << ".";
                }
                break;
            }

            case CommandQueue::Command::requestHasFocusNodes:
            {
                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);
                    const bool hasFocusNodes =
                        wrapper->instance->hasFocusNodes();
                    stateMachineLock.unlock();

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

            case CommandQueue::Command::clearFocus:
            {
                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->clearFocus();
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for clearFocus.";
                }
                break;
            }

            case CommandQueue::Command::requestFocusState:
            {
                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);
                    const auto focusState = wrapper->instance->focusState();
                    stateMachineLock.unlock();

                    std::unique_lock<std::mutex> messageLock(
                        m_commandQueue->m_messageMutex);
                    messageStream << CommandQueue::Message::focusStateReceived;
                    messageStream << handle;
                    messageStream << requestId;
                    messageStream << focusState.hasFocus;
                    messageStream << focusState.expectsKeyboardInput;
                }
                else
                {
                    ErrorReporter<StateMachineHandle>(
                        this,
                        handle,
                        requestId,
                        CommandQueue::Message::stateMachineError)
                        << "State machine " << handle
                        << " not found for requestFocusState.";
                }
                break;
            }
        }

        // 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);
    if (instance != nullptr)
    {
        instance->dispose();
    }
}

CommandServer::SynchronizedStateMachine& CommandServer::
    SynchronizedStateMachine::operator=(SynchronizedStateMachine&& other)
{
    instance = std::move(other.instance);
    m_lastSemanticsTransform = other.m_lastSemanticsTransform;
    m_hasLastSemanticsTransform = other.m_hasLastSemanticsTransform;
    return *this;
}

CommandServer::SynchronizedStateMachine::SynchronizedStateMachine(
    std::unique_ptr<StateMachineInstance> instance) :
    instance(std::move(instance))
{}

bool CommandServer::focusNextSynchronized(StateMachineHandle handle)
{
    std::unique_lock<std::mutex> accessLock(m_stateMachineAccessMutex);
    auto it = m_stateMachines.find(handle);
    if (it == m_stateMachines.end())
    {
        return false;
    }

    auto stateMachine = it->second;
    accessLock.unlock();
    std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
    return stateMachine->instance->focusNext();
}

bool CommandServer::focusPreviousSynchronized(StateMachineHandle handle)
{
    std::unique_lock<std::mutex> accessLock(m_stateMachineAccessMutex);
    auto it = m_stateMachines.find(handle);
    if (it == m_stateMachines.end())
    {
        return false;
    }

    auto stateMachine = it->second;
    accessLock.unlock();
    std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
    return stateMachine->instance->focusPrevious();
}
}; // namespace rive
