/*
 * 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/input/focus_manager.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
{

/**
 * Stores registered resource handles and matching assets in loaded files for
 * one file asset type.
 *
 * Entries are keyed by unique asset name. Each entry contains the one resource
 * handle registered for that name and a map of the loaded files containing a
 * matching out-of-band file asset. Registering a resource and applying it to
 * those file assets are intentionally separate operations.
 */
template <typename TResourceHandle, typename TFileAsset>
class TypedGlobalAssetRegistry
{
public:
  /** Adds a matching file asset after its file imports successfully. */
  void addFileAsset(FileHandle fileHandle, TFileAsset* asset)
  {
    m_entries[asset->uniqueName()].assetsByFileHandle[fileHandle] = ref_rcp(
        asset);
  }

  /** Removes a file asset when its containing file is deleted. */
  void removeFileAsset(FileHandle fileHandle, const std::string& name)
  {
    auto itr = m_entries.find(name);
    if (itr == m_entries.end())
    {
      return;
    }
    itr->second.assetsByFileHandle.erase(fileHandle);
    eraseIfUnused(itr);
  }

  /** Returns the resource registered for a name, or the null handle. */
  TResourceHandle getResourceHandle(const std::string& name) const
  {
    auto itr = m_entries.find(name);
    return itr == m_entries.end() ? RIVE_NULL_HANDLE
                                  : itr->second.resourceHandle;
  }

  /** Sets the resource for a name without applying it to file assets. */
  void setResource(const std::string& name, TResourceHandle handle)
  {
    m_entries[name].resourceHandle = handle;
  }

  /** Unregisters the resource for a name without clearing file assets. */
  void unregisterResourceByName(const std::string& name)
  {
    auto itr = m_entries.find(name);
    if (itr == m_entries.end())
    {
      return;
    }
    itr->second.resourceHandle = RIVE_NULL_HANDLE;
    eraseIfUnused(itr);
  }

  /**
   * Unregisters every name backed by a resource handle.
   *
   * Returns the names that still have loaded file assets and therefore need
   * to have the null resource applied separately.
   */
  std::vector<std::string> unregisterResourceByHandle(TResourceHandle handle)
  {
    std::vector<std::string> names;
    for (auto itr = m_entries.begin(); itr != m_entries.end();)
    {
      if (itr->second.resourceHandle != handle)
      {
        ++itr;
        continue;
      }

      itr->second.resourceHandle = RIVE_NULL_HANDLE;
      if (itr->second.empty())
      {
        itr = m_entries.erase(itr);
      }
      else
      {
        names.push_back(itr->first);
        ++itr;
      }
    }
    return names;
  }

  /** Applies an operation to every loaded file asset matching a name. */
  template <typename Apply>
  void applyToFileAssets(const std::string& name, Apply&& apply) const
  {
    auto itr = m_entries.find(name);
    if (itr == m_entries.end())
    {
      return;
    }

    for (const auto& fileAsset : itr->second.assetsByFileHandle)
    {
      apply(*fileAsset.second);
    }
  }

private:
  struct Entry
  {
    TResourceHandle resourceHandle = RIVE_NULL_HANDLE;
    std::unordered_map<FileHandle, rcp<TFileAsset>> assetsByFileHandle;

    bool empty() const
    {
      return resourceHandle == RIVE_NULL_HANDLE && assetsByFileHandle.empty();
    }
  };

  using Entries = std::unordered_map<std::string, Entry>;

  void eraseIfUnused(typename Entries::iterator itr)
  {
    if (itr->second.empty())
    {
      m_entries.erase(itr);
    }
  }

  Entries m_entries;
};

/**
 * Maintains global resource registrations and the loaded out-of-band file
 * assets that consume them.
 *
 * One typed registry is maintained for images, audio sources, and fonts. This
 * class adds and removes file assets, registers and unregisters resource
 * handles, resolves them from read-only references to CommandServer's resource
 * maps, and applies the resources to matching loaded file assets.
 *
 * It does not own decoded resources. CommandServer owns those resources.
 *
 * Resource registration and application remain separate so callers control
 * when each operation occurs.
 */
class GlobalAssetRegistry : public RefCnt<GlobalAssetRegistry>
{
public:
  GlobalAssetRegistry(
      const std::unordered_map<RenderImageHandle, rcp<RenderImage>>& images,
      const std::unordered_map<AudioSourceHandle, rcp<AudioSource>>&
          audioSources,
      const std::unordered_map<FontHandle, rcp<Font>>& fonts)
      : m_images(images)
      , m_audioSources(audioSources)
      , m_fonts(fonts)
  {}

  /** Adds successfully imported out-of-band file assets to the registry. */
  void addFileAssets(FileHandle fileHandle, Span<const rcp<FileAsset>> assets)
  {
    for (const auto& asset : assets)
    {
      if (asset->is<ImageAsset>())
      {
        m_imageRegistry.addFileAsset(fileHandle, asset->as<ImageAsset>());
      }
      else if (asset->is<AudioAsset>())
      {
        m_audioRegistry.addFileAsset(fileHandle, asset->as<AudioAsset>());
      }
      else if (asset->is<FontAsset>())
      {
        m_fontRegistry.addFileAsset(fileHandle, asset->as<FontAsset>());
      }
    }
  }

  /** Applies registered resources to newly imported file assets. */
  void applyResourcesToFileAssets(Span<const rcp<FileAsset>> fileAssets) const
  {
    for (const auto& asset : fileAssets)
    {
      if (asset->is<ImageAsset>())
      {
        auto handle = renderImageHandle(asset->uniqueName());
        asset->as<ImageAsset>()->renderImage(getResource(m_images, handle));
      }
      else if (asset->is<AudioAsset>())
      {
        auto handle = audioSourceHandle(asset->uniqueName());
        asset->as<AudioAsset>()->audioSource(
            getResource(m_audioSources, handle));
      }
      else if (asset->is<FontAsset>())
      {
        auto handle = fontHandle(asset->uniqueName());
        asset->as<FontAsset>()->font(getResource(m_fonts, handle));
      }
    }
  }

  RenderImageHandle renderImageHandle(const std::string& name) const
  {
    return m_imageRegistry.getResourceHandle(name);
  }

  AudioSourceHandle audioSourceHandle(const std::string& name) const
  {
    return m_audioRegistry.getResourceHandle(name);
  }

  FontHandle fontHandle(const std::string& name) const
  {
    return m_fontRegistry.getResourceHandle(name);
  }

  /** Sets the resource for a name. The caller applies it separately. */
  void setRenderImage(const std::string& name, RenderImageHandle handle)
  {
    m_imageRegistry.setResource(name, handle);
  }

  void setAudioSource(const std::string& name, AudioSourceHandle handle)
  {
    m_audioRegistry.setResource(name, handle);
  }

  void setFont(const std::string& name, FontHandle handle)
  {
    m_fontRegistry.setResource(name, handle);
  }

  /**
   * Unregisters the resource for a name. The caller applies the null resource
   * separately.
   */
  void removeRenderImage(const std::string& name)
  {
    m_imageRegistry.unregisterResourceByName(name);
  }

  void removeAudioSource(const std::string& name)
  {
    m_audioRegistry.unregisterResourceByName(name);
  }

  void removeFont(const std::string& name)
  {
    m_fontRegistry.unregisterResourceByName(name);
  }

  void applyRenderImage(const std::string& name, const rcp<RenderImage>& image)
      const
  {
    m_imageRegistry.applyToFileAssets(name, [&image](ImageAsset& asset) {
      asset.renderImage(image);
    });
  }

  void applyAudioSource(
      const std::string& name,
      const rcp<AudioSource>& audioSource) const
  {
    m_audioRegistry.applyToFileAssets(name, [&audioSource](AudioAsset& asset) {
      asset.audioSource(audioSource);
    });
  }

  void applyFont(const std::string& name, const rcp<Font>& font) const
  {
    m_fontRegistry.applyToFileAssets(name, [&font](FontAsset& asset) {
      asset.font(font);
    });
  }

  /**
   * Unregisters every name backed by a deleted resource handle. The caller
   * applies each returned name separately.
   */
  std::vector<std::string> removeRenderImage(RenderImageHandle handle)
  {
    return m_imageRegistry.unregisterResourceByHandle(handle);
  }

  std::vector<std::string> removeAudioSource(AudioSourceHandle handle)
  {
    return m_audioRegistry.unregisterResourceByHandle(handle);
  }

  std::vector<std::string> removeFont(FontHandle handle)
  {
    return m_fontRegistry.unregisterResourceByHandle(handle);
  }

  /**
   * Removes a deleted file from each registry entry named by an asset in that
   * loaded Rive file. No file-to-assets reverse registry is needed.
   */
  void removeFileAssets(
      FileHandle fileHandle,
      Span<const rcp<FileAsset>> assets)
  {
    for (const auto& asset : assets)
    {
      if (asset->is<ImageAsset>())
      {
        m_imageRegistry.removeFileAsset(fileHandle, asset->uniqueName());
      }
      else if (asset->is<AudioAsset>())
      {
        m_audioRegistry.removeFileAsset(fileHandle, asset->uniqueName());
      }
      else if (asset->is<FontAsset>())
      {
        m_fontRegistry.removeFileAsset(fileHandle, asset->uniqueName());
      }
    }
  }

#ifdef TESTING
  RenderImageHandle testing_imageNamed(const std::string& name)
  {
    return renderImageHandle(name);
  }

  AudioSourceHandle testing_audioNamed(const std::string& name)
  {
    return audioSourceHandle(name);
  }

  FontHandle testing_fontNamed(const std::string& name)
  {
    return fontHandle(name);
  }
#endif

private:
  template <typename TResourceHandle, typename TResource>
  static rcp<TResource> getResource(
      const std::unordered_map<TResourceHandle, rcp<TResource>>& resources,
      TResourceHandle handle)
  {
    auto itr = resources.find(handle);
    return itr == resources.end() ? nullptr : itr->second;
  }

  const std::unordered_map<RenderImageHandle, rcp<RenderImage>>& m_images;
  const std::unordered_map<AudioSourceHandle, rcp<AudioSource>>& m_audioSources;
  const std::unordered_map<FontHandle, rcp<Font>>& m_fonts;
  TypedGlobalAssetRegistry<RenderImageHandle, ImageAsset> m_imageRegistry;
  TypedGlobalAssetRegistry<AudioSourceHandle, AudioAsset> m_audioRegistry;
  TypedGlobalAssetRegistry<FontHandle, FontAsset> m_fontRegistry;
};

/**
 * The file asset loader for one command-queue import.
 *
 * It first delegates to the optional FileAssetLoader supplied to CommandServer.
 * When that loader returns true, it is loading or has loaded the asset outside
 * the command queue, so the asset is not registered for a global resource.
 * Otherwise, eligible out-of-band assets are retained locally so they can be
 * registered after a successful import.
 */
class CommandServer::CommandFileAssetLoader : public FileAssetLoader
{
public:
  CommandFileAssetLoader(rcp<FileAssetLoader> internalLoader)
      : m_internalLoader(std::move(internalLoader))
  {}

  bool loadContents(
      FileAsset& asset,
      Span<const uint8_t> inBandBytes,
      Factory* factory) override
  {
    if (m_internalLoader &&
        m_internalLoader->loadContents(asset, inBandBytes, factory))
    {
      return true;
    }
    if (!inBandBytes.empty())
    {
      return false;
    }
    if (asset.is<ImageAsset>() || asset.is<AudioAsset>() ||
        asset.is<FontAsset>())
    {
      m_fileAssets.push_back(ref_rcp(&asset));
      return false;
    }
    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;
    }
    fprintf(
        stderr,
        "ERROR: CommandFileAssetLoader::loadContents - Unsupported"
        " asset type for asset: '%s'\n",
        asset.uniqueFilename().c_str());
    return false;
  }

  Span<const rcp<FileAsset>> fileAssets() const
  {
    return {m_fileAssets.data(), m_fileAssets.size()};
  }

private:
  rcp<FileAssetLoader> m_internalLoader;
  std::vector<rcp<FileAsset>> m_fileAssets;
};

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::assetFont:
      os << "Asset Font";
      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_globalAssetRegistry->testing_imageNamed(name);
}

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

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

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

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

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

#endif

CommandServer::CommandServer(
    rcp<CommandQueue> commandBuffer,
    Factory* factory,
    rcp<rive::FileAssetLoader> internalFileAssetLoader)
    : m_commandQueue(std::move(commandBuffer))
    , m_factory(factory)
    ,
#ifndef NDEBUG
    m_threadID(std::this_thread::get_id())
    ,
#endif
    m_globalAssetRegistry(
        make_rcp<GlobalAssetRegistry>(m_images, m_audioSources, m_fonts))
    , m_internalFileAssetLoader(std::move(internalFileAssetLoader))
{}

CommandServer::~CommandServer() {}

void CommandServer::postRuntimeMessage(
    uint32_t tag,
    std::vector<uint8_t> payload)
{
  std::unique_lock<std::mutex> lock(m_commandQueue->m_messageMutex);
  m_commandQueue->m_messageStream << CommandQueue::Message::runtimeMessage;
  m_commandQueue->m_messageStream << tag;
  m_commandQueue->m_messageByteVectors << std::move(payload);
}

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,
          pointerEvent.button);
      // 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,
          pointerEvent.button);
      // 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;
}

bool CommandServer::listensToButtonAtSynchronized(
    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->listensToButtonAt(
          pos,
          pointerEvent.button);
    }
  }

  return false;
}

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::assetFont:
            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::assetFont:
            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();
        auto fileAssetLoader = make_rcp<CommandFileAssetLoader>(
            m_internalFileAssetLoader);

#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,
            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,
            fileAssetLoader);
#endif

        if (file != nullptr)
        {
#if defined(__EMSCRIPTEN__) && defined(WITH_RIVE_SCRIPTING_WASM)
          // No host awaits a prepare step for a file the command
          // server loads, so its modules instantiate inline here.
          file->startScripts();
#endif
          auto fileAssets = fileAssetLoader->fileAssets();
          m_globalAssetRegistry->addFileAssets(handle, fileAssets);
          m_globalAssetRegistry->applyResourcesToFileAssets(fileAssets);
          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();
        auto fileItr = m_files.find(handle);
        if (fileItr != m_files.end())
        {
          m_globalAssetRegistry->removeFileAssets(
              handle,
              fileItr->second->assets());
          m_files.erase(fileItr);
        }
        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);
        for (const auto& name :
             m_globalAssetRegistry->removeRenderImage(handle))
        {
          m_globalAssetRegistry->applyRenderImage(name, nullptr);
        }
        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);
        for (const auto& name :
             m_globalAssetRegistry->removeAudioSource(handle))
        {
          m_globalAssetRegistry->applyAudioSource(name, nullptr);
        }
        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(std::move(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);
        for (const auto& name : m_globalAssetRegistry->removeFont(handle))
        {
          m_globalAssetRegistry->applyFont(name, nullptr);
        }
        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;
        FontHandle fontHandle = 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::assetFont:
            commandStream >> fontHandle;
            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 << " for view model instance "
                    << handle;
              }
              break;
            }
            case DataType::assetFont:
            {
              if (auto fontProperty = viewModelInstance->propertyFont(
                      value.metaData.name))
              {
                if (fontHandle == RIVE_NULL_HANDLE)
                {
                  fontProperty->value(nullptr);
                }
                else if (auto font = getFont(fontHandle))
                {
                  fontProperty->value(font);
                }
                else
                {
                  ErrorReporter<ViewModelInstanceHandle>(
                      this,
                      handle,
                      requestId,
                      CommandQueue::Message::viewModelError)
                      << "Could not find font " << fontHandle
                      << " 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 "
                       "font property at path "
                    << value.metaData.name << " for view model instance "
                    << handle;
              }
              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 << " for view model instance "
                    << handle;
              }
              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 << " for view model instance "
                    << handle;
              }
              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))
        {
          bool found = false;
          switch (value.metaData.type)
          {
            case DataType::boolean:
            {
              if (auto property = viewModelInstance->propertyBoolean(
                      value.metaData.name))
              {
                value.boolValue = property->value();
                found = true;
              }
              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();
                found = true;
              }
              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();
                found = true;
              }
              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();
                found = true;
              }
              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();
                found = true;
              }
              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();
          }

          if (!found)
          {
            // Exit this command, preserving the batch/draw
            // epilogue. Failed reads must not emit a second,
            // invalid value response.
            break;
          }

          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,
              pointerEvent.button);
          // 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,
              pointerEvent.button);
          // 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::keyInput:
      {
        StateMachineHandle handle;
        uint64_t requestId;
        commandStream >> handle;
        commandStream >> requestId;
        Key key;
        KeyModifiers modifiers;
        bool isPressed;
        bool isRepeat;
        commandStream >> key;
        commandStream >> modifiers;
        commandStream >> isPressed;
        commandStream >> isRepeat;
        lock.unlock();
        if (auto wrapper = getStateMachineWrapper(handle))
        {
          std::unique_lock<std::mutex> stateMachineLock(wrapper->m_mutex);
          const bool handled = wrapper->instance->keyInput(
              key,
              modifiers,
              isPressed,
              isRepeat);
          stateMachineLock.unlock();

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

      case CommandQueue::Command::textInput:
      {
        StateMachineHandle handle;
        uint64_t requestId;
        commandStream >> handle;
        commandStream >> requestId;
        std::string text;
        m_commandQueue->m_names >> text;
        lock.unlock();
        if (auto wrapper = getStateMachineWrapper(handle))
        {
          std::unique_lock<std::mutex> stateMachineLock(wrapper->m_mutex);
          const bool handled = wrapper->instance->textInput(text);
          stateMachineLock.unlock();

          std::unique_lock<std::mutex> messageLock(
              m_commandQueue->m_messageMutex);
          messageStream << CommandQueue::Message::textInputHandled;
          messageStream << handle;
          messageStream << requestId;
          messageStream << handled;
        }
        else
        {
          ErrorReporter<StateMachineHandle>(
              this,
              handle,
              requestId,
              CommandQueue::Message::stateMachineError)
              << "State machine " << handle << " not found for textInput.";
        }
        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();
        auto image = ref_rcp(getImage(handle));
        if (image != nullptr)
        {
          m_globalAssetRegistry->setRenderImage(name, handle);
          m_globalAssetRegistry->applyRenderImage(name, image);
        }
        else
        {
          ErrorReporter<RenderImageHandle>(
              this,
              handle,
              requestId,
              CommandQueue::Message::imageError)
              << "Invalid image handle when adding global image "
                 "asset \""
              << name << "\"";
        }
        break;
      }

      case CommandQueue::Command::removeImageFileAsset:
      {
        std::string name;
        uint64_t requestId;
        CommandQueue::PointerEvent pointerEvent;
        commandStream >> requestId;
        m_commandQueue->m_names >> name;
        lock.unlock();
        m_globalAssetRegistry->removeRenderImage(name);
        m_globalAssetRegistry->applyRenderImage(name, nullptr);
        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();
        auto audioSource = ref_rcp(getAudioSource(handle));
        if (audioSource != nullptr)
        {
          m_globalAssetRegistry->setAudioSource(name, handle);
          m_globalAssetRegistry->applyAudioSource(name, audioSource);
        }
        else
        {
          ErrorReporter<AudioSourceHandle>(
              this,
              handle,
              requestId,
              CommandQueue::Message::audioError)
              << "Invalid audio handle when adding global audio "
                 "asset \""
              << name << "\"";
        }
        break;
      }

      case CommandQueue::Command::removeAudioFileAsset:
      {
        std::string name;
        uint64_t requestId;
        CommandQueue::PointerEvent pointerEvent;
        commandStream >> requestId;
        m_commandQueue->m_names >> name;
        lock.unlock();
        m_globalAssetRegistry->removeAudioSource(name);
        m_globalAssetRegistry->applyAudioSource(name, nullptr);
        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();
        auto font = ref_rcp(getFont(handle));
        if (font != nullptr)
        {
          m_globalAssetRegistry->setFont(name, handle);
          m_globalAssetRegistry->applyFont(name, font);
        }
        else
        {
          ErrorReporter<FontHandle>(
              this,
              handle,
              requestId,
              CommandQueue::Message::fontError)
              << "Invalid font handle when adding global font asset "
                 "\""
              << name << "\"";
        }
        break;
      }

      case CommandQueue::Command::removeFontFileAsset:
      {
        std::string name;
        uint64_t requestId;
        CommandQueue::PointerEvent pointerEvent;
        commandStream >> requestId;
        m_commandQueue->m_names >> name;
        lock.unlock();
        m_globalAssetRegistry->removeFont(name);
        m_globalAssetRegistry->applyFont(name, nullptr);
        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)
{
  return focusNextWithResultSynchronized(handle).moved;
}

bool CommandServer::focusPreviousSynchronized(StateMachineHandle handle)
{
  return focusPreviousWithResultSynchronized(handle).moved;
}

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

  auto stateMachine = it->second;
  accessLock.unlock();
  std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
  const bool moved = stateMachine->instance->focusNext();
  const auto state = stateMachine->instance->focusState();
  return {moved, {state.hasFocus, state.expectsKeyboardInput}};
}

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

  auto stateMachine = it->second;
  accessLock.unlock();
  std::unique_lock<std::mutex> lock(stateMachine->m_mutex);
  const bool moved = stateMachine->instance->focusPrevious();
  const auto state = stateMachine->instance->focusState();
  return {moved, {state.hasFocus, state.expectsKeyboardInput}};
}

bool CommandServer::keyInputSynchronized(
    StateMachineHandle handle,
    Key key,
    KeyModifiers modifiers,
    bool isPressed,
    bool isRepeat)
{
  std::unique_lock<std::mutex> accessLock(m_stateMachineAccessMutex);
  auto it = m_stateMachines.find(handle);
  if (it == m_stateMachines.end())
  {
    return false;
  }
  auto wrapper = it->second;
  accessLock.unlock();
  std::unique_lock<std::mutex> lock(wrapper->m_mutex);
  return wrapper->instance->keyInput(key, modifiers, isPressed, isRepeat);
}

bool CommandServer::focusInDirectionSynchronized(
    StateMachineHandle handle,
    Direction direction)
{
  std::unique_lock<std::mutex> accessLock(m_stateMachineAccessMutex);
  auto it = m_stateMachines.find(handle);
  if (it == m_stateMachines.end())
  {
    return false;
  }
  auto wrapper = it->second;
  accessLock.unlock();
  std::unique_lock<std::mutex> lock(wrapper->m_mutex);
  auto* manager = wrapper->instance->focusManager();
  if (!manager)
  {
    return false;
  }
  switch (direction)
  {
    case Direction::left:
      return manager->focusLeft();
    case Direction::right:
      return manager->focusRight();
    case Direction::up:
      return manager->focusUp();
    case Direction::down:
      return manager->focusDown();
  }
  return false;
}
}; // namespace rive
