97 lines
2.5 KiB
C++
97 lines
2.5 KiB
C++
/**
|
|
* @file tree_node.cpp
|
|
* @brief Tree node ownership and navigation.
|
|
*
|
|
* Created: 2026-03-13
|
|
* Author: Deeaitch (Dim. Himro)
|
|
*
|
|
* Licensed under the MIT License.
|
|
* See LICENSE file in the project root for full license text.
|
|
*/
|
|
|
|
#include "tree_node.h"
|
|
#include <stdexcept>
|
|
|
|
TreeNode::TreeNode()
|
|
: m_type(NodeType::Root), m_name("dbc") {
|
|
}
|
|
|
|
TreeNode::TreeNode(const FrameInfo &frame)
|
|
: m_type(NodeType::Frame), m_name(frame.name), m_frame(std::make_unique<FrameInfo>(frame)) {
|
|
}
|
|
|
|
TreeNode::TreeNode(const SignalInfo &signal)
|
|
: m_type(NodeType::Signal), m_name(signal.name), m_signal(std::make_unique<SignalInfo>(signal)) {
|
|
}
|
|
|
|
void TreeNode::AddChild(std::unique_ptr<TreeNode> &&child) {
|
|
if (child) {
|
|
for (const TreeNode *ancestor = this; ancestor; ancestor = ancestor->m_parent) {
|
|
if (ancestor == child.get())
|
|
throw std::invalid_argument("Cannot insert a node into its own subtree");
|
|
}
|
|
if (child->m_parent)
|
|
throw std::invalid_argument("Child is already attached");
|
|
m_children.push_back(std::move(child));
|
|
m_children.back()->m_parent = this;
|
|
m_children.back()->m_row = m_children.size() - 1U;
|
|
}
|
|
}
|
|
|
|
std::size_t TreeNode::GetChildCount() const {
|
|
return m_children.size();
|
|
}
|
|
|
|
const TreeNode *TreeNode::GetChild(std::size_t index) const {
|
|
if (index >= m_children.size())
|
|
return nullptr;
|
|
|
|
return m_children[index].get();
|
|
}
|
|
|
|
TreeNode *TreeNode::GetChild(std::size_t index) {
|
|
if (index >= m_children.size())
|
|
return nullptr;
|
|
|
|
return m_children[index].get();
|
|
}
|
|
|
|
NodeType TreeNode::GetType() const {
|
|
return m_type;
|
|
}
|
|
|
|
const std::string &TreeNode::GetName() const {
|
|
return m_name;
|
|
}
|
|
|
|
const FrameInfo *TreeNode::GetFrame() const {
|
|
return m_frame.get();
|
|
}
|
|
|
|
const SignalInfo *TreeNode::GetSignal() const {
|
|
return m_signal.get();
|
|
}
|
|
|
|
const TreeNode *TreeNode::GetParent() const {
|
|
return m_parent;
|
|
}
|
|
|
|
std::size_t TreeNode::GetRow() const {
|
|
return m_row;
|
|
}
|
|
|
|
std::optional<FrameKey> TreeNode::GetFrameKey() const {
|
|
if (m_frame)
|
|
return FrameKey(m_frame->canId, m_frame->isExtended);
|
|
if (m_signal && m_parent && m_parent->GetType() == NodeType::Frame)
|
|
return m_parent->GetFrameKey();
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::optional<SignalKey> TreeNode::GetSignalKey() const {
|
|
const std::optional<FrameKey> frame = GetFrameKey();
|
|
if (m_signal && frame)
|
|
return SignalKey(*frame, m_signal->name);
|
|
return std::nullopt;
|
|
}
|