From 87bd205c26166a4213ce168e4303fc9dcd5100d3 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Tue, 1 Mar 2016 07:25:05 +0100 Subject: [PATCH] updated rcon --- src/rcon/AIApplication.h | 1 + src/rcon/AIDebugger.cpp | 37 +++++++++++++------ src/rcon/gui/view/aggro/AggroTable.cpp | 2 +- src/rcon/gui/view/aggro/AggroTable.h | 1 - src/rcon/gui/view/list/EntityList.cpp | 9 +++-- src/rcon/gui/view/list/EntityListModel.cpp | 12 ++++++ src/rcon/gui/view/list/EntityListModel.h | 1 + src/rcon/gui/view/map/MapView.cpp | 22 ++++++++++- src/rcon/gui/view/map/MapView.h | 1 + src/rcon/gui/view/state/StateTable.cpp | 2 +- src/rcon/gui/view/state/StateTable.h | 1 - src/rcon/gui/view/tree/BehaviourTreeModel.cpp | 5 ++- .../gui/view/tree/BehaviourTreeModelItem.cpp | 6 +-- .../gui/view/tree/BehaviourTreeModelItem.h | 2 - 14 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/rcon/AIApplication.h b/src/rcon/AIApplication.h index 578429c2a..5d3e4de97 100644 --- a/src/rcon/AIApplication.h +++ b/src/rcon/AIApplication.h @@ -17,6 +17,7 @@ class AINodeStaticResolver; * don't need this. */ class AIApplication: public QApplication { +Q_OBJECT protected: AIDebugger* _debugger; AINodeStaticResolver* _resolver; diff --git a/src/rcon/AIDebugger.cpp b/src/rcon/AIDebugger.cpp index 751700105..4dc6a07f0 100644 --- a/src/rcon/AIDebugger.cpp +++ b/src/rcon/AIDebugger.cpp @@ -100,7 +100,7 @@ public: AIDebugger::AIDebugger(AINodeStaticResolver& resolver) : QObject(), _stateHandler(new StateHandler(*this)), _characterHandler(new CharacterHandler(*this)), _characterStaticHandler( new CharacterStaticHandler(*this)), _pauseHandler(new PauseHandler(*this)), _namesHandler(new NamesHandler(*this)), _nopHandler( - new NopHandler()), _selectedId(-1), _socket(this), _pause(false), _resolver(resolver) { + new NopHandler()), _selectedId(AI_NOTHING_SELECTED), _socket(this), _pause(false), _resolver(resolver) { connect(&_socket, SIGNAL(readyRead()), SLOT(readTcpData())); connect(&_socket, SIGNAL(disconnected()), SLOT(onDisconnect())); @@ -153,7 +153,9 @@ void AIDebugger::togglePause() { } void AIDebugger::select(const ai::AIStateWorld& ai) { - writeMessage(AISelectMessage(ai.getId())); + const ai::CharacterId id = ai.getId(); + qDebug() << "select " << id; + writeMessage(AISelectMessage(id)); } bool AIDebugger::writeMessage(const IProtocolMessage& msg) { @@ -185,10 +187,12 @@ bool AIDebugger::writeMessage(const IProtocolMessage& msg) { } void AIDebugger::unselect() { - writeMessage(AISelectMessage(-1)); - _selectedId = -1; + writeMessage(AISelectMessage(AI_NOTHING_SELECTED)); + _selectedId = AI_NOTHING_SELECTED; _aggro.clear(); _node = AIStateNode(); + _attributes.clear(); + emit onSelected(); qDebug() << "unselect entity"; } @@ -248,7 +252,7 @@ void AIDebugger::onDisconnect() { emit onPause(_pause); } { - _selectedId = -1; + _selectedId = AI_NOTHING_SELECTED; _aggro.clear(); _attributes.clear(); _node = AIStateNode(); @@ -262,7 +266,6 @@ void AIDebugger::onDisconnect() { _entities.clear(); emit onEntitiesUpdated(); } - emit disconnect(); } void AIDebugger::readTcpData() { @@ -278,7 +281,8 @@ void AIDebugger::readTcpData() { for (;;) { if (!mf.isNewMessageAvailable(_stream)) break; - std::unique_ptr msg(mf.create(_stream)); + // don't free this - preallocated memory that is reused + ai::IProtocolMessage* msg = mf.create(_stream); if (!msg) { qDebug() << "unknown server message - disconnecting"; _socket.disconnectFromHost(); @@ -303,16 +307,27 @@ MapView* AIDebugger::createMapWidget() { void AIDebugger::setNames(const std::vector& names) { _names.clear(); - for (std::vector::const_iterator i = names.begin(); i != names.end(); ++i) { - _names << QString::fromStdString(*i); + _names.reserve(names.size()); + // TODO: measure if contains/remove/insert manually is faster + for (const std::string& name : names) { + _names << QString::fromStdString(name); } } void AIDebugger::setEntities(const std::vector& entities) { _entities.clear(); - for (std::vector::const_iterator i = entities.begin(); i != entities.end(); ++i) { - _entities.insert(i->getId(), *i); + // TODO: measure if contains/remove/insert manually is faster + for (const AIStateWorld& state : entities) { + _entities.insert(state.getId(), state); } + if (_selectedId == AI_NOTHING_SELECTED) { + return; + } + if (_entities.contains(_selectedId)) { + return; + } + // TODO: this doesn't work for some reason +// unselect(); } } diff --git a/src/rcon/gui/view/aggro/AggroTable.cpp b/src/rcon/gui/view/aggro/AggroTable.cpp index 379fea5c7..8806195dd 100644 --- a/src/rcon/gui/view/aggro/AggroTable.cpp +++ b/src/rcon/gui/view/aggro/AggroTable.cpp @@ -5,7 +5,7 @@ namespace ai { namespace debug { AggroTable::AggroTable(AIDebugger& debugger) : - QTableView(), _model(debugger, this), _debugger(debugger) { + QTableView(), _model(debugger, this) { _proxyModel.setSourceModel(&_model); setModel(&_proxyModel); setAlternatingRowColors(true); diff --git a/src/rcon/gui/view/aggro/AggroTable.h b/src/rcon/gui/view/aggro/AggroTable.h index c7a589ede..9d368a63e 100644 --- a/src/rcon/gui/view/aggro/AggroTable.h +++ b/src/rcon/gui/view/aggro/AggroTable.h @@ -16,7 +16,6 @@ class AggroTable: public QTableView { private: AggroTableModel _model; QSortFilterProxyModel _proxyModel; - AIDebugger& _debugger; public: AggroTable(AIDebugger& debugger); virtual ~AggroTable(); diff --git a/src/rcon/gui/view/list/EntityList.cpp b/src/rcon/gui/view/list/EntityList.cpp index a4237b213..ed466c643 100644 --- a/src/rcon/gui/view/list/EntityList.cpp +++ b/src/rcon/gui/view/list/EntityList.cpp @@ -10,9 +10,10 @@ EntityList::EntityList(AIDebugger& debugger, QLineEdit* entityFilter) : _proxyModel.setSourceModel(&_model); setModel(&_proxyModel); setAlternatingRowColors(true); - setSortingEnabled(true); + setSortingEnabled(false); setSelectionMode(QAbstractItemView::SingleSelection); setSelectionBehavior(QAbstractItemView::SelectRows); + setEditTriggers(QAbstractItemView::NoEditTriggers); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); verticalHeader()->hide(); horizontalHeader()->setStretchLastSection(true); @@ -26,12 +27,14 @@ EntityList::~EntityList() { void EntityList::updateEntityList() { _model.update(); - _model.sort(0); } void EntityList::selectEntity(const QModelIndex ¤t, const QModelIndex &previous) { Q_UNUSED(previous); - const AIStateWorld& state = _model.getEntities().at(_proxyModel.mapToSource(current).row()); + if (!current.isValid()) + return; + const QModelIndex index = _proxyModel.mapToSource(current); + const AIStateWorld& state = _model.getEntities().at(index.row()); _debugger.select(state); } diff --git a/src/rcon/gui/view/list/EntityListModel.cpp b/src/rcon/gui/view/list/EntityListModel.cpp index d290ad732..57ca9174f 100644 --- a/src/rcon/gui/view/list/EntityListModel.cpp +++ b/src/rcon/gui/view/list/EntityListModel.cpp @@ -11,9 +11,21 @@ EntityListModel::EntityListModel(AIDebugger& debugger, QTableView *parent) : EntityListModel::~EntityListModel() { } +QModelIndex EntityListModel::characterIndex(CharacterId id) const { + int row = 0; + for (const AIStateWorld& state : _list) { + if (state.getId() == id) + return createIndex(row, 0); + ++row; + } + qDebug() << "Could not find entity " << id << " in the model"; + return QModelIndex(); +} + void EntityListModel::update() { beginResetModel(); _list = _debugger.getEntities().values(); + // TODO: sort list - not model endResetModel(); } diff --git a/src/rcon/gui/view/list/EntityListModel.h b/src/rcon/gui/view/list/EntityListModel.h index 56129a6ed..dd49d03c1 100644 --- a/src/rcon/gui/view/list/EntityListModel.h +++ b/src/rcon/gui/view/list/EntityListModel.h @@ -23,6 +23,7 @@ public: } void update(); + QModelIndex characterIndex(CharacterId id) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/rcon/gui/view/map/MapView.cpp b/src/rcon/gui/view/map/MapView.cpp index b1be93ba1..bb1bc94e4 100644 --- a/src/rcon/gui/view/map/MapView.cpp +++ b/src/rcon/gui/view/map/MapView.cpp @@ -20,23 +20,41 @@ MapView::~MapView() { } MapItem* MapView::createMapItem(const AIStateWorld& state) { - MapItem* item = new MapItem(nullptr, state, _debugger); + auto i = _items.find(state.getId()); + MapItem* item; + if (i != _items.end()) { + item = i.value(); + } else { + item = new MapItem(nullptr, state, _debugger); + } item->setPos((qreal)state.getPosition().x, (qreal)state.getPosition().z); if (_debugger.isSelected(state)) { item->setZValue(std::numeric_limits::max()); } else { item->setZValue((qreal)state.getPosition().y); } + if (i == _items.end()) + return nullptr; + _items[state.getId()] = item; return item; } void MapView::updateMapView() { - _scene.clear(); + QHash copy(_items); const AIDebugger::Entities& e = _debugger.getEntities(); for (AIDebugger::EntitiesIter i = e.begin(); i != e.end(); ++i) { + copy.remove(i->getId()); MapItem* item = createMapItem(*i); + if (item == nullptr) + continue; _scene.addItem(item); } + + // remove the remaining entities - they are no longer part of the snapshot + for (auto i = copy.begin(); i != copy.end(); ++i) { + _scene.removeItem(i.value()); + _items.remove(i.key()); + } } } diff --git a/src/rcon/gui/view/map/MapView.h b/src/rcon/gui/view/map/MapView.h index 1badb86a5..91d520d00 100644 --- a/src/rcon/gui/view/map/MapView.h +++ b/src/rcon/gui/view/map/MapView.h @@ -22,6 +22,7 @@ class MapView: public IGraphicsView { protected: QGraphicsScene _scene; AIDebugger& _debugger; + QHash _items; public: MapView(AIDebugger& debugger); virtual ~MapView(); diff --git a/src/rcon/gui/view/state/StateTable.cpp b/src/rcon/gui/view/state/StateTable.cpp index ec578319a..f2300e8c8 100644 --- a/src/rcon/gui/view/state/StateTable.cpp +++ b/src/rcon/gui/view/state/StateTable.cpp @@ -5,7 +5,7 @@ namespace ai { namespace debug { StateTable::StateTable(AIDebugger& debugger) : - QTableView(), _model(debugger), _debugger(debugger) { + QTableView(), _model(debugger) { _proxyModel.setSourceModel(&_model); setModel(&_proxyModel); setAlternatingRowColors(true); diff --git a/src/rcon/gui/view/state/StateTable.h b/src/rcon/gui/view/state/StateTable.h index 70083f3f1..59039d5de 100644 --- a/src/rcon/gui/view/state/StateTable.h +++ b/src/rcon/gui/view/state/StateTable.h @@ -16,7 +16,6 @@ class StateTable: public QTableView { private: StateTableModel _model; QSortFilterProxyModel _proxyModel; - AIDebugger& _debugger; public: StateTable(AIDebugger& debugger); virtual ~StateTable(); diff --git a/src/rcon/gui/view/tree/BehaviourTreeModel.cpp b/src/rcon/gui/view/tree/BehaviourTreeModel.cpp index e2a7ab579..b1187e6cc 100644 --- a/src/rcon/gui/view/tree/BehaviourTreeModel.cpp +++ b/src/rcon/gui/view/tree/BehaviourTreeModel.cpp @@ -153,8 +153,11 @@ void BehaviourTreeModel::setRootNode(AIStateNode* node) { beginResetModel(); if (_rootItem) { delete _rootItem; + _rootItem = nullptr; + } + if (node->getNodeId() != -1) { + _rootItem = new BehaviourTreeModelItem(node, _resolver); } - _rootItem = new BehaviourTreeModelItem(node, _resolver); endResetModel(); } diff --git a/src/rcon/gui/view/tree/BehaviourTreeModelItem.cpp b/src/rcon/gui/view/tree/BehaviourTreeModelItem.cpp index 5b3841576..aaea830e6 100644 --- a/src/rcon/gui/view/tree/BehaviourTreeModelItem.cpp +++ b/src/rcon/gui/view/tree/BehaviourTreeModelItem.cpp @@ -7,12 +7,12 @@ namespace ai { namespace debug { BehaviourTreeModelItem::BehaviourTreeModelItem(AIStateNode* node, AINodeStaticResolver& resolver, BehaviourTreeModelItem* parent) : - _node(node), _staticNodeData(resolver.get(node->getNodeId())), _populated(false), _rowCount(0), _parent(parent) { + _node(node), _staticNodeData(resolver.get(node->getNodeId())), _parent(parent) { if (_parent == nullptr) { _rows.push_back(new BehaviourTreeModelItem(_node, resolver, this)); } else { - for (const AIStateNode& node : _node->getChildren()) { - _rows.push_back(new BehaviourTreeModelItem(const_cast(&node), resolver, this)); + for (const AIStateNode& stateNode : _node->getChildren()) { + _rows.push_back(new BehaviourTreeModelItem(const_cast(&stateNode), resolver, this)); } } const QString type = QString::fromStdString(_staticNodeData.getType()).toLower(); diff --git a/src/rcon/gui/view/tree/BehaviourTreeModelItem.h b/src/rcon/gui/view/tree/BehaviourTreeModelItem.h index 6c0ff2028..dbb791701 100644 --- a/src/rcon/gui/view/tree/BehaviourTreeModelItem.h +++ b/src/rcon/gui/view/tree/BehaviourTreeModelItem.h @@ -23,8 +23,6 @@ class BehaviourTreeModelItem { private: AIStateNode* _node; const AIStateNodeStatic& _staticNodeData; - bool _populated; - int _rowCount; QList _rows; BehaviourTreeModelItem* _parent; QIcon _icon;