From 0187d1bd9fe15897262c1d270671450784cccfee Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Sun, 6 Jul 2025 09:55:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=93=E7=82=B9=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=EF=BC=8C=E5=AE=8C=E5=96=84=E9=85=8D=E7=BD=AE=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ComponentBasic/BehaviorPerform.cpp | 63 +++++++++--- ComponentBasic/BehaviorPerform.h | 17 +++- ComponentBasic/ComponentBasic.vcxproj | 2 +- MessageBasic/MessageBasic.vcxproj | 2 +- SimsBasic/SimsBasic.vcxproj | 2 +- SimsWorld/BehaviorConfigurationPanel.cpp | 122 +++++++++++++++++++++++ SimsWorld/BehaviorConfigurationPanel.h | 42 ++++++++ SimsWorld/BehaviorEditor.cpp | 93 ++++++++++++++++- SimsWorld/BehaviorEditor.h | 28 +++++- SimsWorld/SimsWorld.vcxproj | 4 +- SimsWorld/SimsWorld.vcxproj.filters | 6 ++ StandardGlobe/StandardGlobe.vcxproj | 2 +- TestProject/TestProject.vcxproj | 2 +- 13 files changed, 356 insertions(+), 29 deletions(-) create mode 100644 SimsWorld/BehaviorConfigurationPanel.cpp create mode 100644 SimsWorld/BehaviorConfigurationPanel.h diff --git a/ComponentBasic/BehaviorPerform.cpp b/ComponentBasic/BehaviorPerform.cpp index 20866d7..c080466 100644 --- a/ComponentBasic/BehaviorPerform.cpp +++ b/ComponentBasic/BehaviorPerform.cpp @@ -354,6 +354,16 @@ QList BehaviorMapNode::outputVariableKeys() const return keys; } +QList BehaviorMapNode::internalVariableKeys() const +{ + QList keys; + for (auto key : this->_variables.keys()) + if (this->_variables[key].first == IO_TYPE::INTERNAL) + keys << key; + + return keys; +} + void BehaviorMapNode::removeVariable(const QString& key) { this->_variables.remove(key); @@ -403,9 +413,14 @@ void BehaviorMapNode::reset() this->_state_value = ExecuteResult::UNDEFINED; } +QString BehaviorMapNode::rtName() const +{ + return QString(u8"行为树节点<%1>(%2)").arg(_map_name).arg(getID()); +} + QString BehaviorMapNode::typeName() const { - return _map_name; + return u8"行为树节点"; } ExecuteResult BehaviorMapNode::execute() @@ -460,7 +475,7 @@ QList> SequenceNode::getForwards() const QString SequenceNode::typeName() const { - return u8"顺序"; + return u8"顺序节点"; } ExecuteResult SequenceNode::execute() { @@ -608,7 +623,7 @@ void SelectorNode::reset() QString SelectorNode::typeName() const { - return u8"选择"; + return u8"选择节点"; } ExecuteResult SelectorNode::execute() @@ -650,7 +665,7 @@ void ParallelNode::reset() QString ParallelNode::typeName() const { - return u8"并行"; + return u8"并行节点"; } ExecuteResult ParallelNode::execute() @@ -704,11 +719,6 @@ void ParallelNode::saveTo(QJsonObject& obj) const void CompareNode::reset() { } -QString CompareNode::typeName() const -{ - return QString(u8"%1<%2>").arg(u8"比较", delegateName()); -} - ExecuteResult CompareNode::execute() { if (this->_bind_delegate) { @@ -729,6 +739,16 @@ QList> CompareNode::getForwards() const return QList>(); } +QString CompareNode::rtName() const +{ + return QString(u8"%1<%2>(%3)").arg(typeName(), delegateName()).arg(getID()); +} + +QString CompareNode::typeName() const +{ + return u8"比较节点"; +} + bool CompareNode::fallback(std::shared_ptr node, ExecuteResult ste) { return true; } @@ -918,9 +938,14 @@ QList> ExecuteNode::getForwards() const return QList>(); } +QString ExecuteNode::rtName() const +{ + return QString("%1<%2>(%3)").arg(typeName(),delegateName()).arg(getID()); +} + QString ExecuteNode::typeName() const { - return QString(u8"执行<%1>").arg(delegateName()); + return u8"执行节点"; } QHash> ExecuteNode::inputList() const @@ -1015,19 +1040,27 @@ void ModifiedNode::insert(std::shared_ptr node, int index /*= -1*/) LogicalNode::insert(node); } -QString ModifiedNode::typeName() const +QString ModifiedNode::rtName() const { + QString temp_string; switch (modifyType()) { case ModifyType::ALWAYS_SUCCESS: - return u8"修饰<永远成功>"; + temp_string = u8"修饰节点<永远成功>"; case ModifyType::ALWAYS_FAILURE: - return u8"修饰<永远失败>"; + temp_string = u8"修饰节点<永远失败>"; case ModifyType::RESULT_INVENTER: - return u8"修饰<结果反转>"; + temp_string = u8"修饰节点<结果反转>"; default: - return u8"修饰<>"; + temp_string = u8"修饰节点<>"; } + + return temp_string + QString("(%1)").arg(getID()); +} + +QString ModifiedNode::typeName() const +{ + return u8"修饰节点"; } QHash> ModifiedNode::inputList() const diff --git a/ComponentBasic/BehaviorPerform.h b/ComponentBasic/BehaviorPerform.h index e821955..331e232 100644 --- a/ComponentBasic/BehaviorPerform.h +++ b/ComponentBasic/BehaviorPerform.h @@ -405,7 +405,7 @@ public: /// 实例化节点名称 /// /// - QString rtName() const; + virtual QString rtName() const; /// /// 获取节点名称 @@ -460,14 +460,16 @@ public: /// 逻辑树节点输入输出类型 /// enum class IO_TYPE { - INPUT, OUTPUT + INPUT, // 输入 + OUTPUT, // 输出 + INTERNAL// 内部变量 }; /// /// 自定义行为树节点根节点实例 /// class COMPONENTBASIC_EXPORT BehaviorMapNode : public LogicalNode { private: - QString _map_name = u8"行为树"; + QString _map_name = u8"行为树节点"; /// /// 地图变量表 @@ -485,6 +487,7 @@ public: virtual void setVariable(const QString& key, IO_TYPE t, std::shared_ptr ins); virtual QList inputVariableKeys() const; virtual QList outputVariableKeys() const; + virtual QList internalVariableKeys() const; virtual void removeVariable(const QString &key); /// /// 获取指定名称的数据变量 @@ -504,6 +507,11 @@ public: /// void reset() override; /// + /// 实例名称 + /// + /// + QString rtName() const override; + /// /// 获取节点类型名称 /// /// @@ -641,6 +649,7 @@ public: void bindDelegate(std::shared_ptr ins); virtual QList> getForwards() const override; + virtual QString rtName() const override; QString typeName() const override; QHash> inputList() const override; @@ -671,6 +680,7 @@ public: void bindDelegate(std::shared_ptr ins); virtual QList> getForwards() const override; + virtual QString rtName() const override; QString typeName() const override; QHash> inputList() const override; @@ -710,6 +720,7 @@ public: void insert(std::shared_ptr node, int index = -1) override; + virtual QString rtName() const override; QString typeName() const override; QHash> inputList() const override; QHash> outputList() const override; diff --git a/ComponentBasic/ComponentBasic.vcxproj b/ComponentBasic/ComponentBasic.vcxproj index 79e73fa..9d3a0c9 100644 --- a/ComponentBasic/ComponentBasic.vcxproj +++ b/ComponentBasic/ComponentBasic.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core;xml;gui;qml;concurrent debug diff --git a/MessageBasic/MessageBasic.vcxproj b/MessageBasic/MessageBasic.vcxproj index 60cb910..0a98f7f 100644 --- a/MessageBasic/MessageBasic.vcxproj +++ b/MessageBasic/MessageBasic.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core;gui debug diff --git a/SimsBasic/SimsBasic.vcxproj b/SimsBasic/SimsBasic.vcxproj index 7abe405..1a73115 100644 --- a/SimsBasic/SimsBasic.vcxproj +++ b/SimsBasic/SimsBasic.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core debug diff --git a/SimsWorld/BehaviorConfigurationPanel.cpp b/SimsWorld/BehaviorConfigurationPanel.cpp new file mode 100644 index 0000000..4127a25 --- /dev/null +++ b/SimsWorld/BehaviorConfigurationPanel.cpp @@ -0,0 +1,122 @@ +#include "BehaviorConfigurationPanel.h" +#include +#include +#include + +BehaviorMapConfigurationPanel::BehaviorMapConfigurationPanel(QWidget* p) + :QFrame(p), + _root_name(new QLineEdit(this)), + _variable_table(new QTableView(this)), + _variable_model(new QStandardItemModel(this)) +{ + setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + auto p_layout = new QGridLayout(this); + p_layout->addWidget(new QLabel(u8"行为树名称:", this)); + p_layout->addWidget(_root_name, 0, 1, 1, 3); + + auto addVar = new QPushButton(u8"添加变量", this); + auto rmVar = new QPushButton(u8"删除变量", this); + p_layout->addWidget(addVar, 0, 4); + p_layout->addWidget(rmVar, 0, 5); + + p_layout->addWidget(_variable_table, 1, 0, 3, 6); + _variable_table->setModel(_variable_model); + _variable_model->setHorizontalHeaderLabels(QStringList() + << u8"输入/输出" << u8"变量名" << u8"变量类型"); + + p_layout->setColumnStretch(1, 1); + + + connect(addVar, &QPushButton::clicked, [=](){ + VariableAdd dia(this->_bind_node, this); + dia.exec(); + }); +} + +void BehaviorMapConfigurationPanel::setTarget(std::shared_ptr map_root, NodePresent* ins) +{ + this->_bind_graph = ins; + this->_bind_node = std::dynamic_pointer_cast(map_root); + _variable_model->removeRows(0, _variable_model->rowCount()); + + _root_name->setText(map_root->typeName()); + for (auto key : _bind_node->inputVariableKeys()) { + auto ins_prop = _bind_node->getVariable(key); + QList row; + row << new QStandardItem(u8"输入"); + row << new QStandardItem(key); + row << new QStandardItem(ins_prop->topicString()); + std::for_each(row.begin(), row.end(), + [](QStandardItem* ins) {ins->setEditable(false); } + ); + + _variable_model->appendRow(row); + } + + for (auto key : _bind_node->outputVariableKeys()) { + auto ins_prop = _bind_node->getVariable(key); + QList row; + row << new QStandardItem(u8"输出"); + row << new QStandardItem(key); + row << new QStandardItem(ins_prop->topicString()); + std::for_each(row.begin(), row.end(), + [](QStandardItem* ins) { ins->setEditable(false); } + ); + + _variable_model->appendRow(row); + } + + for (auto key : _bind_node->internalVariableKeys()) { + auto ins_prop = _bind_node->getVariable(key); + QList row; + row << new QStandardItem(u8"内部"); + row << new QStandardItem(key); + row << new QStandardItem(ins_prop->topicString()); + std::for_each(row.begin(), row.end(), + [](QStandardItem* ins) {ins->setEditable(false); } + ); + + _variable_model->appendRow(row); + } +} + +VariableAdd::VariableAdd(std::shared_ptr node, QWidget* parent) + : QDialog(parent), _bind_node(node), + _io_type(new QComboBox(this)), + _data_type(new QComboBox(this)), + _var_name(new QLineEdit(this)) +{ + setWindowTitle(u8"添加变量"); + + auto d_layout = new QGridLayout(this); + d_layout->addWidget(new QLabel(u8"输入/输出", this)); + d_layout->addWidget(_io_type, 0, 1, 1, 2); + d_layout->addWidget(new QLabel(u8"变量类型", this), 1, 0); + d_layout->addWidget(_data_type, 1, 1, 1, 2); + d_layout->addWidget(new QLabel(u8"变量名", this), 2, 0); + d_layout->addWidget(_var_name, 2, 1, 1, 2); + + auto cancel = new QPushButton(u8"取消"); + auto yes = new QPushButton(u8"确定"); + d_layout->addWidget(yes, 2, 0); + d_layout->addWidget(cancel, 2, 2); + + connect(cancel, &QPushButton::clicked, this, &QDialog::reject); + connect(yes, &QPushButton::clicked, this, &VariableAdd::appendVariable); + + _io_type->addItems(QStringList()<addItems(_bind_node->getKernal()->dataTypes()); +} + +void VariableAdd::appendVariable() +{ + auto iotype = this->_io_type->currentText(); + IO_TYPE typemark = IO_TYPE::INPUT; + if(iotype == u8"输出") + typemark = IO_TYPE::OUTPUT; + + auto type_topic = this->_data_type->currentText(); + auto type_o = this->_bind_node->getKernal()->getData(type_topic); + auto type_def = std::dynamic_pointer_cast(type_o->newDefault()); + this->_bind_node->setVariable(this->_var_name->text(), typemark, type_def); +} diff --git a/SimsWorld/BehaviorConfigurationPanel.h b/SimsWorld/BehaviorConfigurationPanel.h new file mode 100644 index 0000000..c6bae3c --- /dev/null +++ b/SimsWorld/BehaviorConfigurationPanel.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +class VariableAdd : public QDialog { +private: + std::shared_ptr _bind_node = nullptr; + + QComboBox *const _io_type; + QComboBox *const _data_type; + QLineEdit *const _var_name; + +public: + VariableAdd(std::shared_ptr node, QWidget *parent = nullptr); + + void appendVariable(); +}; + +class NodePresent; +class BehaviorMapConfigurationPanel : public QFrame +{ + Q_OBJECT +private: + QLineEdit *const _root_name; + QTableView *const _variable_table; + QStandardItemModel *const _variable_model; + + std::shared_ptr _bind_node; // 绑定内容结点 + NodePresent *_bind_graph = nullptr; // 绑定图形显示结点 + +public: + BehaviorMapConfigurationPanel(QWidget *p = nullptr); + + void setTarget(std::shared_ptr map_root, NodePresent *ins); +}; + diff --git a/SimsWorld/BehaviorEditor.cpp b/SimsWorld/BehaviorEditor.cpp index 12186cd..26f74a6 100644 --- a/SimsWorld/BehaviorEditor.cpp +++ b/SimsWorld/BehaviorEditor.cpp @@ -443,19 +443,41 @@ void BehaviorEditor::new_behavior_map() // 清空行为树节点变量列表 auto variable_key_set = this->_map_root->inputVariableKeys(); variable_key_set << this->_map_root->outputVariableKeys(); - for(auto key : variable_key_set) + for (auto key : variable_key_set) this->_map_root->removeVariable(key); // 重置地图节点 this->_logical_present->setRoot(_map_root); } +#include +#include +#include +#include +QWidget* BehaviorEditor::newModifyNodeConfigration(QWidget* pwidget) +{ + auto panel = new QFrame(this); + panel->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + auto p_layout = new QGridLayout(panel); + + p_layout->addWidget(new QLabel(u8"修饰类型:", this)); + p_layout->addWidget(new QComboBox(this), 0, 1, 1, 3); + p_layout->addWidget(new QWidget(this), 1, 0, 1, 4); + + p_layout->setRowStretch(1, 1); + p_layout->setColumnStretch(1, 1); + return panel; +} + BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) : QMainWindow(parent), _type_view(new NodeTypesView(this)), _type_model(new QStandardItemModel(this)), _logical_present(new BehaviorsPresent(this)), - _logs_present(new QTextBrowser(this)) + _message_panel(new QTabWidget(this)), + _stacked_panel(new QStackedWidget(this)), + _logs_present(new QTextBrowser(this)), + _map_configuration(new BehaviorMapConfigurationPanel(this)) { _global_loader = std::make_shared(); _global_kernal = std::make_shared(_global_loader); @@ -477,7 +499,7 @@ BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) auto split_h = new QSplitter(Qt::Horizontal, this); split_v->addWidget(split_h); - split_v->addWidget(_logs_present); + split_v->addWidget(_message_panel); split_v->setStretchFactor(0, 1); split_v->setStretchFactor(1, 0); @@ -488,6 +510,16 @@ BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) _type_view->setModel(_type_model); nodeTypesViewInit(_type_model); + + + // 下方堆叠面板 + _message_panel->addTab(_logs_present, u8"控制台"); + _message_panel->addTab(_stacked_panel, u8"属性配置"); + _stacked_panel->addWidget(new BehaviorMapConfigurationPanel(this)); + _stacked_panel->addWidget(newModifyNodeConfigration(this)); + _stacked_panel->addWidget(newActionNodeConfigration(this)); + _stacked_panel->addWidget(newCompareNodeConfigration(this)); + _stacked_panel->addWidget(newDefaultConfigration(this)); } void BehaviorEditor::nodeTypesViewInit(QStandardItemModel* m) @@ -501,6 +533,61 @@ void BehaviorEditor::nodeTypesViewInit(QStandardItemModel* m) } } +#include +#include +#include +#include +#include + +QWidget* BehaviorEditor::newDefaultConfigration(QWidget* pwidget) +{ + auto ins = new QLabel(u8"该结点无需配置", pwidget); + ins->setAlignment(Qt::AlignCenter); + ins->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + return ins; +} + +QWidget* BehaviorEditor::newCompareNodeConfigration(QWidget* pwidget) +{ + auto panel = new QFrame(this); + panel->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + auto p_layout = new QGridLayout(panel); + + auto compare_types = new QComboBox(this); + p_layout->addWidget(new QLabel(u8"类型筛选:", this), 0, 0); + p_layout->addWidget(new QComboBox(this), 0, 1, 1, 5); + p_layout->addWidget(new QLabel(u8"比较器类型:"), 1, 0); + p_layout->addWidget(compare_types, 1, 1, 1, 5); + p_layout->addWidget(new QLabel(u8"输入变量A:", this), 2, 0); + p_layout->addWidget(new QComboBox(this), 2, 1, 1, 5); + p_layout->addWidget(new QLabel(u8"输入变量B:", this), 3, 0); + p_layout->addWidget(new QComboBox(this), 3, 1, 1, 5); + + p_layout->setColumnStretch(1, 1); + return panel; +} + +QWidget* BehaviorEditor::newActionNodeConfigration(QWidget* pwidget) +{ + auto panel = new QFrame(this); + panel->setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + auto p_layout = new QGridLayout(panel); + + p_layout->addWidget(new QLabel(u8"执行器类型:", this)); + p_layout->addWidget(new QComboBox(this), 0, 1, 1, 4); + auto vars_tabw = new QTabWidget(this); + p_layout->addWidget(vars_tabw, 1, 0, 3, 5); + vars_tabw->setTabPosition(QTabWidget::West); + + vars_tabw->addTab(new QTableView(this), u8"输入变量"); + vars_tabw->addTab(new QTableView(this), u8"输出变量"); + + p_layout->setColumnStretch(1, 1); + return panel; +} + + + NodeTypesView::NodeTypesView(QWidget* parent /*= nullptr*/) : QListView(parent) { diff --git a/SimsWorld/BehaviorEditor.h b/SimsWorld/BehaviorEditor.h index e0168b4..3a10176 100644 --- a/SimsWorld/BehaviorEditor.h +++ b/SimsWorld/BehaviorEditor.h @@ -144,6 +144,11 @@ protected: #include #include #include +#include +#include +#include + +#include "BehaviorConfigurationPanel.h" /// /// 行为树节点编辑器 @@ -156,7 +161,9 @@ private: NodeTypesView* const _type_view; QStandardItemModel* const _type_model; BehaviorsPresent* const _logical_present; - QTextBrowser* const _logs_present; + QTabWidget *const _message_panel; + QStackedWidget *const _stacked_panel; + BehaviorMapConfigurationPanel *const _map_configuration; std::shared_ptr _map_root; QUrl _current_fileurl; @@ -164,8 +171,25 @@ private: void open_behavior_map(); void new_behavior_map(); + void nodeTypesViewInit(QStandardItemModel* m); + + // ============================================== + QTextBrowser* const _logs_present; + + // ============================================== + + // ============================================== + QWidget* newDefaultConfigration(QWidget* pwidget); + + // ============================================== + QWidget* newCompareNodeConfigration(QWidget* pwidget); + + // ============================================== + QWidget* newActionNodeConfigration(QWidget* pwidget); + + // ============================================== + QWidget* newModifyNodeConfigration(QWidget* pwidget); public: BehaviorEditor(QWidget* parent = nullptr); - void nodeTypesViewInit(QStandardItemModel* m); }; \ No newline at end of file diff --git a/SimsWorld/SimsWorld.vcxproj b/SimsWorld/SimsWorld.vcxproj index 6107745..c008107 100644 --- a/SimsWorld/SimsWorld.vcxproj +++ b/SimsWorld/SimsWorld.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core;gui;widgets;qml debug @@ -99,6 +99,7 @@ + @@ -117,6 +118,7 @@ + diff --git a/SimsWorld/SimsWorld.vcxproj.filters b/SimsWorld/SimsWorld.vcxproj.filters index cfb0841..48c52b1 100644 --- a/SimsWorld/SimsWorld.vcxproj.filters +++ b/SimsWorld/SimsWorld.vcxproj.filters @@ -55,6 +55,9 @@ Source Files + + Source Files + @@ -63,6 +66,9 @@ Header Files + + Header Files + diff --git a/StandardGlobe/StandardGlobe.vcxproj b/StandardGlobe/StandardGlobe.vcxproj index a91c0de..e7ecadd 100644 --- a/StandardGlobe/StandardGlobe.vcxproj +++ b/StandardGlobe/StandardGlobe.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core;gui debug diff --git a/TestProject/TestProject.vcxproj b/TestProject/TestProject.vcxproj index 3302cf4..d1abf9c 100644 --- a/TestProject/TestProject.vcxproj +++ b/TestProject/TestProject.vcxproj @@ -36,7 +36,7 @@ - 5.12.11_msvc2017_64 + 5.12.9_msvc2017_64 core;gui debug