ladybird/Userland/DevTools/Profiler/FilesystemEventModel.cpp
Linus Groh 57dc179b1f Everywhere: Rename to_{string => deprecated_string}() where applicable
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.

One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
2022-12-06 08:54:33 +01:00

190 lines
4.8 KiB
C++

/*
* Copyright (c) 2022, Jakub Berkop <jakub.berkop@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "FilesystemEventModel.h"
#include "Profile.h"
#include <AK/StringBuilder.h>
#include <LibGUI/FileIconProvider.h>
#include <LibSymbolication/Symbolication.h>
#include <stdio.h>
namespace Profiler {
FileEventModel::FileEventModel(Profile& profile)
: m_profile(profile)
{
}
FileEventModel::~FileEventModel()
{
}
FileEventNode& FileEventNode::find_or_create_node(DeprecatedString const& searched_path)
{
// TODO: Optimize this function.
if (searched_path == ""sv) {
return *this;
}
auto lex_path = LexicalPath(searched_path);
auto parts = lex_path.parts();
auto current = parts.take_first();
StringBuilder sb;
sb.join('/', parts);
auto new_s = sb.to_deprecated_string();
for (auto& child : m_children) {
if (child->m_path == current) {
return child->find_or_create_node(new_s);
}
}
if (m_parent) {
for (auto& child : m_children) {
if (child->m_path == current) {
return child->find_or_create_node(new_s);
}
}
return create_recursively(searched_path);
} else {
if (!searched_path.starts_with("/"sv)) {
m_children.append(create(searched_path, this));
return *m_children.last();
}
return create_recursively(searched_path);
}
}
FileEventNode& FileEventNode::create_recursively(DeprecatedString new_path)
{
auto const lex_path = LexicalPath(new_path);
auto parts = lex_path.parts();
if (parts.size() == 1) {
auto new_node = FileEventNode::create(new_path, this);
m_children.append(new_node);
return *new_node.ptr();
} else {
auto new_node = FileEventNode::create(parts.take_first(), this);
m_children.append(new_node);
StringBuilder sb;
sb.join('/', parts);
return new_node->create_recursively(sb.to_deprecated_string());
}
}
void FileEventNode::for_each_parent_node(Function<void(FileEventNode&)> callback)
{
auto* current = this;
while (current) {
callback(*current);
current = current->m_parent;
}
}
GUI::ModelIndex FileEventModel::index(int row, int column, GUI::ModelIndex const& parent) const
{
if (!parent.is_valid()) {
return create_index(row, column, m_profile.file_event_nodes()->children()[row].ptr());
}
auto& remote_parent = *static_cast<FileEventNode*>(parent.internal_data());
return create_index(row, column, remote_parent.children().at(row).ptr());
}
GUI::ModelIndex FileEventModel::parent_index(GUI::ModelIndex const& index) const
{
if (!index.is_valid())
return {};
auto& node = *static_cast<FileEventNode*>(index.internal_data());
if (!node.parent())
return {};
if (node.parent()->parent()) {
auto const& children = node.parent()->parent()->children();
for (size_t row = 0; row < children.size(); ++row) {
if (children.at(row).ptr() == node.parent()) {
return create_index(row, index.column(), node.parent());
}
}
}
auto const& children = node.parent()->children();
for (size_t row = 0; row < children.size(); ++row) {
if (children.at(row).ptr() == &node) {
return create_index(row, index.column(), node.parent());
}
}
VERIFY_NOT_REACHED();
return {};
}
int FileEventModel::row_count(GUI::ModelIndex const& index) const
{
if (!index.is_valid())
return m_profile.file_event_nodes()->children().size();
auto& node = *static_cast<FileEventNode*>(index.internal_data());
return node.children().size();
}
int FileEventModel::column_count(GUI::ModelIndex const&) const
{
return Column::__Count;
}
DeprecatedString FileEventModel::column_name(int column) const
{
switch (column) {
case Column::Path:
return "Path";
case Column::Count:
return "Event Count";
case Column::Duration:
return "Duration [ms]";
default:
VERIFY_NOT_REACHED();
return {};
}
}
GUI::Variant FileEventModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
{
if (role == GUI::ModelRole::TextAlignment) {
if (index.column() == Path)
return Gfx::TextAlignment::CenterLeft;
return Gfx::TextAlignment::CenterRight;
}
auto* node = static_cast<FileEventNode*>(index.internal_data());
if (role == GUI::ModelRole::Display) {
if (index.column() == Column::Count) {
return node->count();
}
if (index.column() == Column::Path) {
return node->path();
}
if (index.column() == Column::Duration) {
return node->duration();
}
return {};
}
return {};
}
}