variable WIP

This commit is contained in:
T0b1
2023-06-21 02:10:16 +02:00
parent a4217e76d2
commit 88a33bf437
3 changed files with 200 additions and 50 deletions

View File

@@ -2948,7 +2948,7 @@ std::optional<dbgui::data::result::NodeIdx>
if (_var_cache[*cache_entry].used)
{
// was already diffed
return *cache_entry;
return *_var_cache[*cache_entry].cached_node;
}
auto node_idx = *_var_cache[*cache_entry].cached_node;
_var_cache[*cache_entry].used = true;

View File

@@ -1025,7 +1025,8 @@ bool WatchWindow::draw(Frontend &frontend)
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::PushID("TTTTTT");
if (ImGui::TreeNodeEx("Locals", ImGuiTreeNodeFlags_SpanFullWidth))
if (ImGui::TreeNodeEx("Locals", ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_DefaultOpen))
{
auto locals_idx =
frontend.target->data_idx_for_src_id(this->locals_src_id);
@@ -1064,60 +1065,65 @@ bool WatchWindow::draw(Frontend &frontend)
}
ImGui::PopID();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::InputText("##EXTRASLOT", this->extra_slot_path_buf,
sizeof(this->extra_slot_path_buf),
ImGuiInputTextFlags_AutoSelectAll
| ImGuiInputTextFlags_EnterReturnsTrue)
&& ImGui::IsItemDeactivatedAfterEdit())
for (size_t i = 0; i < extra_slots.size(); ++i)
{
if (this->extra_slot_bak != this->extra_slot_path_buf)
{
if (this->extra_slot_id)
{
frontend.target->backend->remove_data_node(*this->extra_slot_id);
this->extra_slot_id = {};
}
this->extra_slot_bak = this->extra_slot_path_buf;
if (this->extra_slot_bak != "")
{
auto id = frontend.target->data_node_id++;
this->extra_slot_id = id;
using namespace data::source;
frontend.target->backend->add_data_node(
Node{.id = id,
.type = Node::Type::source,
.data = Source{.type = Source::Type::variable,
.data = Source::Variable{
.expr_path = this->extra_slot_bak}}});
}
}
}
if (this->extra_slot_id)
{
auto res_idx = frontend.target->data_idx_for_src_id(*this->extra_slot_id);
auto res_idx = frontend.target->data_idx_for_src_id(extra_slots[i].id);
if (res_idx)
{
const auto &node = *frontend.target->data_res_nodes[*res_idx];
if (!node.success || node.children.size() != 1)
{
// TODO: allow edit
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("%s", extra_slots[i].bak.c_str());
ImGui::TableNextColumn();
ImGui::TextDisabled("<not available>");
} else
{
//printf("Extratypeid: %u", node.type_id.type);
const auto &child_node =
*frontend.target->data_res_nodes[node.children[0]];
//printf("Child: %u\n", child_node.type_id.type);
this->draw_value(frontend, child_node.type_id, this->extra_slot_bak,
this->draw_value(frontend, child_node.type_id, &extra_slots[i],
node.children[0], 0);
if (extra_slots[i].bak == "")
{
frontend.target->backend->remove_data_node(extra_slots[i].id);
extra_slots.erase(extra_slots.begin() + i);
--i;
continue;
}
}
}
}
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::InputText("##EXTRASLOT", this->add_slot_buf,
sizeof(this->add_slot_buf),
ImGuiInputTextFlags_AutoSelectAll
| ImGuiInputTextFlags_EnterReturnsTrue)
&& ImGui::IsItemDeactivatedAfterEdit())
{
if (this->add_slot_buf[0] != '\0')
{
auto id = frontend.target->data_node_id++;
using namespace data::source;
frontend.target->backend->add_data_node(Node{
.id = id,
.type = Node::Type::source,
.data =
Source{.type = Source::Type::variable,
.data = Source::Variable{.expr_path = this->add_slot_buf}}});
extra_slots.push_back(ExtraSlot{.id = id, .bak = this->add_slot_buf});
memcpy(extra_slots.back().buf, this->add_slot_buf,
sizeof(this->add_slot_buf));
this->add_slot_buf[0] = '\0';
}
}
ImGui::EndTable();
}
@@ -1128,15 +1134,26 @@ bool WatchWindow::draw(Frontend &frontend)
void WatchWindow::draw_value(Frontend &frontend,
data::type_info::TypeID type_id,
std::string_view name,
std::variant<std::string_view, ExtraSlot *> name,
data::result::NodeIdx node_idx, size_t off)
{
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
const char *name_begin, *name_end;
if (name.index() == 0)
{
name_begin = std::get<std::string_view>(name).begin();
name_end = std::get<std::string_view>(name).end();
} else
{
name_begin = &*std::get<ExtraSlot *>(name)->bak.begin();
name_end = &*std::get<ExtraSlot *>(name)->bak.end();
}
const auto &node_opt = frontend.target->data_res_nodes[node_idx];
if (!node_opt || !node_opt->success)
{
ImGui::TextUnformatted(name.begin(), name.end());
ImGui::TextUnformatted(name_begin, name_end);
ImGui::TableNextColumn();
ImGui::TextDisabled("<unavailable>");
return;
@@ -1154,26 +1171,89 @@ void WatchWindow::draw_value(Frontend &frontend,
auto pop_id = false;
if (type_id.type == Type::complex || type_id.type == Type::array)
{
ImGui::PushID(name.begin(), name.end());
ImGui::PushID(name_begin, name_end);
pop_id = true;
tree_open =
ImGui::TreeNodeEx((void *)node_idx, ImGuiTreeNodeFlags_SpanFullWidth,
"%.*s", static_cast<int>(name.size()), name.data());
char tree_id_buf[128];
std::snprintf(tree_id_buf, sizeof(tree_id_buf), "%u#off%lu", node_idx, off);
auto is_editing = false;
if (name.index() == 1)
{
auto *slot = std::get<ExtraSlot *>(name);
if (slot->is_editing)
{
is_editing = true;
ImGui::BeginDisabled();
tree_open = ImGui::TreeNodeEx(tree_id_buf, 0, "");
ImGui::EndDisabled();
ImGui::SameLine();
if (slot->edit_was_started)
{
slot->edit_was_started = false;
ImGui::SetKeyboardFocusHere();
}
if (ImGui::InputText("##dddd", slot->buf, sizeof(slot->buf),
ImGuiInputTextFlags_AutoSelectAll
| ImGuiInputTextFlags_EnterReturnsTrue)
&& ImGui::IsItemDeactivatedAfterEdit())
{
if (slot->buf[0] != '\0')
{
frontend.target->backend->remove_data_node(slot->id);
using namespace data::source;
frontend.target->backend->add_data_node(
Node{.id = slot->id,
.type = Node::Type::source,
.data =
Source{.type = Source::Type::variable,
.data = Source::Variable{.expr_path = slot->buf}}});
}
slot->bak = slot->buf;
slot->is_editing = false;
}
if (ImGui::IsItemDeactivated())
{
slot->is_editing = false;
}
}
}
if (!is_editing)
{
tree_open =
ImGui::TreeNodeEx(tree_id_buf, ImGuiTreeNodeFlags_SpanFullWidth, "%.*s",
static_cast<int>(name_end - name_begin), name_begin);
if (name.index() == 1
&& ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)
&& ImGui::IsItemHovered())
{
auto *slot = std::get<ExtraSlot *>(name);
slot->is_editing = true;
slot->edit_was_started = true;
}
}
if (tree_open)
{
if (type_id.type == Type::complex)
{
char tree_id_buf[128];
const auto &members = frontend.target->types[type_id.idx].member_vec();
for (size_t i = 0; i < members.size(); ++i)
{
const auto &member = members[i];
if (member.bitfield_size)
{
std::snprintf(tree_id_buf, sizeof(tree_id_buf), "%u#member%lu",
node_idx, i);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("%s", member.name.c_str());
ImGui::TreeNodeEx(tree_id_buf,
ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_Leaf
| ImGuiTreeNodeFlags_NoTreePushOnOpen,
"%s", member.name.c_str());
ImGui::TableNextColumn();
auto member_type = member.type_id;
@@ -1259,7 +1339,67 @@ void WatchWindow::draw_value(Frontend &frontend,
ImGui::PopID();
} else
{
ImGui::TextUnformatted(name.begin(), name.end());
auto is_editing = false;
if (name.index() == 1)
{
auto *slot = std::get<ExtraSlot *>(name);
if (slot->is_editing)
{
is_editing = true;
if (slot->edit_was_started)
{
slot->edit_was_started = false;
ImGui::SetKeyboardFocusHere();
}
if (ImGui::InputText("##dddd", slot->buf, sizeof(slot->buf),
ImGuiInputTextFlags_AutoSelectAll
| ImGuiInputTextFlags_EnterReturnsTrue)
&& ImGui::IsItemDeactivatedAfterEdit())
{
if (slot->buf[0] != '\0')
{
frontend.target->backend->remove_data_node(slot->id);
using namespace data::source;
frontend.target->backend->add_data_node(
Node{.id = slot->id,
.type = Node::Type::source,
.data =
Source{.type = Source::Type::variable,
.data = Source::Variable{.expr_path = slot->buf}}});
}
slot->bak = slot->buf;
slot->is_editing = false;
}
if (ImGui::IsItemDeactivated())
{
slot->is_editing = false;
}
}
}
if (!is_editing)
{
char tree_id_buf[128];
std::snprintf(tree_id_buf, sizeof(tree_id_buf), "%u#off%lu", node_idx,
off);
// TODO: better id
ImGui::TreeNodeEx(
tree_id_buf,
ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf
| ImGuiTreeNodeFlags_NoTreePushOnOpen,
"%.*s", static_cast<int>(name_end - name_begin), name_begin);
//ImGui::TextUnformatted(name_begin, name_end);
if (name.index() == 1
&& ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)
&& ImGui::IsItemHovered())
{
auto *slot = std::get<ExtraSlot *>(name);
slot->is_editing = true;
slot->edit_was_started = true;
}
}
ImGui::TableSetColumnIndex(1);
switch (type_id.type)
{

View File

@@ -126,8 +126,18 @@ namespace dbgui::frontend
struct WatchWindow
{
struct ExtraSlot
{
size_t id;
char buf[256];
std::string bak;
bool is_editing = false;
bool edit_was_started = false;
};
bool draw(Frontend &);
void draw_value(Frontend &, data::type_info::TypeID, std::string_view name,
void draw_value(Frontend &, data::type_info::TypeID,
std::variant<std::string_view, ExtraSlot *> name,
data::result::NodeIdx node_idx, size_t off);
// void handle_source_updated(Target& target, size_t id);
@@ -136,9 +146,9 @@ namespace dbgui::frontend
bool first;
size_t locals_src_id;
std::optional<size_t> extra_slot_id;
char extra_slot_path_buf[256] = {0};
std::string extra_slot_bak = "";
std::vector<ExtraSlot> extra_slots;
char add_slot_buf[256] = {};
};
struct Window