variable WIP
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user