/*
 * Copyright 2025 Rive
 */

#pragma once

#include "rive/object_stream.hpp"
#include "rive/input/focusable.hpp"
#include "rive/refcnt.hpp"
#include "rive/math/vec2d.hpp"
#include "rive/pointer_button.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
#include "rive/animation/semantic_listener_group.hpp"
#include "rive/semantic/semantic_snapshot.hpp"

#include <condition_variable>
#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <unordered_map>
#include "file_asset_loader.hpp"

// Macros for defining and working with command buffer handles.
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(void*) == 8, "expected a 64-bit environment");
// Define handles as pointers to forward-declared types for type safety.
#define RIVE_DEFINE_HANDLE(NAME) using NAME = struct NAME##_HandlePlaceholder*;
#define RIVE_NULL_HANDLE nullptr
#elif INTPTR_MAX == INT32_MAX
static_assert(sizeof(void*) == 4, "expected a 32-bit environment");
#define RIVE_DEFINE_HANDLE(NAME) using NAME = uint64_t;
#define RIVE_NULL_HANDLE 0
#else
#error "environment not 32 or 64-bit."
#endif

namespace rive
{
enum class Direction : uint8_t;
class Factory;
class File;
class ArtboardInstance;
class StateMachineInstance;
class CommandServer;
class ScriptingContext;

RIVE_DEFINE_HANDLE(FontHandle);
RIVE_DEFINE_HANDLE(FileHandle);
RIVE_DEFINE_HANDLE(ArtboardHandle);
RIVE_DEFINE_HANDLE(AudioSourceHandle);
RIVE_DEFINE_HANDLE(RenderImageHandle);
RIVE_DEFINE_HANDLE(BlobAssetHandle);
RIVE_DEFINE_HANDLE(StateMachineHandle);
RIVE_DEFINE_HANDLE(ViewModelInstanceHandle);
RIVE_DEFINE_HANDLE(DrawKey);

// Function poimter that gets called back from the server thread.
using CommandServerCallback = std::function<void(CommandServer*)>;
using CommandServerDrawCallback = std::function<void(DrawKey, CommandServer*)>;

// Creates the ScriptingContext used for a loaded file's Lua VM. Invoked on the
// command server thread with the server's Factory so the context is built with
// the correct factory on the correct thread. Return nullptr (or leave the
// factory empty) to fall back to the default CPPRuntimeScriptingContext. Used
// by hosts (e.g. Unreal) to redirect Lua console/error output to their own
// logging.
using ScriptingContextFactory = std::function<std::unique_ptr<ScriptingContext>(
    Factory*)>;

struct ViewModelEnum
{
  std::string name;
  std::vector<std::string> enumerants;
};

// Client-side recorder for commands that will be executed by a CommandServer.
// Synchronized operations require an active CommandServer processing this
// queue on another thread and must not be called after disconnect(); otherwise,
// they block indefinitely.
class CommandQueue : public RefCnt<CommandQueue>
{
public:
  template <typename ListenerType, typename HandleType> class ListenerBase
  {
  public:
    friend class CommandQueue;

    ListenerBase(const ListenerBase&) = delete;
    ListenerBase& operator=(const ListenerBase&) = delete;
    ListenerBase(ListenerBase&& other)
        : m_owningQueue(std::move(other.m_owningQueue))
        , m_handle(std::move(other.m_handle))
    {
      if (m_owningQueue)
      {
        m_owningQueue->unregisterListener(
            m_handle,
            static_cast<ListenerType*>(&other));
        m_owningQueue->registerListener(
            m_handle,
            static_cast<ListenerType*>(this));
      }
    }
    ~ListenerBase()
    {
      if (m_owningQueue)
        m_owningQueue->unregisterListener(
            m_handle,
            static_cast<ListenerType*>(this));
    }
    ListenerBase() : m_handle(RIVE_NULL_HANDLE) {}

  private:
    rcp<CommandQueue> m_owningQueue;
    HandleType m_handle;
  };

  class FileListener
      : public CommandQueue::ListenerBase<FileListener, FileHandle>
  {
  public:
    virtual void onFileError(
        const FileHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onFileDeleted(const FileHandle, uint64_t requestId) {}

    virtual void onFileLoaded(const FileHandle, uint64_t requestId) {}

    /**
     * Called after an artboard instance is created.
     *
     * @param fileHandle The file from which the artboard was instantiated.
     * @param requestId The request that created the artboard handle.
     * @param artboardHandle The confirmed artboard handle.
     */
    virtual void onArtboardInstantiated(
        const FileHandle fileHandle,
        uint64_t requestId,
        ArtboardHandle artboardHandle)
    {}

    /**
     * Called after a view model instance or instance reference is created.
     *
     * @param fileHandle The source file for a newly instantiated view
     * model, or RIVE_NULL_HANDLE when the new handle references an existing
     * nested or list-item instance. Confirmations with RIVE_NULL_HANDLE are
     * delivered only to a FileListener registered for RIVE_NULL_HANDLE.
     * @param requestId The request that created the instance handle.
     * @param viewModelInstanceHandle The confirmed instance handle.
     */
    virtual void onViewModelInstanceInstantiated(
        const FileHandle fileHandle,
        uint64_t requestId,
        ViewModelInstanceHandle viewModelInstanceHandle)
    {}

    virtual void onArtboardsListed(
        const FileHandle,
        uint64_t requestId,
        std::vector<std::string> artboardNames)
    {}

    virtual void onViewModelsListed(
        const FileHandle,
        uint64_t requestId,
        std::vector<std::string> viewModelNames)
    {}

    virtual void onGlobalViewModelNamesListed(
        const FileHandle,
        uint64_t requestId,
        std::vector<std::string> globalViewModelNames)
    {}

    virtual void onViewModelInstanceNamesListed(
        const FileHandle,
        uint64_t requestId,
        std::string viewModelName,
        std::vector<std::string> instanceNames)
    {}

    struct ViewModelPropertyData
    {
      DataType type = DataType::none;
      std::string name = "";
      std::string metaData = "";
    };

    virtual void onViewModelPropertiesListed(
        const FileHandle,
        uint64_t requestId,
        std::string viewModelName,
        std::vector<ViewModelPropertyData> properties)
    {}

    virtual void onViewModelEnumsListed(
        const FileHandle,
        uint64_t requestId,
        std::vector<ViewModelEnum> enums)
    {}

    struct FileAssetData
    {
      std::string name;
      std::string uniqueName;
      uint32_t assetID = 0;
      std::string cdnUUID;
      std::string cdnBaseURL;
      std::string fileExtension;
      uint16_t type = 0;
    };

    virtual void onFileAssetsListed(
        const FileHandle,
        uint64_t requestId,
        std::vector<FileAssetData> assets)
    {}
  };

  class RenderImageListener
      : public CommandQueue::
            ListenerBase<RenderImageListener, RenderImageHandle>
  {
  public:
    virtual void onRenderImageDecoded(
        const RenderImageHandle,
        uint64_t requestId)
    {}

    virtual void onRenderImageError(
        const RenderImageHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onRenderImageDeleted(
        const RenderImageHandle,
        uint64_t requestId)
    {}
  };

  class AudioSourceListener
      : public CommandQueue::
            ListenerBase<AudioSourceListener, AudioSourceHandle>
  {
  public:
    virtual void onAudioSourceDecoded(
        const AudioSourceHandle,
        uint64_t requestId)
    {}

    virtual void onAudioSourceError(
        const AudioSourceHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onAudioSourceDeleted(
        const AudioSourceHandle,
        uint64_t requestId)
    {}
  };

  class FontListener
      : public CommandQueue::ListenerBase<FontListener, FontHandle>
  {
  public:
    virtual void onFontDecoded(const FontHandle, uint64_t requestId) {}

    virtual void onFontError(
        const FontHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onFontDeleted(const FontHandle, uint64_t requestId) {}
  };

  class BlobAssetListener
      : public CommandQueue::ListenerBase<BlobAssetListener, BlobAssetHandle>
  {
  public:
    virtual void onBlobAssetDecoded(const BlobAssetHandle, uint64_t requestId)
    {}

    virtual void onBlobAssetError(
        const BlobAssetHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onBlobAssetDeleted(const BlobAssetHandle, uint64_t requestId)
    {}
  };

  class ArtboardListener
      : public CommandQueue::ListenerBase<ArtboardListener, ArtboardHandle>
  {
  public:
    virtual void onArtboardError(
        const ArtboardHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onDefaultViewModelInfoReceived(
        const ArtboardHandle,
        uint64_t requestId,
        std::string viewModelName,
        std::string instanceName)
    {}

    virtual void onArtboardDeleted(const ArtboardHandle, uint64_t requestId) {}

    /**
     * Called after a state machine instance is created.
     *
     * @param artboardHandle The artboard from which the state machine was
     * instantiated.
     * @param requestId The request that created the state machine handle.
     * @param stateMachineHandle The confirmed state machine handle.
     */
    virtual void onStateMachineInstantiated(
        const ArtboardHandle artboardHandle,
        uint64_t requestId,
        StateMachineHandle stateMachineHandle)
    {}

    virtual void onStateMachinesListed(
        const ArtboardHandle,
        uint64_t requestId,
        std::vector<std::string> stateMachineNames)
    {}

    virtual void onArtboardVolumeReceived(
        const ArtboardHandle,
        uint64_t requestId,
        float volume)
    {}

    virtual void onArtboardSizeReceived(
        const ArtboardHandle,
        uint64_t requestId,
        float width,
        float height)
    {}
  };

  struct ViewModelInstanceData
  {
    // The path and type of this property
    PropertyData metaData;

    // The specific value of this property, you must use the correct union
    // member base on type in metaData, both enumType and string use
    // stringValue

    // std::string is non trival, so it stays outside the union
    std::string stringValue;
    union
    {
      bool boolValue;
      float numberValue;
      ColorInt colorValue;
    };
  };

  // Mirrors StateMachineInstance::FocusState for command queue responses.
  struct FocusState
  {
    bool hasFocus = false;
    bool expectsKeyboardInput = false;
  };

  /** Traversal and its resulting state, observed under the same lock. */
  struct FocusTraversalResult
  {
    /** Whether traversal moved focus, including entry into the focus tree.
     */
    bool moved = false;
    /** The focus state immediately after traversal, even when it did not
     * move. */
    FocusState focusState = {};
  };

  class ViewModelInstanceListener
      : public CommandQueue::
            ListenerBase<ViewModelInstanceListener, ViewModelInstanceHandle>
  {
  public:
    virtual void onViewModelInstanceError(
        const ViewModelInstanceHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onViewModelInstanceViewModelNameReceived(
        const ViewModelInstanceHandle,
        uint64_t requestId,
        std::string viewModelName)
    {}
    virtual void onViewModelInstanceNameReceived(
        const ViewModelInstanceHandle handle,
        uint64_t requestId,
        std::string instanceName)
    {}

    virtual void onViewModelDeleted(
        const ViewModelInstanceHandle,
        uint64_t requestId)
    {}

    virtual void onViewModelDataReceived(
        const ViewModelInstanceHandle,
        uint64_t requestId,
        ViewModelInstanceData)
    {}

    virtual void onViewModelListSizeReceived(
        const ViewModelInstanceHandle,
        uint64_t requestId,
        std::string path,
        size_t size)
    {}

    virtual void onViewModelListCleared(
        const ViewModelInstanceHandle,
        uint64_t requestId,
        std::string path)
    {}
  };

  class StateMachineListener
      : public CommandQueue::
            ListenerBase<StateMachineListener, StateMachineHandle>
  {
  public:
    virtual void onStateMachineError(
        const StateMachineHandle,
        uint64_t requestId,
        std::string error)
    {}

    virtual void onStateMachineDeleted(
        const StateMachineHandle,
        uint64_t requestId)
    {}
    // requestId in this case is the specific request that caused the
    // statemachine to settle
    virtual void onStateMachineSettled(
        const StateMachineHandle,
        uint64_t requestId)
    {}

    /**
     * Called after mainViewModelInstance or globalViewModelInstance
     * successfully retrieves a view model instance bound to a state
     * machine. Lookup failures are reported through onStateMachineError.
     *
     * @param stateMachineHandle The state machine from which the view model
     * instance was retrieved.
     * @param requestId The request that retrieved the view model instance.
     * @param viewModelInstanceHandle The confirmed view model instance
     * handle.
     */
    virtual void onViewModelInstanceReceived(
        const StateMachineHandle stateMachineHandle,
        uint64_t requestId,
        ViewModelInstanceHandle viewModelInstanceHandle)
    {}

    /**
     * Reports whether a focused node or its ancestor handled a key event.
     * A handled input need not change text. Invalid handles are reported
     * through onStateMachineError instead.
     *
     * @param stateMachineHandle The state machine that received the input.
     * @param requestId The input command's request identifier.
     * @param handled Whether a recipient claimed the input.
     */
    virtual void onKeyInputHandled(
        const StateMachineHandle stateMachineHandle,
        uint64_t requestId,
        bool handled)
    {}

    /**
     * Reports whether a focused node or its ancestor handled committed
     * text. A handled input need not change text. Invalid handles are
     * reported through onStateMachineError instead.
     *
     * @param stateMachineHandle The state machine that received the input.
     * @param requestId The input command's request identifier.
     * @param handled Whether a recipient claimed the input.
     */
    virtual void onTextInputHandled(
        const StateMachineHandle stateMachineHandle,
        uint64_t requestId,
        bool handled)
    {}

    // Delivered when an incremental semantic diff is available for this
    // state machine. Emitted only when drainSemanticsDiff produces a
    // non-empty diff. Bounds inside the diff are reported in view space
    // using the fit/alignment/scale/view-bounds arguments provided to the
    // drain command.
    virtual void onSemanticsDiffReceived(
        const StateMachineHandle,
        uint64_t requestId,
        SemanticsDiff diff)
    {}

    virtual void onHasFocusNodesReceived(
        const StateMachineHandle,
        uint64_t requestId,
        bool hasFocusNodes)
    {}

    virtual void onFocusStateReceived(
        const StateMachineHandle,
        uint64_t requestId,
        FocusState focusState)
    {}
  };

  class RuntimeMessageListener
  {
  public:
    virtual ~RuntimeMessageListener() = default;

    /**
     * Receives runtime-defined messages posted by the command server.
     *
     * Called on the thread running processMessages(), with the message
     * mutex released. The callback owns the payload and may retain it.
     *
     * @param tag Runtime-owned message type identifier.
     * @param payload Runtime-owned serialized message bytes.
     */
    virtual void onRuntimeMessage(uint32_t tag, std::vector<uint8_t> payload) {}
  };

  CommandQueue();
  ~CommandQueue();

  FileHandle loadFile(
      std::vector<uint8_t> rivBytes,
      FileListener* listener = nullptr,
      uint64_t requestId = 0
#ifdef WITH_RIVE_SCRIPTING
      ,
      ScriptingContextFactory scriptingContextFactory = nullptr
#endif
  );

  void deleteFile(FileHandle, uint64_t requestId = 0);

  /**
   * Registers a global image asset that provides the contents for any file's
   * out-of-band image asset with the same unique name.
   *
   * The change reaches files that are already open as well as files loaded
   * afterward. Registering a name that is already registered replaces its
   * resource everywhere.
   *
   * Assets with embedded contents and assets claimed by a host-supplied file
   * asset loader are never overridden. Reports an error on the matching
   * asset listener if the handle is invalid.
   *
   * @param name The unique asset name to register.
   * @param handle The decoded image resource to provide.
   * @param requestId The request identifier used for an error callback.
   */
  void addGlobalImageAsset(
      std::string name,
      RenderImageHandle handle,
      uint64_t requestId = 0);
  /**
   * Registers a global font asset that provides the contents for any file's
   * out-of-band font asset with the same unique name.
   *
   * The change reaches files that are already open as well as files loaded
   * afterward. Registering a name that is already registered replaces its
   * resource everywhere.
   *
   * Assets with embedded contents and assets claimed by a host-supplied file
   * asset loader are never overridden. Reports an error on the matching
   * asset listener if the handle is invalid.
   *
   * @param name The unique asset name to register.
   * @param handle The decoded font resource to provide.
   * @param requestId The request identifier used for an error callback.
   */
  void addGlobalFontAsset(
      std::string name,
      FontHandle handle,
      uint64_t requestId = 0);
  /**
   * Registers a global audio asset that provides the contents for any file's
   * out-of-band audio asset with the same unique name.
   *
   * The change reaches files that are already open as well as files loaded
   * afterward. Registering a name that is already registered replaces its
   * resource everywhere.
   *
   * Assets with embedded contents and assets claimed by a host-supplied file
   * asset loader are never overridden. Reports an error on the matching
   * asset listener if the handle is invalid.
   *
   * @param name The unique asset name to register.
   * @param handle The decoded audio resource to provide.
   * @param requestId The request identifier used for an error callback.
   */
  void addGlobalAudioAsset(
      std::string name,
      AudioSourceHandle handle,
      uint64_t requestId = 0);

  /**
   * Unregisters the global image asset with the given unique name, clearing
   * it from every open file it was applied to. Deleting the backing image
   * resource has the same effect for every name that resource was registered
   * under.
   *
   * @param name The unique asset name to unregister.
   * @param requestId The request identifier.
   */
  void removeGlobalImageAsset(std::string name, uint64_t requestId = 0);
  /**
   * Unregisters the global font asset with the given unique name, clearing it
   * from every open file it was applied to. Deleting the backing font
   * resource has the same effect for every name that resource was registered
   * under.
   *
   * @param name The unique asset name to unregister.
   * @param requestId The request identifier.
   */
  void removeGlobalFontAsset(std::string name, uint64_t requestId = 0);
  /**
   * Unregisters the global audio asset with the given unique name, clearing
   * it from every open file it was applied to. Deleting the backing audio
   * resource has the same effect for every name that resource was registered
   * under.
   *
   * @param name The unique asset name to unregister.
   * @param requestId The request identifier.
   */
  void removeGlobalAudioAsset(std::string name, uint64_t requestId = 0);

  ArtboardHandle instantiateArtboardNamed(
      FileHandle,
      std::string name,
      ArtboardListener* listener = nullptr,
      uint64_t requestId = 0);
  ArtboardHandle instantiateDefaultArtboard(
      FileHandle fileHandle,
      ArtboardListener* listener = nullptr,
      uint64_t requestId = 0)
  {
    return instantiateArtboardNamed(fileHandle, "", listener, requestId);
  }

  void setArtboardSize(
      ArtboardHandle,
      float width,
      float height,
      float scale = 1,
      uint64_t requestId = 0);

  void resetArtboardSize(ArtboardHandle, uint64_t requestId = 0);

  void deleteArtboard(ArtboardHandle, uint64_t requestId = 0);

  ViewModelInstanceHandle instantiateBlankViewModelInstance(
      FileHandle fileHandle,
      ArtboardHandle artboardHandle,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  ViewModelInstanceHandle instantiateBlankViewModelInstance(
      FileHandle fileHandle,
      std::string viewModelName,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  ViewModelInstanceHandle instantiateDefaultViewModelInstance(
      FileHandle fileHandle,
      ArtboardHandle artboardHandle,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0)
  {
    return instantiateViewModelInstanceNamed(
        fileHandle,
        artboardHandle,
        "",
        listener,
        requestId);
  }

  ViewModelInstanceHandle instantiateDefaultViewModelInstance(
      FileHandle fileHandle,
      std::string viewModelName,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0)
  {
    return instantiateViewModelInstanceNamed(
        fileHandle,
        viewModelName,
        "",
        listener,
        requestId);
  }

  ViewModelInstanceHandle instantiateViewModelInstanceNamed(
      FileHandle,
      ArtboardHandle,
      std::string viewModelInstanceName,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  ViewModelInstanceHandle instantiateViewModelInstanceNamed(
      FileHandle,
      std::string viewModelName,
      std::string viewModelInstanceName,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  ViewModelInstanceHandle referenceNestedViewModelInstance(
      ViewModelInstanceHandle,
      std::string path,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  ViewModelInstanceHandle referenceListViewModelInstance(
      ViewModelInstanceHandle,
      std::string path,
      int index,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  void fireViewModelTrigger(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void setViewModelInstanceBool(
      ViewModelInstanceHandle,
      std::string path,
      bool value,
      uint64_t requestId = 0);
  void setViewModelInstanceNumber(
      ViewModelInstanceHandle,
      std::string path,
      float value,
      uint64_t requestId = 0);
  void setViewModelInstanceColor(
      ViewModelInstanceHandle,
      std::string path,
      ColorInt value,
      uint64_t requestId = 0);
  void setViewModelInstanceEnum(
      ViewModelInstanceHandle,
      std::string path,
      std::string value,
      uint64_t requestId = 0);
  void setViewModelInstanceString(
      ViewModelInstanceHandle,
      std::string path,
      std::string value,
      uint64_t requestId = 0);
  void setViewModelInstanceImage(
      ViewModelInstanceHandle,
      std::string path,
      RenderImageHandle value,
      uint64_t requestId = 0);
  void setViewModelInstanceFont(
      ViewModelInstanceHandle,
      std::string path,
      FontHandle value,
      uint64_t requestId = 0);
  void setViewModelInstanceBlob(
      ViewModelInstanceHandle,
      std::string path,
      BlobAssetHandle value,
      uint64_t requestId = 0);
  void setViewModelInstanceArtboard(
      ViewModelInstanceHandle,
      std::string path,
      ArtboardHandle value,
      uint64_t requestId = 0);
  void setViewModelInstanceNestedViewModel(
      ViewModelInstanceHandle,
      std::string path,
      ViewModelInstanceHandle value,
      uint64_t requestId = 0);
  void insertViewModelInstanceListViewModel(
      ViewModelInstanceHandle,
      std::string path,
      ViewModelInstanceHandle value,
      int index,
      uint64_t requestId = 0);

  void appendViewModelInstanceListViewModel(
      ViewModelInstanceHandle handle,
      std::string path,
      ViewModelInstanceHandle value,
      uint64_t requestId = 0)
  {
    insertViewModelInstanceListViewModel(
        handle,
        std::move(path),
        value,
        -1,
        requestId);
  }

  void removeViewModelInstanceListViewModel(
      ViewModelInstanceHandle,
      std::string path,
      int index,
      ViewModelInstanceHandle value = RIVE_NULL_HANDLE,
      uint64_t requestId = 0);

  void removeViewModelInstanceListViewModel(
      ViewModelInstanceHandle handle,
      std::string path,
      ViewModelInstanceHandle value,
      uint64_t requestId = 0)
  {
    removeViewModelInstanceListViewModel(
        handle,
        std::move(path),
        -1,
        value,
        requestId);
  }

  void swapViewModelInstanceListValues(
      ViewModelInstanceHandle handle,
      std::string path,
      int indexa,
      int indexb,
      uint64_t requestId = 0);

  void subscribeToViewModelProperty(
      ViewModelInstanceHandle handle,
      std::string path,
      DataType type,
      uint64_t requestId = 0);

  void unsubscribeToViewModelProperty(
      ViewModelInstanceHandle handle,
      std::string path,
      DataType type,
      uint64_t requestId = 0);

  void deleteViewModelInstance(ViewModelInstanceHandle, uint64_t requestId = 0);

  StateMachineHandle instantiateStateMachineNamed(
      ArtboardHandle,
      std::string name,
      StateMachineListener* listener = nullptr,
      uint64_t requestId = 0);
  StateMachineHandle instantiateDefaultStateMachine(
      ArtboardHandle artboardHandle,
      StateMachineListener* listener = nullptr,
      uint64_t requestId = 0)
  {
    return instantiateStateMachineNamed(
        artboardHandle,
        "",
        listener,
        requestId);
  }

  void bindViewModelInstance(
      StateMachineHandle,
      ViewModelInstanceHandle,
      uint64_t requestId = 0);

  // Sets the main (non-global) view model instance without rebinding. Call
  // bind() to apply.
  void setViewModelInstance(
      StateMachineHandle,
      ViewModelInstanceHandle,
      uint64_t requestId = 0);

  /**
   * Returns a handle to the main view model instance currently bound to the
   * state machine. This lookup never creates an instance.
   *
   * A successful lookup is reported through
   * StateMachineListener::onViewModelInstanceReceived. If no main instance
   * is bound, or if the state machine handle is invalid, the lookup reports
   * through StateMachineListener::onStateMachineError and the returned handle
   * maps to nothing.
   *
   * The optional ViewModelInstanceListener is associated with the returned
   * handle for subsequent view model instance operations. It is not notified
   * of lookup success or failure.
   *
   * @param stateMachineHandle The state machine whose main instance should
   * be retrieved.
   * @param listener The listener to associate with the returned view model
   * instance handle.
   * @param requestId The identifier reported with the asynchronous result.
   */
  ViewModelInstanceHandle mainViewModelInstance(
      StateMachineHandle stateMachineHandle,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  /**
   * Removes the main (non-global) view model instance from a state machine
   * without rebinding. Call bind() to create and apply its default main
   * instance.
   *
   * @param stateMachineHandle The state machine whose main instance should
   * be cleared.
   * @param requestId The identifier reported with any asynchronous error.
   */
  void clearViewModelInstance(
      StateMachineHandle stateMachineHandle,
      uint64_t requestId = 0);

  // Sets/replaces the global view model instance bound under the given global
  // view model name without rebinding. Call bind() to apply. Reports a state
  // machine error if the name does not match a global view model.
  void setGlobalViewModelInstance(
      StateMachineHandle,
      std::string name,
      ViewModelInstanceHandle,
      uint64_t requestId = 0);

  /**
   * Removes the instance occupying a named global slot without rebinding,
   * preserving the main instance and every other global slot. Call bind() to
   * create and apply that slot's default instance. Reports a state machine
   * error if name does not identify a global view model.
   *
   * @param stateMachineHandle The state machine whose global slot should be
   * cleared.
   * @param name The global view model slot to clear.
   * @param requestId The identifier reported with any asynchronous error.
   */
  void clearGlobalViewModelInstance(
      StateMachineHandle stateMachineHandle,
      std::string name,
      uint64_t requestId = 0);

  /**
   * Returns a handle to the global view model instance currently bound under
   * the given name. This lookup never creates an instance.
   *
   * A successful lookup is reported through
   * StateMachineListener::onViewModelInstanceReceived. If no instance is
   * bound under the name, or if the state machine handle is invalid, the
   * lookup reports through StateMachineListener::onStateMachineError and the
   * returned handle maps to nothing.
   *
   * The optional ViewModelInstanceListener is associated with the returned
   * handle for subsequent view model instance operations. It is not notified
   * of lookup success or failure.
   *
   * @param stateMachineHandle The state machine whose global instance should
   * be retrieved.
   * @param name The global view model name to look up.
   * @param listener The listener to associate with the returned view model
   * instance handle.
   * @param requestId The identifier reported with the asynchronous result.
   */
  ViewModelInstanceHandle globalViewModelInstance(
      StateMachineHandle stateMachineHandle,
      std::string name,
      ViewModelInstanceListener* listener = nullptr,
      uint64_t requestId = 0);

  /**
   * Applies the state machine's current data context to its artboard and
   * state machine data binds in a single pass. Any missing main or global
   * view model instances are created from their defaults before binding.
   * Reports a state machine error asynchronously if the handle is invalid.
   *
   * @param stateMachineHandle The state machine whose data context should be
   * applied.
   * @param requestId The identifier reported with any asynchronous error.
   */
  void bind(StateMachineHandle stateMachineHandle, uint64_t requestId = 0);

  void advanceStateMachine(
      StateMachineHandle,
      float timeToAdvance,
      uint64_t requestId = 0);

  // Enable the semantic subsystem on the given state machine. Must be
  // called before diffs are delivered. Safe to call multiple times.
  void enableSemantics(StateMachineHandle, uint64_t requestId = 0);

  // Drain the current semantic diff for the given state machine.
  // The response is delivered via
  // StateMachineListener::onSemanticsDiffReceived when the diff is non-empty.
  // Output bounds are mapped to view space using the provided fit/alignment/
  // scale/view-bounds parameters.
  void drainSemanticsDiff(
      StateMachineHandle,
      Fit fit,
      Alignment alignment,
      float scaleFactor,
      Vec2D viewBounds,
      uint64_t requestId = 0);

  // Pointer events
  struct PointerEvent
  {
    Fit fit = Fit::none;      // the fit the artboard is drawn with
    Alignment alignment;      // the alignment the artboard is drawn with
    Vec2D screenBounds;       // the bounds of coordinate system of the cursor
    Vec2D position;           // the cursor position
    float scaleFactor = 1.0f; // scale factor for things like retina display
    int pointerId = 0;        // stable pointer identifier for multitouch
    PointerButton button = PointerButton::primary; // mouse button for
                                                   // down/up events
  };

  // All pointer events will automatically convert between artboard and screen
  // space for you based on the values passed in the PointerEvent struct.

  void pointerMove(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
  void pointerDown(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
  void pointerUp(StateMachineHandle, PointerEvent, uint64_t requestId = 0);
  void pointerExit(StateMachineHandle, PointerEvent, uint64_t requestId = 0);

  /**
   * Enqueues a key event for the state machine's focused node and ancestors.
   * Reports consumption asynchronously through
   * StateMachineListener::onKeyInputHandled, or an invalid handle through
   * StateMachineListener::onStateMachineError. Printable text must be sent
   * separately with textInput; a key event does not insert its character.
   *
   * @param stateMachineHandle The state machine receiving the event.
   * @param key The Rive key code to dispatch.
   * @param modifiers The active modifier flags.
   * @param isPressed Whether the key is pressed rather than released.
   * @param isRepeat Whether this is a repeated key press.
   * @param requestId Identifier returned with the result or error.
   */
  void keyInput(
      StateMachineHandle stateMachineHandle,
      Key key,
      KeyModifiers modifiers,
      bool isPressed,
      bool isRepeat,
      uint64_t requestId = 0);

  /**
   * Enqueues committed UTF-8 text for the focused node and its ancestors.
   * A focused TextInput inserts it at the caret, replacing any selection.
   * Reports consumption asynchronously through
   * StateMachineListener::onTextInputHandled, or an invalid handle through
   * StateMachineListener::onStateMachineError. This does not set an IME
   * composing range or replace the field's entire value.
   *
   * @param stateMachineHandle The state machine receiving the text.
   * @param text The committed text, owned by the queue until dispatch.
   * @param requestId Identifier returned with the result or error.
   */
  void textInput(
      StateMachineHandle stateMachineHandle,
      std::string text,
      uint64_t requestId = 0);

  void deleteStateMachine(StateMachineHandle, uint64_t requestId = 0);

  // Fire a semantic action (tap / increase / decrease) on the given node.
  // Fire-and-forget; reports a stateMachineError if the handle is unknown or
  // semantics isn't enabled. An unknown node id is a silent no-op.
  void fireSemanticAction(
      StateMachineHandle,
      uint32_t semanticNodeId,
      SemanticActionType actionType,
      uint64_t requestId = 0);

  // Request focus on the given semantic node. Fire-and-forget; reports a
  // stateMachineError if the handle is unknown or semantics isn't enabled.
  // An unknown or non-focusable node id is a silent no-op.
  void requestSemanticFocus(
      StateMachineHandle,
      uint32_t semanticNodeId,
      uint64_t requestId = 0);

  // Clear all semantic focus. Called when the screen reader moves
  // focus entirely away from the hosting view.
  void clearSemanticFocus(StateMachineHandle, uint64_t requestId = 0);

  RenderImageHandle decodeImage(
      std::vector<uint8_t> imageEncodedBytes,
      RenderImageListener* listener = nullptr,
      uint64_t requestId = 0);
  // This is needed for unreal rhi because all images come pre-decoded and
  // uploaded to gpu.
  RenderImageHandle addExternalImage(
      rcp<RenderImage> externalImage,
      RenderImageListener* listener = nullptr,
      uint64_t requestId = 0);

  void deleteImage(RenderImageHandle, uint64_t requestId = 0);

  AudioSourceHandle decodeAudio(
      std::vector<uint8_t> imageEncodedBytes,
      AudioSourceListener* listener = nullptr,
      uint64_t requestId = 0);

  AudioSourceHandle addExternalAudio(
      rcp<AudioSource> externalAudio,
      AudioSourceListener* listener = nullptr,
      uint64_t requestId = 0);

  void deleteAudio(AudioSourceHandle, uint64_t requestId = 0);

  FontHandle decodeFont(
      std::vector<uint8_t> imageEncodedBytes,
      FontListener* listener = nullptr,
      uint64_t requestId = 0);

  FontHandle addExternalFont(
      rcp<Font> externalFont,
      FontListener* listener = nullptr,
      uint64_t requestId = 0);

  void deleteFont(FontHandle, uint64_t requestId = 0);

  BlobAssetHandle decodeBlob(
      std::vector<uint8_t> blobBytes,
      BlobAssetListener* listener = nullptr,
      uint64_t requestId = 0);

  BlobAssetHandle addExternalBlob(
      rcp<BlobAsset> externalBlob,
      BlobAssetListener* listener = nullptr,
      uint64_t requestId = 0);

  void deleteBlob(BlobAssetHandle, uint64_t requestId = 0);

  // Create unique draw key for draw.
  DrawKey createDrawKey();

  /**
   * Executes a one-time callback directly on the command server.
   *
   * This is an escape hatch for tests and runtime-specific operations that
   * cannot be represented by the shared command and message protocol. Do not
   * use it to implement capabilities common to multiple runtimes; add a
   * canonical command, message, and listener callback instead.
   *
   * @param callback The callback to execute on the command server.
   */
  void runOnce(CommandServerCallback);

  // Run draw function for given draw key, only the latest function passed
  // will be run per pollCommands.
  void draw(DrawKey, CommandServerDrawCallback);

  // Cancel a pending draw for the given key if it has already been admitted
  // to the current coalesced draw batch.
  void cancelDraw(DrawKey);

#ifdef TESTING
  // Sends a commandLoopBreak command to the server. This will cause the
  // processCommands to return even if there are more commands to consume.
  // This does not shutdown the server, it only causes processCommands to
  // return. To continue processing commands, another call to processCommands
  // is required.
  void testing_commandLoopBreak();
  FileListener* testing_getFileListener(FileHandle);
  ArtboardListener* testing_getArtboardListener(ArtboardHandle);
  StateMachineListener* testing_getStateMachineListener(StateMachineHandle);
#endif

  void disconnect();

  void requestViewModelNames(FileHandle, uint64_t requestId = 0);
  void requestGlobalViewModelNames(FileHandle, uint64_t requestId = 0);
  void requestArtboardNames(FileHandle, uint64_t requestId = 0);
  void requestFileAssets(FileHandle, uint64_t requestId = 0);
  void requestViewModelEnums(FileHandle, uint64_t requestId = 0);
  void requestViewModelPropertyDefinitions(
      FileHandle,
      std::string viewModelName,
      uint64_t requestId = 0);

  void requestViewModelInstanceNames(
      FileHandle,
      std::string viewModelName,
      uint64_t requestId = 0);

  void requestViewModelInstanceViewModelName(
      ViewModelInstanceHandle,
      uint64_t requestId = 0);

  void requestViewModelInstanceName(
      ViewModelInstanceHandle handle,
      uint64_t requestId = 0);

  void requestViewModelInstanceBool(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceNumber(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceColor(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceEnum(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceString(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceListSize(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void requestViewModelInstanceListClear(
      ViewModelInstanceHandle,
      std::string path,
      uint64_t requestId = 0);

  void setArtboardVolume(ArtboardHandle, float volume, uint64_t requestId = 0);
  void requestArtboardVolume(ArtboardHandle, uint64_t requestId = 0);

  void requestArtboardSize(ArtboardHandle, uint64_t requestId = 0);
  void requestStateMachineNames(ArtboardHandle, uint64_t requestId = 0);
  void requestDefaultViewModelInfo(
      ArtboardHandle,
      FileHandle,
      uint64_t requestId = 0);

  // Consume all messages received from the server.
  void processMessages();

  void setGlobalFileListener(FileListener* listener)
  {
    m_globalFileListener = listener;
  }
  void setGlobalArtboardListener(ArtboardListener* listener)
  {
    m_globalArtboardListener = listener;
  }
  void setGlobalStateMachineListener(StateMachineListener* listener)
  {
    m_globalStateMachineListener = listener;
  }
  void setGlobalViewModelInstanceListener(ViewModelInstanceListener* listener)
  {
    m_globalViewModelListener = listener;
  }
  void setGlobalRenderImageListener(RenderImageListener* listener)
  {
    m_globalImageListener = listener;
  }
  void setGlobalAudioSourceListener(AudioSourceListener* listener)
  {
    m_globalAudioListener = listener;
  }
  void setGlobalFontListener(FontListener* listener)
  {
    m_globalFontListener = listener;
  }
  void setGlobalBlobAssetListener(BlobAssetListener* listener)
  {
    m_globalBlobListener = listener;
  }

  bool focusNextSynchronized(StateMachineHandle);
  bool focusPreviousSynchronized(StateMachineHandle);
  void focusNext(StateMachineHandle, uint64_t requestId = 0);
  void focusPrevious(StateMachineHandle, uint64_t requestId = 0);
  void requestHasFocusNodes(StateMachineHandle, uint64_t requestId = 0);
  void clearFocus(StateMachineHandle, uint64_t requestId = 0);
  void requestFocusState(StateMachineHandle, uint64_t requestId = 0);

  /**
   * Synchronously traverses forward and captures the resulting focus state.
   * A traversal that does not move may still retain focus, such as at a stop
   * boundary. The returned state distinguishes retained focus from exit.
   *
   * @param stateMachineHandle The state machine whose focus tree to traverse.
   * @return Movement and post-traversal state, or a default-initialized
   * result if the state machine does not exist.
   */
  FocusTraversalResult focusNextWithResultSynchronized(
      StateMachineHandle stateMachineHandle);

  /**
   * Synchronously traverses backward and captures the resulting focus state.
   * A traversal that does not move may still retain focus, such as at a stop
   * boundary. The returned state distinguishes retained focus from exit.
   *
   * @param stateMachineHandle The state machine whose focus tree to traverse.
   * @return Movement and post-traversal state, or a default-initialized
   * result if the state machine does not exist.
   */
  FocusTraversalResult focusPreviousWithResultSynchronized(
      StateMachineHandle stateMachineHandle);

  /**
   * Delivers a key synchronously to the focused node and its ancestors.
   *
   * @param stateMachineHandle The state machine receiving the event.
   * @param key The Rive key code to dispatch.
   * @param modifiers The active modifier flags.
   * @param isPressed Whether the key is pressed rather than released.
   * @param isRepeat Whether this is a repeated key press.
   * @return Whether the event was handled. Returns false for a missing
   * state machine or when no focused node or ancestor handles the event.
   */
  bool keyInputSynchronized(
      StateMachineHandle stateMachineHandle,
      Key key,
      KeyModifiers modifiers,
      bool isPressed,
      bool isRepeat);

  /**
   * Synchronously attempts spatial focus traversal in the given direction.
   *
   * @param stateMachineHandle The state machine whose focus tree to traverse.
   * @param direction The direction in root artboard space.
   * @return Whether traversal moved focus. Returns false for a missing
   * state machine, missing focus manager, or unsuccessful traversal.
   */
  bool focusInDirectionSynchronized(
      StateMachineHandle stateMachineHandle,
      Direction direction);

  /**
   * Sets the listener for runtime-defined command server messages.
   *
   * Registration is non-owning. The listener must remain alive until it is
   * replaced or cleared and any callback in progress has completed. Calls to
   * this setter must be serialized with processMessages(), typically by
   * using the same thread.
   *
   * The listener registered when a message is processed receives it. Messages
   * processed without a listener are discarded, not retained for a later
   * registration.
   *
   * @param listener Listener to receive runtime messages, or nullptr to clear
   * the listener.
   */
  void setGlobalRuntimeMessageListener(RuntimeMessageListener* listener)
  {
    m_globalRuntimeMessageListener = listener;
  }

private:
  void registerListener(FileHandle handle, FileListener* listener)
  {
    assert(listener);
    assert(m_fileListeners.find(handle) == m_fileListeners.end());
    m_fileListeners.insert({handle, listener});
  }

  void registerListener(RenderImageHandle handle, RenderImageListener* listener)
  {
    assert(listener);
    assert(m_imageListeners.find(handle) == m_imageListeners.end());
    m_imageListeners.insert({handle, listener});
  }

  void registerListener(AudioSourceHandle handle, AudioSourceListener* listener)
  {
    assert(listener);
    assert(m_audioListeners.find(handle) == m_audioListeners.end());
    m_audioListeners.insert({handle, listener});
  }

  void registerListener(FontHandle handle, FontListener* listener)
  {
    assert(listener);
    assert(m_fontListeners.find(handle) == m_fontListeners.end());
    m_fontListeners.insert({handle, listener});
  }

  void registerListener(BlobAssetHandle handle, BlobAssetListener* listener)
  {
    assert(listener);
    assert(m_blobListeners.find(handle) == m_blobListeners.end());
    m_blobListeners.insert({handle, listener});
  }

  void registerListener(ArtboardHandle handle, ArtboardListener* listener)
  {
    assert(listener);
    assert(m_artboardListeners.find(handle) == m_artboardListeners.end());
    m_artboardListeners.insert({handle, listener});
  }

  void registerListener(
      ViewModelInstanceHandle handle,
      ViewModelInstanceListener* listener)
  {
    assert(listener);
    assert(m_viewModelListeners.find(handle) == m_viewModelListeners.end());
    m_viewModelListeners.insert({handle, listener});
  }

  void registerListener(
      StateMachineHandle handle,
      StateMachineListener* listener)
  {
    assert(listener);
    assert(
        m_stateMachineListeners.find(handle) == m_stateMachineListeners.end());
    m_stateMachineListeners.insert({handle, listener});
  }

  // On 32-bit architectures, Handles are all uint64_t (not unique types), so
  // it will think we are re-declaring unregisterListener 3 times if we don't
  // add the listener pointer (even though it is not needed).

  void unregisterListener(FileHandle handle, FileListener* listener)
  {
    m_fileListeners.erase(handle);
  }

  void unregisterListener(
      RenderImageHandle handle,
      RenderImageListener* listener)
  {
    m_imageListeners.erase(handle);
  }

  void unregisterListener(
      AudioSourceHandle handle,
      AudioSourceListener* listener)
  {
    m_audioListeners.erase(handle);
  }

  void unregisterListener(FontHandle handle, FontListener* listener)
  {
    m_fontListeners.erase(handle);
  }

  void unregisterListener(BlobAssetHandle handle, BlobAssetListener* listener)
  {
    m_blobListeners.erase(handle);
  }

  void unregisterListener(ArtboardHandle handle, ArtboardListener* listener)
  {
    m_artboardListeners.erase(handle);
  }

  void unregisterListener(
      ViewModelInstanceHandle handle,
      ViewModelInstanceListener* listener)
  {
    m_viewModelListeners.erase(handle);
  }

  void unregisterListener(
      StateMachineHandle handle,
      StateMachineListener* listener)
  {
    m_stateMachineListeners.erase(handle);
  }

  enum class Command
  {
    loadFile,
    deleteFile,
    decodeImage,
    externalImage,
    decodeAudio,
    externalAudio,
    decodeFont,
    externalFont,
    decodeBlob,
    externalBlob,
    deleteImage,
    deleteAudio,
    deleteFont,
    deleteBlob,
    addImageFileAsset,
    addAudioFileAsset,
    addFontFileAsset,
    removeImageFileAsset,
    removeAudioFileAsset,
    removeFontFileAsset,
    instantiateArtboard,
    deleteArtboard,
    setArtboardSize,
    resetArtboardSize,
    instantiateViewModel,
    refNestedViewModel,
    refListViewModel,
    instantiateBlankViewModel,
    instantiateViewModelForArtboard,
    instantiateBlankViewModelForArtboard,
    setViewModelInstanceValue,
    addViewModelListValue,
    removeViewModelListValue,
    swapViewModelListValue,
    subscribeViewModelProperty,
    unsubscribeViewModelProperty,
    deleteViewModel,
    instantiateStateMachine,
    deleteStateMachine,
    advanceStateMachine,
    enableSemantics,
    drainSemanticsDiff,
    fireSemanticAction,
    requestSemanticFocus,
    clearSemanticFocus,
    bindViewModelInstance,
    setViewModelInstance,
    getMainViewModelInstance,
    clearViewModelInstance,
    setGlobalViewModelInstance,
    clearGlobalViewModelInstance,
    getGlobalViewModelInstance,
    bind,
    runOnce,
    draw,
    cancelDraw,
    pointerMove,
    pointerDown,
    pointerUp,
    pointerExit,
    keyInput,
    textInput,
    disconnect,
    // This will cause processCommands to return once received. We want to
    // ensure that we do not indefinetly block the calling thread. This is
    // how we achieve that.
    commandLoopBreak,
    // messages
    listViewModelEnums,
    listArtboards,
    listStateMachines,
    getDefaultViewModel,
    listViewModels,
    listGlobalViewModelNames,
    listViewModelInstanceNames,
    listViewModelProperties,
    listViewModelPropertyValue,
    getViewModelInstanceViewModelName,
    getViewModelInstanceName,
    getViewModelListSize,
    clearViewModelList,
    listFileAssets,
    setArtboardVolume,
    getArtboardVolume,
    getArtboardSize,
    focusNext,
    focusPrevious,
    requestHasFocusNodes,
    clearFocus,
    requestFocusState
  };

  enum class Message
  {
    // Same as commandLoopBreak for processMessages
    messageLoopBreak,
    viewModelEnumsListed,
    artboardsListed,
    stateMachinesListed,
    defaultViewModelReceived,
    viewModelInstanceViewModelNameReceived,
    viewModelInstanceNameReceived,
    viewModelsListend,
    globalViewModelNamesListed,
    viewModelInstanceNamesListed,
    viewModelPropertiesListed,
    viewModelPropertyValueReceived,
    viewModelListSizeReceived,
    viewModelListCleared,
    fileLoaded,
    fileDeleted,
    artboardInstantiated,
    stateMachineInstantiated,
    viewModelInstanceInstantiated,
    imageDecoded,
    imageDeleted,
    audioDecoded,
    audioDeleted,
    fontDecoded,
    fontDeleted,
    blobDecoded,
    blobDeleted,
    artboardDeleted,
    viewModelDeleted,
    stateMachineDeleted,
    stateMachineSettled,
    stateMachineViewModelInstanceReceived,
    keyInputHandled,
    textInputHandled,
    semanticsDiffReceived,
    fileAssetsListed,
    artboardSizeReceived,
    fileError,
    artboardError,
    viewModelError,
    imageError,
    audioError,
    fontError,
    blobError,
    stateMachineError,
    artboardVolumeReceived,
    hasFocusNodesReceived,
    focusStateReceived,
    runtimeMessage
  };

  friend class CommandServer;

  uint64_t m_currentFileHandleIdx = 0;
  uint64_t m_currentListHandleIdx = 0;
  uint64_t m_currentFontHandleIdx = 0;
  uint64_t m_currentArtboardHandleIdx = 0;
  uint64_t m_currentViewModelHandleIdx = 0;
  uint64_t m_currentRenderImageHandleIdx = 0;
  uint64_t m_currentBlobAssetHandleIdx = 0;
  uint64_t m_currentAudioSourceHandleIdx = 0;
  uint64_t m_currentStateMachineHandleIdx = 0;
  uint64_t m_currentDrawKeyIdx = 0;

  std::mutex m_commandMutex;
  std::condition_variable m_commandConditionVariable;
  PODStream m_commandStream;
  ObjectStream<rcp<RenderImage>> m_externalImages;
  ObjectStream<rcp<AudioSource>> m_externalAudioSources;
  ObjectStream<rcp<Font>> m_externalFonts;
  ObjectStream<rcp<BlobAsset>> m_externalBlobs;
  ObjectStream<std::vector<uint8_t>> m_byteVectors;
#ifdef WITH_RIVE_SCRIPTING
  ObjectStream<ScriptingContextFactory> m_scriptingContextFactories;
#endif
  ObjectStream<PointerEvent> m_pointerEvents;
  ObjectStream<std::string> m_names;
  ObjectStream<CommandServerCallback> m_callbacks;
  ObjectStream<CommandServerDrawCallback> m_drawCallbacks;

  // Messages streams
  std::mutex m_messageMutex;
  PODStream m_messageStream;
  ObjectStream<std::string> m_messageNames;
  ObjectStream<std::vector<uint8_t>> m_messageByteVectors;
  ObjectStream<SemanticsDiff> m_messageSemanticsDiffs;

  // Listeners
  FileListener* m_globalFileListener = nullptr;
  RenderImageListener* m_globalImageListener = nullptr;
  AudioSourceListener* m_globalAudioListener = nullptr;
  FontListener* m_globalFontListener = nullptr;
  BlobAssetListener* m_globalBlobListener = nullptr;
  ArtboardListener* m_globalArtboardListener = nullptr;
  ViewModelInstanceListener* m_globalViewModelListener = nullptr;
  StateMachineListener* m_globalStateMachineListener = nullptr;
  RuntimeMessageListener* m_globalRuntimeMessageListener = nullptr;

  std::unordered_map<FileHandle, FileListener*> m_fileListeners;
  std::unordered_map<RenderImageHandle, RenderImageListener*> m_imageListeners;
  std::unordered_map<AudioSourceHandle, AudioSourceListener*> m_audioListeners;
  std::unordered_map<FontHandle, FontListener*> m_fontListeners;
  std::unordered_map<BlobAssetHandle, BlobAssetListener*> m_blobListeners;
  std::unordered_map<ArtboardHandle, ArtboardListener*> m_artboardListeners;
  std::unordered_map<ViewModelInstanceHandle, ViewModelInstanceListener*>
      m_viewModelListeners;
  std::unordered_map<StateMachineHandle, StateMachineListener*>
      m_stateMachineListeners;
};

}; // namespace rive
