view lldb/tools/lldb-vscode/ProgressEvent.cpp @ 213:25ca0248ac32

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 11 Jul 2021 17:05:31 +0900
parents 2e18cbf3894f
children 5f17cb93ff66
line wrap: on
line source

//===-- ProgressEvent.cpp ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ProgressEvent.h"

#include "JSONUtils.h"

using namespace lldb_vscode;
using namespace llvm;

ProgressEvent::ProgressEvent(uint64_t progress_id, const char *message,
                             uint64_t completed, uint64_t total)
    : m_progress_id(progress_id), m_message(message) {
  if (completed == total)
    m_event_type = progressEnd;
  else if (completed == 0)
    m_event_type = progressStart;
  else if (completed < total)
    m_event_type = progressUpdate;
  else
    m_event_type = progressInvalid;

  if (0 < total && total < UINT64_MAX)
    m_percentage = (uint32_t)(((float)completed / (float)total) * 100.0);
}

bool ProgressEvent::operator==(const ProgressEvent &other) const {
  return m_progress_id == other.m_progress_id &&
         m_event_type == other.m_event_type &&
         m_percentage == other.m_percentage;
}

const char *ProgressEvent::GetEventName() const {
  if (m_event_type == progressStart)
    return "progressStart";
  else if (m_event_type == progressEnd)
    return "progressEnd";
  else if (m_event_type == progressUpdate)
    return "progressUpdate";
  else
    return "progressInvalid";
}

bool ProgressEvent::IsValid() const { return m_event_type != progressInvalid; }

uint64_t ProgressEvent::GetID() const { return m_progress_id; }

json::Value ProgressEvent::ToJSON() const {
  llvm::json::Object event(CreateEventObject(GetEventName()));
  llvm::json::Object body;

  std::string progress_id_str;
  llvm::raw_string_ostream progress_id_strm(progress_id_str);
  progress_id_strm << m_progress_id;
  progress_id_strm.flush();
  body.try_emplace("progressId", progress_id_str);

  if (m_event_type == progressStart) {
    EmplaceSafeString(body, "title", m_message);
    body.try_emplace("cancellable", false);
  }

  auto now = std::chrono::duration<double>(
      std::chrono::system_clock::now().time_since_epoch());
  std::string timestamp(llvm::formatv("{0:f9}", now.count()));
  EmplaceSafeString(body, "timestamp", timestamp);

  if (m_percentage)
    body.try_emplace("percentage", *m_percentage);

  event.try_emplace("body", std::move(body));
  return json::Value(std::move(event));
}

ProgressEventFilterQueue::ProgressEventFilterQueue(
    std::function<void(ProgressEvent)> callback)
    : m_callback(callback) {}

void ProgressEventFilterQueue::Push(const ProgressEvent &event) {
  if (!event.IsValid())
    return;

  auto it = m_last_events.find(event.GetID());
  if (it == m_last_events.end() || !(it->second == event)) {
    m_last_events[event.GetID()] = event;
    m_callback(event);
  }
}