From 55ef35db3a33c85fc2028a7ff52fa4e9e8f20142 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 19 Jun 2023 15:47:02 +0200 Subject: [PATCH 01/40] identify pin related user actions --- .../gui/user_action/user_action_object.h | 2 -- .../module_details_widget/module_ports_tree.cpp | 14 ++++++++++++++ .../module_details_widget/port_tree_model.cpp | 17 +++++++++++++++++ .../user_action/action_add_items_to_object.cpp | 2 ++ .../src/user_action/action_create_object.cpp | 2 ++ .../src/user_action/action_delete_object.cpp | 2 ++ .../action_remove_items_from_object.cpp | 2 ++ .../src/user_action/action_rename_object.cpp | 4 ++++ .../src/user_action/action_reorder_object.cpp | 2 ++ .../src/user_action/action_set_object_type.cpp | 2 ++ 10 files changed, 47 insertions(+), 2 deletions(-) diff --git a/plugins/gui/include/gui/user_action/user_action_object.h b/plugins/gui/include/gui/user_action/user_action_object.h index 572e608de2f..4658b22d8ab 100644 --- a/plugins/gui/include/gui/user_action/user_action_object.h +++ b/plugins/gui/include/gui/user_action/user_action_object.h @@ -54,8 +54,6 @@ namespace hal Grouping, Netlist, Context, - Pin, - PinGroup, MaxObjectType }; Q_ENUM(ObjectType) diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index 9d1b73c0400..d5dd75a6ee8 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -134,10 +134,12 @@ namespace hal return; pinSet.insert(pin->get_id()); } + /* TODO PIN ActionAddItemsToObject* act = new ActionAddItemsToObject(QSet(), QSet(), QSet(), pinSet); act->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); + */ } }); } @@ -153,10 +155,12 @@ namespace hal auto* group = gNetlist->get_module_by_id(modId)->get_pin_group_by_id(itemId); if (group != nullptr) { + /* TODO PIN ActionRenameObject* renameObj = new ActionRenameObject(ipd.textValue()); renameObj->setObject(UserActionObject(group->get_id(), UserActionObjectType::PinGroup)); renameObj->setParentObject(UserActionObject(modId, UserActionObjectType::Module)); renameObj->exec(); + */ } } }); @@ -164,10 +168,12 @@ namespace hal auto* pinGroup = mod->get_pin_group_by_id(itemId); if (pinGroup != nullptr) { + /* TDOD PIN ActionDeleteObject* delObj = new ActionDeleteObject; delObj->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); delObj->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); delObj->exec(); + */ } }); @@ -193,10 +199,12 @@ namespace hal auto* pin = mod->get_pin_by_id(itemId); if (pin != nullptr) { + /* TODO PIN ActionRenameObject* renameObj = new ActionRenameObject(ipd.textValue()); renameObj->setObject(UserActionObject(pin->get_id(), UserActionObjectType::Pin)); renameObj->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); renameObj->exec(); + */ } } }); @@ -214,10 +222,12 @@ namespace hal if (cbd.exec() == QDialog::Accepted) { + /* TODO PIN ActionSetObjectType* act = new ActionSetObjectType(cbd.textValue()); act->setObject(UserActionObject(pin->get_id(), UserActionObjectType::Pin)); act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); + */ } }); menu.addAction("Add net to current selection", [this, n]() { @@ -238,10 +248,12 @@ namespace hal for (auto item : selectedPins) pins.insert(mPortModel->getIdOfItem(item)); + /* TODO PIN ActionRemoveItemsFromObject* act = new ActionRemoveItemsFromObject(QSet(), QSet(), QSet(), pins); act->setObject(UserActionObject(mod->get_pin_group_by_id(sameGroup.second)->get_id(), UserActionObjectType::PinGroup)); act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); + */ }); } @@ -285,6 +297,7 @@ namespace hal return; pins.insert(pin->get_id()); } + /* TODO PIN UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); ActionCreateObject* actCreate = new ActionCreateObject(UserActionObjectType::PinGroup, ipd.textValue()); @@ -294,6 +307,7 @@ namespace hal act->addAction(actCreate); act->addAction(actAdd); act->exec(); + */ } }); } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 138ed0814e4..73ef3e8b692 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -480,6 +480,7 @@ namespace hal for(const auto &pin : group->get_pins()) pins.insert(pin->get_id()); + /* TODO PIN UserActionCompound* compAct = new UserActionCompound; ActionReorderObject* reorderActHack = new ActionReorderObject(droppedGroup->getOwnRow()); reorderActHack->setObject(UserActionObject(group->get_id(), UserActionObjectType::PinGroup)); @@ -490,6 +491,7 @@ namespace hal compAct->addAction(reorderActHack); compAct->addAction(addAct); compAct->exec(); + */ // too keep the order, ActionAddItemsToObject cannot be executed with all pins, but a ComAction must be created // with many ActionAddItemsToObject that contain a single pin each -> set destroys order of pins in source pingroup setModule(mModule); @@ -505,10 +507,13 @@ namespace hal auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; //mModule->move_pin_group(mModule->get_pin_group_by_id(getIdOfItem(droppedGroup)), desiredIdx); + /* TODO PIN ActionReorderObject* reordObj = new ActionReorderObject(desiredIdx); reordObj->setObject(UserActionObject(getIdOfItem(droppedGroup), UserActionObjectType::PinGroup)); reordObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); auto ret = reordObj->exec(); + */ + bool ret = true; // TEMP if(ret){ removeItem(droppedGroup); insertItem(droppedGroup, mRootItem, desiredIdx); @@ -520,10 +525,12 @@ namespace hal { mIgnoreEventsFlag = true; QSet e; + /* TODO PIN ActionAddItemsToObject* addAct = new ActionAddItemsToObject(e,e,e, QSet() << getIdOfItem(droppedPin)); addAct->setObject(UserActionObject(getIdOfItem(onDroppedGroup), UserActionObjectType::PinGroup)); addAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); addAct->exec(); + */ auto oldParent = droppedPin->getParent(); removeItem(droppedPin); insertItem(droppedPin, onDroppedGroup, onDroppedGroup->getChildCount()); @@ -545,14 +552,17 @@ namespace hal bool bottomEdge = row == onDroppedParent->getChildCount(); desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; // insert item here + /* TODO PIN ActionReorderObject* reorderObj = new ActionReorderObject(desiredIdx); reorderObj->setObject(UserActionObject(getIdOfItem(droppedPin), UserActionObjectType::Pin)); reorderObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); reorderObj->exec(); + */ } else // different groups { // reorder action from source group is still needed (for undo action)! + /* TODO PIN UserActionCompound* compAct = new UserActionCompound; ActionReorderObject* reorderActHack = new ActionReorderObject(droppedPin->getOwnRow()); reorderActHack->setObject(UserActionObject(getIdOfItem(droppedPin), UserActionObjectType::Pin)); @@ -567,6 +577,7 @@ namespace hal compAct->addAction(addAct); compAct->addAction(reorderAct); compAct->exec(); + */ } auto oldParent = droppedPin->getParent(); removeItem(droppedPin); @@ -586,10 +597,13 @@ namespace hal mIgnoreEventsFlag = true; auto pinGroup = mModule->get_pin_group_by_id(getIdOfItem(droppedPin->getParent())); QSet e; + /* TODO PIN ActionRemoveItemsFromObject* removeAct = new ActionRemoveItemsFromObject(e,e,e, QSet() << getIdOfItem(droppedPin)); removeAct->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); removeAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); bool ret = removeAct->exec(); + */ + bool ret = true; // TEMP // must search for the created group (must secure way is to serve for a group that contains the pin id) // and then move that group (the source group cannot be empty after the pin was removed -> canDropMimeData) if(ret) // can fail if the pins name that one wants to remove has the same name as another group that already exists @@ -604,11 +618,14 @@ namespace hal pinGroupItem->setAdditionalData(keyId, newGroup->get_id()); int pos = mRootItem->getChildCount(); // or query current index + + /* TODO PIN ActionReorderObject* reordObj = new ActionReorderObject(row); reordObj->setObject(UserActionObject(newGroup->get_id(), UserActionObjectType::PinGroup)); reordObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); if(reordObj->exec()) pos = row; + */ insertItem(pinGroupItem, mRootItem, pos); removeItem(droppedPin); diff --git a/plugins/gui/src/user_action/action_add_items_to_object.cpp b/plugins/gui/src/user_action/action_add_items_to_object.cpp index 44b87bba1fe..25a201b5c0c 100644 --- a/plugins/gui/src/user_action/action_add_items_to_object.cpp +++ b/plugins/gui/src/user_action/action_add_items_to_object.cpp @@ -173,6 +173,7 @@ namespace hal else return false; break; + /* TODO PIN case UserActionObjectType::PinGroup: { if (mPins.empty()) return true; @@ -257,6 +258,7 @@ namespace hal } } break; + */ default: return false; } diff --git a/plugins/gui/src/user_action/action_create_object.cpp b/plugins/gui/src/user_action/action_create_object.cpp index 2a73b467ae0..8a501f44b13 100644 --- a/plugins/gui/src/user_action/action_create_object.cpp +++ b/plugins/gui/src/user_action/action_create_object.cpp @@ -63,6 +63,7 @@ namespace hal switch (mObject.type()) { + /* TODO PIN case UserActionObjectType::PinGroup: { Module* parentModule = gNetlist->get_module_by_id(mParentObject.id()); @@ -77,6 +78,7 @@ namespace hal else return false; } + */ break; case UserActionObjectType::Module: diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index b26e214e8d5..323a6b06125 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -41,6 +41,7 @@ namespace hal switch (mObject.type()) { + /* TODO PIN case UserActionObjectType::PinGroup: { mod = gNetlist->get_module_by_id(mParentObject.id()); auto* pinGroup = mod->get_pin_group_by_id(mObject.id()); @@ -64,6 +65,7 @@ namespace hal return false; } break; + */ case UserActionObjectType::Module: mod = gNetlist->get_module_by_id(mObject.id()); if (mod) diff --git a/plugins/gui/src/user_action/action_remove_items_from_object.cpp b/plugins/gui/src/user_action/action_remove_items_from_object.cpp index 00719d3bdc0..79212b7e558 100644 --- a/plugins/gui/src/user_action/action_remove_items_from_object.cpp +++ b/plugins/gui/src/user_action/action_remove_items_from_object.cpp @@ -116,6 +116,7 @@ namespace hal else return false; break; + /* TODO PIN case UserActionObjectType::PinGroup: { auto mod = gNetlist->get_module_by_id(mParentObject.id()); if (mod) @@ -162,6 +163,7 @@ namespace hal } } break; + */ default: return false; } diff --git a/plugins/gui/src/user_action/action_rename_object.cpp b/plugins/gui/src/user_action/action_rename_object.cpp index d5f6d3e35cb..2e8a080cd8c 100644 --- a/plugins/gui/src/user_action/action_rename_object.cpp +++ b/plugins/gui/src/user_action/action_rename_object.cpp @@ -104,6 +104,7 @@ namespace hal return false; } break; + /* TODO PIN case UserActionObjectType::Pin: { mod = gNetlist->get_module_by_id(mParentObject.id()); if (!mod) @@ -138,15 +139,18 @@ namespace hal mod->set_pin_group_name(pinGroup, mNewName.toStdString()); } break; + */ default: return false; } ActionRenameObject* undo = new ActionRenameObject(oldName); undo->setObject(mObject); + /* TODO PIN if (mObject.type() == UserActionObjectType::Pin || mObject.type() == UserActionObjectType::PinGroup) { undo->setParentObject(mParentObject); } + */ mUndoAction = undo; return UserAction::exec(); } diff --git a/plugins/gui/src/user_action/action_reorder_object.cpp b/plugins/gui/src/user_action/action_reorder_object.cpp index 8db33f3f89c..cddb10050c4 100644 --- a/plugins/gui/src/user_action/action_reorder_object.cpp +++ b/plugins/gui/src/user_action/action_reorder_object.cpp @@ -23,6 +23,7 @@ namespace hal bool ActionReorderObject::exec() { + /* TODO PIN int oldIndex = -1; switch (mObject.type()) { @@ -86,6 +87,7 @@ namespace hal undo->setParentObject(mParentObject); mUndoAction = undo; } + */ return UserAction::exec(); } diff --git a/plugins/gui/src/user_action/action_set_object_type.cpp b/plugins/gui/src/user_action/action_set_object_type.cpp index f86cb5d2f41..00c52ebc305 100644 --- a/plugins/gui/src/user_action/action_set_object_type.cpp +++ b/plugins/gui/src/user_action/action_set_object_type.cpp @@ -49,6 +49,7 @@ namespace hal Module* mod; switch (mObject.type()) { + /* TODO PIN case UserActionObjectType::Pin: //only possible to change module pin types { //should also check if its a valid type? (enum_from_string default value doesnt help @@ -74,6 +75,7 @@ namespace hal } } break; + */ case UserActionObjectType::Module: mod = gNetlist->get_module_by_id(mObject.id()); if (mod != nullptr) From ea258b724ba83c8c21641464627d5a7d8b69dd40 Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 30 Jun 2023 11:04:05 +0200 Subject: [PATCH 02/40] class ActionPingroup added --- .../include/gui/user_action/action_pingroup.h | 112 +++++++ .../module_details_widget/port_tree_model.cpp | 160 +++++----- .../gui/src/user_action/action_pingroup.cpp | 280 ++++++++++++++++++ 3 files changed, 467 insertions(+), 85 deletions(-) create mode 100644 plugins/gui/include/gui/user_action/action_pingroup.h create mode 100644 plugins/gui/src/user_action/action_pingroup.cpp diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h new file mode 100644 index 00000000000..8a7b011faa6 --- /dev/null +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -0,0 +1,112 @@ +// MIT License +// +// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved. +// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved. +// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved. +// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once +#include "user_action.h" +#include +#include + +namespace hal +{ + class PinAction : public QObject + { + Q_OBJECT + public: + enum Type { None, Create, Delete, MovePin, MoveGroup, Rename, TypeChange, MaxAction }; + Q_ENUM(Type) + public: + static QString toString(Type tp); + static Type fromString(const QString& s); + }; + + /** + * @ingroup user_action + * @brief Pingroup user actions + * + * Action depends on PinAction::Type: + * + * Create: + * Pingroup with given name gets created. + * Pins listed in mPinIds get moved into new group + * Id of created group returned as targetGroupId() + * + * Delete: + * Pingroup ID=mSourceGroupId gets deleted. + * Pins in group are stored for undo command + * + * MovePin: + * Must use move constructor with mandatory arguments pinId and targetIndex + * One out of targetIndex (existing pingroup) or name (create new pingroup) + * must be given to indicate destination + * + * MoveGroup: + * Move Group identified by sourceGroupId to new targetIndex + */ + class ActionPingroup : public UserAction + { + private: + QList mPinActions; + QList mPinIds; + u32 mSourceGroupId; + u32 mTargetGroupId; + int mPinOrderNo; + int mGroupOrderNo; + QString mName; + public: + /** + * Action Constructor. + * + * @param type - The UserActionObjectType of the item that should be created (default type: None) + * @param objName - The name of the object to create (default name: ""). + */ + ActionPingroup(PinAction::Type action = PinAction::None, u32 pingroupId = 0, const QString& name=QString()); + ActionPingroup(u32 pinId, int pinIndex, u32 tgtgroupId=0, const QString& name=QString(), int grpIndex=-1); // action = MovePin + bool exec() override; + QString tagname() const override; + void writeToXml(QXmlStreamWriter& xmlOut) const override; + void readFromXml(QXmlStreamReader& xmlIn) override; + void addToHash(QCryptographicHash& cryptoHash) const override; + void setPinIds(const QList& ids) { mPinIds = ids; } + void addPinAction(PinAction::Type action) { mPinActions.prepend(action); } + void setSourceGroupId(u32 id) { mSourceGroupId = id; } + void setTargetGroupId(u32 id) { mTargetGroupId = id; } + void setPinOrderNo(int inx) { mPinOrderNo = inx; } + void setGroupOrderNo(int inx) { mGroupOrderNo = inx; } + void setName(const QString& name) { mName = name; } + u32 targetGroupId() const { return mTargetGroupId; } + }; + + /** + * @ingroup user_action + * @brief UserActionFactory for ActionPingroup + */ + class ActionPingroupFactory : public UserActionFactory + { + public: + ActionPingroupFactory(); + UserAction* newAction() const; + static ActionPingroupFactory* sFactory; + }; +} diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 73ef3e8b692..97b27bf9f2c 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -3,7 +3,7 @@ #include "gui/basic_tree_model/tree_item.h" #include "gui/gui_globals.h" #include "gui/input_dialog/input_dialog.h" -#include "gui/user_action/action_add_items_to_object.h" +#include "gui/user_action/action_pingroup.h" #include "gui/user_action/action_remove_items_from_object.h" #include "gui/user_action/action_reorder_object.h" #include "gui/user_action/user_action_compound.h" @@ -114,23 +114,33 @@ namespace hal if(type == "group") { if(!parentItem) - //qDebug() << "group was dropped between groups... with row: " << row; //check in canDropMine if its not an adjacent row? + { + qDebug() << "group was dropped between groups... with row: " << row; //check in canDropMine if its not an adjacent row? dndGroupBetweenGroup(droppedItem, row); + } else - //qDebug() << "group was dropped on a group?"; + { + qDebug() << "group was dropped on a group?"; dndGroupOnGroup(droppedItem, parentItem); + } } else { if(!parentItem) - //qDebug() << "pin was dropped between groups on row " << row; + { + qDebug() << "pin was dropped between groups on row " << row; dndPinBetweenGroup(droppedItem, row); + } else if(row != -1) - //qDebug() << "pin was dropped between pins"; + { + qDebug() << "pin was dropped between pins"; dndPinBetweenPin(droppedItem, parentItem, row); + } else - //qDebug() << "pin was dropped on a group..."; + { + qDebug() << "pin was dropped on a group..."; dndPinOnGroup(droppedItem, parentItem); + } } return true; @@ -475,23 +485,30 @@ namespace hal // InputDialog ipd("Name of new group", "Name of new group:", onDroppedGroup->getData(sNameColumn).toString()); // if(ipd.exec() == QDialog::Rejected) return false; mIgnoreEventsFlag = true; - QSet pins, e; - auto group = mModule->get_pin_group_by_id(getIdOfItem(droppedGroup)); - for(const auto &pin : group->get_pins()) - pins.insert(pin->get_id()); - - /* TODO PIN - UserActionCompound* compAct = new UserActionCompound; - ActionReorderObject* reorderActHack = new ActionReorderObject(droppedGroup->getOwnRow()); - reorderActHack->setObject(UserActionObject(group->get_id(), UserActionObjectType::PinGroup)); - reorderActHack->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - ActionAddItemsToObject* addAct = new ActionAddItemsToObject(e,e,e, pins); - addAct->setObject(UserActionObject(getIdOfItem(onDroppedGroup), UserActionObjectType::PinGroup)); - addAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - compAct->addAction(reorderActHack); - compAct->addAction(addAct); - compAct->exec(); - */ + QList pins; + auto srcgroup = mModule->get_pin_group_by_id(getIdOfItem(droppedGroup)); + for(const auto &pin : srcgroup->get_pins()) + pins.append(pin->get_id()); + if (pins.isEmpty()) return; // no pins to move + + auto tgtgroup = mModule->get_pin_group_by_id(getIdOfItem(onDroppedGroup)); + int ntgt = tgtgroup->size(); + if (pins.size()>1) + { + UserActionCompound* compAct = new UserActionCompound; + compAct->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + compAct->setUseCreatedObject(); + for (u32 pinId : pins) + compAct->addAction(new ActionPingroup(pinId,ntgt++,tgtgroup->get_id())); + compAct->exec(); + } + else + { + ActionPingroup* act = new ActionPingroup(pins.at(0),ntgt,tgtgroup->get_id()); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + act->exec(); + } + // too keep the order, ActionAddItemsToObject cannot be executed with all pins, but a ComAction must be created // with many ActionAddItemsToObject that contain a single pin each -> set destroys order of pins in source pingroup setModule(mModule); @@ -506,15 +523,11 @@ namespace hal bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; - //mModule->move_pin_group(mModule->get_pin_group_by_id(getIdOfItem(droppedGroup)), desiredIdx); - /* TODO PIN - ActionReorderObject* reordObj = new ActionReorderObject(desiredIdx); - reordObj->setObject(UserActionObject(getIdOfItem(droppedGroup), UserActionObjectType::PinGroup)); - reordObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); - auto ret = reordObj->exec(); - */ - bool ret = true; // TEMP - if(ret){ + ActionPingroup* act = new ActionPingroup(PinAction::MoveGroup,(u32)getIdOfItem(droppedGroup)); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + act->setPinOrderNo(desiredIdx); + bool ok = act->exec(); + if(ok){ removeItem(droppedGroup); insertItem(droppedGroup, mRootItem, desiredIdx); } @@ -524,13 +537,12 @@ namespace hal void ModulePinsTreeModel::dndPinOnGroup(TreeItem *droppedPin, TreeItem *onDroppedGroup) { mIgnoreEventsFlag = true; - QSet e; - /* TODO PIN - ActionAddItemsToObject* addAct = new ActionAddItemsToObject(e,e,e, QSet() << getIdOfItem(droppedPin)); - addAct->setObject(UserActionObject(getIdOfItem(onDroppedGroup), UserActionObjectType::PinGroup)); - addAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - addAct->exec(); - */ + u32 pinId = getIdOfItem(droppedPin); + + int inx = onDroppedGroup->getChildCount(); + ActionPingroup* act = new ActionPingroup(pinId,inx, getIdOfItem(onDroppedGroup)); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + act->exec(); auto oldParent = droppedPin->getParent(); removeItem(droppedPin); insertItem(droppedPin, onDroppedGroup, onDroppedGroup->getChildCount()); @@ -552,33 +564,11 @@ namespace hal bool bottomEdge = row == onDroppedParent->getChildCount(); desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; // insert item here - /* TODO PIN - ActionReorderObject* reorderObj = new ActionReorderObject(desiredIdx); - reorderObj->setObject(UserActionObject(getIdOfItem(droppedPin), UserActionObjectType::Pin)); - reorderObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); - reorderObj->exec(); - */ - } - else // different groups - { - // reorder action from source group is still needed (for undo action)! - /* TODO PIN - UserActionCompound* compAct = new UserActionCompound; - ActionReorderObject* reorderActHack = new ActionReorderObject(droppedPin->getOwnRow()); - reorderActHack->setObject(UserActionObject(getIdOfItem(droppedPin), UserActionObjectType::Pin)); - reorderActHack->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - ActionAddItemsToObject* addAct = new ActionAddItemsToObject(QSet(), QSet(), QSet(), QSet() << getIdOfItem(droppedPin)); - addAct->setObject(UserActionObject(getIdOfItem(onDroppedParent), UserActionObjectType::PinGroup)); - addAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - ActionReorderObject* reorderAct = new ActionReorderObject(row); - reorderAct->setObject(UserActionObject(getIdOfItem(droppedPin), UserActionObjectType::Pin)); - reorderAct->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); - compAct->addAction(reorderActHack); - compAct->addAction(addAct); - compAct->addAction(reorderAct); - compAct->exec(); - */ } + + ActionPingroup* act = new ActionPingroup(getIdOfItem(droppedPin),desiredIdx,getIdOfItem(onDroppedParent)); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + act->exec(); auto oldParent = droppedPin->getParent(); removeItem(droppedPin); insertItem(droppedPin, onDroppedParent, desiredIdx); @@ -595,19 +585,27 @@ namespace hal // row is needed for when groups can change its order within the module Q_UNUSED(row) mIgnoreEventsFlag = true; - auto pinGroup = mModule->get_pin_group_by_id(getIdOfItem(droppedPin->getParent())); - QSet e; - /* TODO PIN - ActionRemoveItemsFromObject* removeAct = new ActionRemoveItemsFromObject(e,e,e, QSet() << getIdOfItem(droppedPin)); - removeAct->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); - removeAct->setParentObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - bool ret = removeAct->exec(); - */ - bool ret = true; // TEMP - // must search for the created group (must secure way is to serve for a group that contains the pin id) - // and then move that group (the source group cannot be empty after the pin was removed -> canDropMimeData) - if(ret) // can fail if the pins name that one wants to remove has the same name as another group that already exists + + auto pinToMove = mModule->get_pin_by_id(getIdOfItem(droppedPin)); + if (!pinToMove) return; + + QString groupName = QString::fromStdString(pinToMove->get_name()); + QString baseName = groupName; + int cnt = 2; + while (mModule->get_pin_group_by_name(groupName.toStdString())) + // pin group name already exists + groupName = QString("%1_%2").arg(baseName).arg(cnt++); + + ActionPingroup* actMovePin = new ActionPingroup(pinToMove->get_id(),0,0,groupName); + actMovePin->setObject(UserActionObject(mModuleId, UserActionObjectType::Module)); + bool ok = actMovePin->exec(); + if (ok && actMovePin->targetGroupId()) { + ActionPingroup* actMoveGroup = new ActionPingroup(PinAction::MoveGroup,actMovePin->targetGroupId()); + actMoveGroup->setObject(UserActionObject(mModuleId, UserActionObjectType::Module)); + actMoveGroup->setPinOrderNo(row); + actMoveGroup->exec(); + auto newGroup = mModule->get_pin_by_id(getIdOfItem(droppedPin))->get_group().first; auto pinGroupName = QString::fromStdString(newGroup->get_name()); auto pinGroupDirection = QString::fromStdString(enum_to_string((newGroup->get_direction()))); @@ -619,14 +617,6 @@ namespace hal int pos = mRootItem->getChildCount(); // or query current index - /* TODO PIN - ActionReorderObject* reordObj = new ActionReorderObject(row); - reordObj->setObject(UserActionObject(newGroup->get_id(), UserActionObjectType::PinGroup)); - reordObj->setParentObject(UserActionObject(mModule->get_id(), UserActionObjectType::Module)); - if(reordObj->exec()) - pos = row; - */ - insertItem(pinGroupItem, mRootItem, pos); removeItem(droppedPin); insertItem(droppedPin, pinGroupItem, 0); diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp new file mode 100644 index 00000000000..d0c4f3ae54e --- /dev/null +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -0,0 +1,280 @@ +#include "gui/user_action/action_pingroup.h" +#include "gui/gui_globals.h" +#include "hal_core/netlist/grouping.h" +#include "gui/grouping/grouping_manager_widget.h" +#include "gui/graph_widget/contexts/graph_context.h" +#include + +namespace hal +{ + QString PinAction::toString(PinAction::Type tp) + { + QMetaEnum me = QMetaEnum::fromType(); + return QString(me.key(tp)); + } + + PinAction::Type PinAction::fromString(const QString &s) + { + QMetaEnum me = QMetaEnum::fromType(); + for (int t = None; t < MaxAction; t++) + if (s == me.key(t)) + { + return static_cast(t); + } + return None; + } + + ActionPingroupFactory::ActionPingroupFactory() + : UserActionFactory("Pingroup") {;} + + ActionPingroupFactory* ActionPingroupFactory::sFactory = new ActionPingroupFactory; + + UserAction* ActionPingroupFactory::newAction() const + { + return new ActionPingroup; + } + + QString ActionPingroup::tagname() const + { + return ActionPingroupFactory::sFactory->tagname(); + } + + ActionPingroup::ActionPingroup(PinAction::Type action, u32 pingroupId, const QString &name) + : mSourceGroupId(pingroupId), mTargetGroupId(pingroupId), mPinOrderNo(-1), mGroupOrderNo(-1), mName(name) + { + switch (action) + { + case PinAction::None: + break; + case PinAction::MovePin: + // use move constructor + break; + default: + mPinActions.append(action); + } + } + + ActionPingroup::ActionPingroup(u32 pinId, int pinIndex, u32 tgtgroupId, const QString& name, int grpIndex) + : mSourceGroupId(0), mTargetGroupId(tgtgroupId), mPinOrderNo(pinIndex), mGroupOrderNo(grpIndex), mName(name) + { + mPinIds.append(pinId); + mPinActions.append(PinAction::MovePin); + } + + void ActionPingroup::addToHash(QCryptographicHash &cryptoHash) const + { + for (PinAction::Type tp : mPinActions) + cryptoHash.addData((char*)(&tp),sizeof(tp)); + for (u32 pid: mPinIds) + cryptoHash.addData((char*)(&pid),sizeof(pid)); + cryptoHash.addData((char*)(&mSourceGroupId),sizeof(mSourceGroupId)); + cryptoHash.addData((char*)(&mTargetGroupId),sizeof(mTargetGroupId)); + cryptoHash.addData((char*)(&mPinOrderNo),sizeof(mPinOrderNo)); + cryptoHash.addData((char*)(&mGroupOrderNo),sizeof(mGroupOrderNo)); + } + + void ActionPingroup::writeToXml(QXmlStreamWriter& xmlOut) const + { + //todo: remove parentId, switch entirely to parentObject + if (!mPinActions.isEmpty()) + { + QString s; + for (PinAction::Type tp : mPinActions) + { + if (!s.isEmpty()) s += ','; + s += PinAction::toString(tp); + } + xmlOut.writeTextElement("pinactions", s); + } + if (!mPinIds.isEmpty()) + { + QString s; + for (u32 pinId : mPinIds) + { + if (!s.isEmpty()) s += ','; + s += QString::number(pinId); + } + xmlOut.writeTextElement("pinids", s); + } + if (mSourceGroupId) + xmlOut.writeTextElement("srcgroupid", QString::number(mSourceGroupId)); + if (mTargetGroupId) + xmlOut.writeTextElement("tgtgroupid", QString::number(mTargetGroupId)); + if (mPinOrderNo >= 0) + xmlOut.writeTextElement("pinorder", QString::number(mPinOrderNo)); + if (mGroupOrderNo >= 0) + xmlOut.writeTextElement("grporder", QString::number(mGroupOrderNo)); + } + + void ActionPingroup::readFromXml(QXmlStreamReader& xmlIn) + { + while (xmlIn.readNextStartElement()) + { + //todo: emove parentId, switch entirely to parentObject + readParentObjectFromXml(xmlIn); + if (xmlIn.name() == "pinactions") + { + for (QString pinact : xmlIn.readElementText().split(',')) + mPinActions.append(PinAction::fromString(pinact)); + } + if (xmlIn.name() == "pinids") + { + for (QString pinid : xmlIn.readElementText().split(',')) + mPinIds.append(pinid.toInt()); + } + if (xmlIn.name() == "srcgroupid") + mSourceGroupId = xmlIn.readElementText().toInt(); + if (xmlIn.name() == "tgtgroupid") + mTargetGroupId = xmlIn.readElementText().toInt(); + if (xmlIn.name() == "pinorder") + mPinOrderNo = xmlIn.readElementText().toInt(); + if (xmlIn.name() == "grporder") + mGroupOrderNo = xmlIn.readElementText().toInt(); + } + } + + bool ActionPingroup::exec() + { + if (mObject.type() != UserActionObjectType::Module) + return false; + + Module* parentModule = gNetlist->get_module_by_id(mObject.id()); + if (!parentModule) + return false; + + ActionPingroup* undo = nullptr; + + if (mPinActions.size()==1 && mPinActions.at(0) == PinAction::MovePin) + { + auto* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); + if (!pinToMove) return false; + auto* srcgrp = pinToMove->get_group().first; + if (!srcgrp) return false; + int currentIndex = pinToMove->get_group().second; + mSourceGroupId = srcgrp->get_id(); + undo = new ActionPingroup(pinToMove->get_id(), currentIndex, mSourceGroupId, QString::fromStdString(srcgrp->get_name())); + if (srcgrp->get_pins().size() == 1) mPinActions.append(PinAction::Delete); + if (mTargetGroupId) + { + auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + if (!tgtgrp) + tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); + if (!tgtgrp) + mTargetGroupId = 0; + } + else + { + auto* tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); + if (tgtgrp) + mTargetGroupId = tgtgrp->get_id(); + } + if (!mTargetGroupId) + { + // target group does not exist, create it + if (mName.isEmpty()) + mName = QString::fromStdString(pinToMove->get_name()); + mPinActions.replace(0,PinAction::Create); // create will place pins in new group + } + } + + + for (PinAction::Type act : mPinActions) + { + switch (act) + { + case PinAction::None: + break; + case PinAction::Create: + { + auto res = parentModule->create_pin_group(mName.toStdString()); + if(res.is_error()) + return false; + mTargetGroupId = res.get()->get_id(); + if (!mPinIds.isEmpty()) + { + auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + for (u32 pinId : mPinIds) + { + auto pin = parentModule->get_pin_by_id(pinId); + if (pin) pgrp->assign_pin(pin).is_ok(); + } + } + if (!undo) + undo = new ActionPingroup(PinAction::Delete, mTargetGroupId); + break; + } + case PinAction::Delete: + { + auto* pgrp = parentModule->get_pin_group_by_id(mSourceGroupId); + QList pins; + for (const auto& pin : pgrp->get_pins()) + { + pins.append(pin->get_id()); + } + if (!undo) + { + undo = new ActionPingroup(PinAction::Create, pgrp->get_id(), QString::fromStdString(pgrp->get_name())); + undo->setPinIds(pins); + } + break; + } + case PinAction::MovePin: + { + auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + auto* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); + if (!tgtgrp || !pinToMove) return false; + auto* srcgrp = pinToMove->get_group().first; + + if (srcgrp != tgtgrp) + { + if (tgtgrp->assign_pin(pinToMove).is_ok()) return false; + } + tgtgrp->move_pin(pinToMove,mPinOrderNo).is_ok(); + break; + } + case PinAction::MoveGroup: + { + PinGroup* srcgrp = nullptr; + int currentIndex = 0; + for (PinGroup* pgrp : parentModule->get_pin_groups()) + { + if (pgrp->get_id() == mSourceGroupId) + { + srcgrp = pgrp; + break; + } + ++ currentIndex; + } + if (!srcgrp) return false; + if (parentModule->move_pin_group(srcgrp,mPinOrderNo).is_error()) return false; + if (!undo) + { + undo = new ActionPingroup(PinAction::MoveGroup, mSourceGroupId); + undo->setPinOrderNo(currentIndex); + } + } + case PinAction::Rename: + { + auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + if (!pgrp) return false; + QString oldName = QString::fromStdString(pgrp->get_name()); + pgrp->set_name(mName.toStdString()); + if (undo) + { + undo->addPinAction(PinAction::Rename); + undo->setName(oldName); + } + else + undo = new ActionPingroup(PinAction::Rename, pgrp->get_id(), oldName); + break; + } + case PinAction::TypeChange: + break; + default: + break; + } + } + mUndoAction = undo; + return UserAction::exec(); + } +} From b712175a269d5ab9a4a4e6fc892701dec57a4f2b Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 5 Jul 2023 19:56:08 +0200 Subject: [PATCH 03/40] Implementation of ActionPingroup --- .../include/gui/user_action/action_pingroup.h | 23 +++- .../module_ports_tree.cpp | 79 +++++------- .../module_details_widget/port_tree_model.cpp | 3 +- .../gui/src/user_action/action_pingroup.cpp | 116 +++++++++++++----- 4 files changed, 134 insertions(+), 87 deletions(-) diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 8a7b011faa6..9a1e27e8c84 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -25,22 +25,25 @@ #pragma once #include "user_action.h" +#include "hal_core/netlist/module.h" #include #include namespace hal { + class PinAction : public QObject { Q_OBJECT public: - enum Type { None, Create, Delete, MovePin, MoveGroup, Rename, TypeChange, MaxAction }; + enum Type { None, Create, DeleteGroup, RemovePin, MovePin, MoveGroup, RenamePin, RenameGroup, TypeChange, MaxAction }; Q_ENUM(Type) public: static QString toString(Type tp); static Type fromString(const QString& s); }; + int pinGroupIndex(const Module* mod, const PinGroup* pgrp); /** * @ingroup user_action * @brief Pingroup user actions @@ -49,20 +52,27 @@ namespace hal * * Create: * Pingroup with given name gets created. - * Pins listed in mPinIds get moved into new group + * Pins listed in pinIds get moved into new group * Id of created group returned as targetGroupId() * - * Delete: - * Pingroup ID=mSourceGroupId gets deleted. + * DeleteGroup: + * Pingroup ID=sourceGroupId gets deleted. * Pins in group are stored for undo command * + * RemovePin: + * Remove pin from sourceGroup + * * MovePin: - * Must use move constructor with mandatory arguments pinId and targetIndex + * Must use move constructor with mandatory arguments pinId and pinOrderNo * One out of targetIndex (existing pingroup) or name (create new pingroup) * must be given to indicate destination * * MoveGroup: - * Move Group identified by sourceGroupId to new targetIndex + * Move Group identified by sourceGroupId to position groupOrderNo + * RenamePin: + * Set new name to first pin in pinIds + * RenameGroup: + * Set new name to group identified by targetGroupId */ class ActionPingroup : public UserAction { @@ -89,6 +99,7 @@ namespace hal void readFromXml(QXmlStreamReader& xmlIn) override; void addToHash(QCryptographicHash& cryptoHash) const override; void setPinIds(const QList& ids) { mPinIds = ids; } + void setPinId(u32 id) { mPinIds.clear(); mPinIds.append(id); } void addPinAction(PinAction::Type action) { mPinActions.prepend(action); } void setSourceGroupId(u32 id) { mSourceGroupId = id; } void setTargetGroupId(u32 id) { mTargetGroupId = id; } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index d5dd75a6ee8..96475ac7079 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -12,6 +12,7 @@ #include "gui/user_action/action_remove_items_from_object.h" #include "gui/user_action/action_rename_object.h" #include "gui/user_action/action_set_object_type.h" +#include "gui/user_action/action_pingroup.h" #include "gui/user_action/user_action_compound.h" #include "hal_core/netlist/gate_library/enums/pin_direction.h" #include "hal_core/netlist/gate_library/enums/pin_type.h" @@ -123,7 +124,7 @@ namespace hal PingroupSelectorDialog psd("Pingroup selector", "Select pingroup", mod, false); if (psd.exec() == QDialog::Accepted) { - QSet pinSet; + QList pins; auto* pinGroup = mod->get_pin_group_by_id(psd.getSelectedGroupId()); if (pinGroup == nullptr) return; @@ -132,14 +133,12 @@ namespace hal auto* pin = mod->get_pin_by_id(mPortModel->getIdOfItem(item)); if (pin == nullptr) return; - pinSet.insert(pin->get_id()); + pins.append(pin->get_id()); } - /* TODO PIN - ActionAddItemsToObject* act = new ActionAddItemsToObject(QSet(), QSet(), QSet(), pinSet); - act->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); - act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); + ActionPingroup* act = new ActionPingroup(PinAction::MovePin,pinGroup->get_id()); + act->setPinIds(pins); + act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); - */ } }); } @@ -155,12 +154,9 @@ namespace hal auto* group = gNetlist->get_module_by_id(modId)->get_pin_group_by_id(itemId); if (group != nullptr) { - /* TODO PIN - ActionRenameObject* renameObj = new ActionRenameObject(ipd.textValue()); - renameObj->setObject(UserActionObject(group->get_id(), UserActionObjectType::PinGroup)); - renameObj->setParentObject(UserActionObject(modId, UserActionObjectType::Module)); - renameObj->exec(); - */ + ActionPingroup* act = new ActionPingroup(PinAction::RenameGroup,itemId,ipd.textValue()); + act->setObject(UserActionObject(modId, UserActionObjectType::Module)); + act->exec(); } } }); @@ -168,12 +164,9 @@ namespace hal auto* pinGroup = mod->get_pin_group_by_id(itemId); if (pinGroup != nullptr) { - /* TDOD PIN - ActionDeleteObject* delObj = new ActionDeleteObject; - delObj->setObject(UserActionObject(pinGroup->get_id(), UserActionObjectType::PinGroup)); - delObj->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); - delObj->exec(); - */ + ActionPingroup* act = new ActionPingroup(PinAction::DeleteGroup,(u32)itemId); + act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); + act->exec(); } }); @@ -199,12 +192,10 @@ namespace hal auto* pin = mod->get_pin_by_id(itemId); if (pin != nullptr) { - /* TODO PIN - ActionRenameObject* renameObj = new ActionRenameObject(ipd.textValue()); - renameObj->setObject(UserActionObject(pin->get_id(), UserActionObjectType::Pin)); - renameObj->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); - renameObj->exec(); - */ + ActionPingroup* act = new ActionPingroup(PinAction::RenamePin,0,ipd.textValue()); + act->setPinId(pin->get_id()); + act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); + act->exec(); } } }); @@ -222,12 +213,10 @@ namespace hal if (cbd.exec() == QDialog::Accepted) { - /* TODO PIN - ActionSetObjectType* act = new ActionSetObjectType(cbd.textValue()); - act->setObject(UserActionObject(pin->get_id(), UserActionObjectType::Pin)); - act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); + ActionPingroup* act = new ActionPingroup(PinAction::TypeChange,0,cbd.textValue()); + act->setPinId(pin->get_id()); + act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); - */ } }); menu.addAction("Add net to current selection", [this, n]() { @@ -244,16 +233,14 @@ namespace hal if (sameGroup.first && mod->get_pin_group_by_id(sameGroup.second)->size() > 1) { menu.addAction("Remove selection from group", [this, selectedPins, mod, sameGroup]() { - QSet pins; + QList pins; for (auto item : selectedPins) - pins.insert(mPortModel->getIdOfItem(item)); + pins.append(mPortModel->getIdOfItem(item)); - /* TODO PIN - ActionRemoveItemsFromObject* act = new ActionRemoveItemsFromObject(QSet(), QSet(), QSet(), pins); - act->setObject(UserActionObject(mod->get_pin_group_by_id(sameGroup.second)->get_id(), UserActionObjectType::PinGroup)); - act->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); + ActionPingroup* act = new ActionPingroup(PinAction::RemovePin,mod->get_pin_group_by_id(sameGroup.second)->get_id()); + act->setPinIds(pins); + act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); - */ }); } @@ -288,26 +275,20 @@ namespace hal InputDialog ipd("Pingroup name", "New pingroup name", "ExampleName"); if (ipd.exec() == QDialog::Accepted && !ipd.textValue().isEmpty()) { - QSet pins; + QList pins; auto mod = gNetlist->get_module_by_id(modId); for (auto item : selectedPins) { auto* pin = mod->get_pin_by_id(mPortModel->getIdOfItem(item)); if (pin == nullptr) return; - pins.insert(pin->get_id()); + pins.append(pin->get_id()); } - /* TODO PIN - UserActionCompound* act = new UserActionCompound; - act->setUseCreatedObject(); - ActionCreateObject* actCreate = new ActionCreateObject(UserActionObjectType::PinGroup, ipd.textValue()); - actCreate->setParentObject(UserActionObject(modId, UserActionObjectType::Module)); - ActionAddItemsToObject* actAdd = new ActionAddItemsToObject(QSet(), QSet(), QSet(), pins); - actAdd->setUsedInCreateContext(); - act->addAction(actCreate); - act->addAction(actAdd); + + ActionPingroup* act = new ActionPingroup(PinAction::Create,0,ipd.textValue()); + act->setPinIds(pins); + act->setObject(UserActionObject(modId, UserActionObjectType::Module)); act->exec(); - */ } }); } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 97b27bf9f2c..c281c5bcdbf 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -523,8 +523,9 @@ namespace hal bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; - ActionPingroup* act = new ActionPingroup(PinAction::MoveGroup,(u32)getIdOfItem(droppedGroup)); + ActionPingroup* act = new ActionPingroup(PinAction::MoveGroup); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + act->setGroupOrderNo(getIdOfItem(droppedGroup)); act->setPinOrderNo(desiredIdx); bool ok = act->exec(); if(ok){ diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index d0c4f3ae54e..ccdfa68590e 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -7,6 +7,19 @@ namespace hal { + int pinGroupIndex(const Module* mod, const PinGroup* pgrp) + { + if (!mod || !pgrp) return -1; + int inx = 0; + for (const PinGroup* testgrp : mod->get_pin_groups()) + { + if (testgrp == pgrp) return inx; + ++inx; + } + return -1; + } + + QString PinAction::toString(PinAction::Type tp) { QMetaEnum me = QMetaEnum::fromType(); @@ -144,7 +157,8 @@ namespace hal ActionPingroup* undo = nullptr; - if (mPinActions.size()==1 && mPinActions.at(0) == PinAction::MovePin) + if (mPinActions.size()==1 && + (mPinActions.at(0) == PinAction::MovePin || mPinActions.at(0) == PinAction::RemovePin)) { auto* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); if (!pinToMove) return false; @@ -153,27 +167,30 @@ namespace hal int currentIndex = pinToMove->get_group().second; mSourceGroupId = srcgrp->get_id(); undo = new ActionPingroup(pinToMove->get_id(), currentIndex, mSourceGroupId, QString::fromStdString(srcgrp->get_name())); - if (srcgrp->get_pins().size() == 1) mPinActions.append(PinAction::Delete); - if (mTargetGroupId) - { - auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - if (!tgtgrp) - tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); - if (!tgtgrp) - mTargetGroupId = 0; - } - else + if (srcgrp->get_pins().size() == 1) mPinActions.append(PinAction::DeleteGroup); + if (mPinActions.at(0) == PinAction::MovePin) { - auto* tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); - if (tgtgrp) - mTargetGroupId = tgtgrp->get_id(); - } - if (!mTargetGroupId) - { - // target group does not exist, create it - if (mName.isEmpty()) - mName = QString::fromStdString(pinToMove->get_name()); - mPinActions.replace(0,PinAction::Create); // create will place pins in new group + if (mTargetGroupId) + { + auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + if (!tgtgrp) + tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); + if (!tgtgrp) + mTargetGroupId = 0; + } + else + { + auto* tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); + if (tgtgrp) + mTargetGroupId = tgtgrp->get_id(); + } + if (!mTargetGroupId) + { + // target group does not exist, create it + if (mName.isEmpty()) + mName = QString::fromStdString(pinToMove->get_name()); + mPinActions.replace(0,PinAction::Create); // create will place pins in new group + } } } @@ -199,13 +216,17 @@ namespace hal if (pin) pgrp->assign_pin(pin).is_ok(); } } + if (mGroupOrderNo >= 0) + parentModule->move_pin_group(res.get(),mGroupOrderNo).is_ok(); if (!undo) - undo = new ActionPingroup(PinAction::Delete, mTargetGroupId); + undo = new ActionPingroup(PinAction::DeleteGroup, mTargetGroupId); break; } - case PinAction::Delete: + case PinAction::DeleteGroup: { auto* pgrp = parentModule->get_pin_group_by_id(mSourceGroupId); + if (!pgrp) return false; + int currentIndex = pinGroupIndex(parentModule,pgrp); QList pins; for (const auto& pin : pgrp->get_pins()) { @@ -215,13 +236,14 @@ namespace hal { undo = new ActionPingroup(PinAction::Create, pgrp->get_id(), QString::fromStdString(pgrp->get_name())); undo->setPinIds(pins); + undo->setGroupOrderNo(currentIndex); } break; } case PinAction::MovePin: { - auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - auto* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); + PinGroup* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); + ModulePin* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); if (!tgtgrp || !pinToMove) return false; auto* srcgrp = pinToMove->get_group().first; @@ -232,6 +254,14 @@ namespace hal tgtgrp->move_pin(pinToMove,mPinOrderNo).is_ok(); break; } + case PinAction::RemovePin: + { + PinGroup* srcgrp = parentModule->get_pin_group_by_id(mSourceGroupId); + ModulePin* pinToRemove = parentModule->get_pin_by_id(mPinIds.at(0)); + if (!srcgrp || !pinToRemove) return false; + srcgrp->remove_pin(pinToRemove).is_ok(); + break; + } case PinAction::MoveGroup: { PinGroup* srcgrp = nullptr; @@ -253,27 +283,51 @@ namespace hal undo->setPinOrderNo(currentIndex); } } - case PinAction::Rename: + case PinAction::RenamePin: + { + if (mPinIds.isEmpty()) return false; + auto* pin = parentModule->get_pin_by_id(mPinIds.first()); + if (!pin) return false; + QString oldName = QString::fromStdString(pin->get_name()); + pin->set_name(mName.toStdString()); + if (!undo) + { + undo = new ActionPingroup(PinAction::RenamePin, pin->get_id(), oldName); + } + } + case PinAction::RenameGroup: { auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); if (!pgrp) return false; QString oldName = QString::fromStdString(pgrp->get_name()); pgrp->set_name(mName.toStdString()); - if (undo) + if (!undo) { - undo->addPinAction(PinAction::Rename); - undo->setName(oldName); + undo = new ActionPingroup(PinAction::RenameGroup, pgrp->get_id(), oldName); } - else - undo = new ActionPingroup(PinAction::Rename, pgrp->get_id(), oldName); break; } case PinAction::TypeChange: + { + if (mPinIds.isEmpty()) return false; + auto* pin = parentModule->get_pin_by_id(mPinIds.first()); + if (!pin) return false; + PinType ptype = enum_from_string(mName.toStdString(),PinType::none); + PinType oldPtype = pin->get_type(); + pin->set_type(ptype); + if (!undo) + { + undo = new ActionPingroup(PinAction::TypeChange, 0, QString::fromStdString(enum_to_string(oldPtype))); + undo->setPinId(pin->get_id()); + } break; + } default: break; } } + if (undo) + undo->setObject(object()); mUndoAction = undo; return UserAction::exec(); } From 8cb19359260e73111fb62b85ab98b4e1cd4813ca Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 7 Jul 2023 21:15:02 +0200 Subject: [PATCH 04/40] Data added to pin_changed event --- .../netlist/event_system/event_handler.h | 2 +- .../netlist/gate_library/enums/pin_type.h | 18 ++++++- include/hal_core/netlist/module.h | 2 + .../gui/graph_widget/graph_context_manager.h | 3 +- .../include/gui/netlist_relay/netlist_relay.h | 3 +- .../graph_widget/graph_context_manager.cpp | 2 +- .../gui/src/netlist_relay/netlist_relay.cpp | 9 ++-- src/netlist/module.cpp | 54 +++++++++++++------ 8 files changed, 67 insertions(+), 26 deletions(-) diff --git a/include/hal_core/netlist/event_system/event_handler.h b/include/hal_core/netlist/event_system/event_handler.h index 06c6b13372c..58570fdd81d 100644 --- a/include/hal_core/netlist/event_system/event_handler.h +++ b/include/hal_core/netlist/event_system/event_handler.h @@ -114,7 +114,7 @@ namespace hal gates_remove_begin, ///< associated_data = number of gates to remove gates_remove_end, ///< associated_data = number of removed gates gate_removed, ///< associated_data = id of removed gate - pin_changed, ///< no associated_data + pin_changed, ///< associated_data = [4LSB: type of action] [28HSB: id of pin group or pin] }; }; diff --git a/include/hal_core/netlist/gate_library/enums/pin_type.h b/include/hal_core/netlist/gate_library/enums/pin_type.h index 295e7d0acbc..ec073a7768b 100644 --- a/include/hal_core/netlist/gate_library/enums/pin_type.h +++ b/include/hal_core/netlist/gate_library/enums/pin_type.h @@ -54,4 +54,20 @@ namespace hal template<> std::map EnumStrings::data; -} // namespace hal \ No newline at end of file + + enum class PinEvent + { + unknown, + GroupCreate, + GroupReorder, + GroupRename, + GroupTypeChange, + GroupPinAssign, + GroupDelete, + PinCreate, + PinReorder, + PinRename, + PinTypeChange, + PinDelete + }; +} // namespace hal diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index df6c1f52728..c2951c23d37 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -688,6 +688,8 @@ namespace hal bool has_external_destination; }; + static u32 pinevent_associated_data(PinEvent pev, u32 id); + NetConnectivity check_net_endpoints(const Net* net) const; Result check_net(Net* net, bool recursive = false); Result assign_pin_net(const u32 pin_id, Net* net, PinDirection direction, const std::string& name = "", PinType type = PinType::none); diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 55634c4aedb..46ef593ad04 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -26,6 +26,7 @@ #pragma once #include "hal_core/defines.h" +#include "hal_core/netlist/gate_library/enums/pin_type.h" #include #include @@ -193,7 +194,7 @@ namespace hal * * @param m - The module with the changed port */ - void handleModulePortsChanged(Module* m); + void handleModulePortsChanged(Module* m, hal::PinEvent pev, u32 pgid); /** * Handler to be called after a gate has been removed.
diff --git a/plugins/gui/include/gui/netlist_relay/netlist_relay.h b/plugins/gui/include/gui/netlist_relay/netlist_relay.h index 03a8bd3fb1b..6733a89cc50 100644 --- a/plugins/gui/include/gui/netlist_relay/netlist_relay.h +++ b/plugins/gui/include/gui/netlist_relay/netlist_relay.h @@ -26,6 +26,7 @@ #pragma once #include "hal_core/netlist/event_system/event_handler.h" +#include "hal_core/netlist/gate_library/enums/pin_type.h" #include "gui/grouping/grouping_color_serializer.h" #include #include @@ -332,7 +333,7 @@ namespace hal * @param m - The module with the changed port * @param respective_net - The id of the net of the renamed input port */ - void modulePortsChanged(Module* m) const; + void modulePortsChanged(Module* m, PinEvent pev, u32 pgid) const; /** * Q_SIGNAL to notify that the type of a module has been changed.
diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index e050e5b9452..04d21ad52df 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -348,7 +348,7 @@ namespace hal xout << "-------\n"; } - void GraphContextManager::handleModulePortsChanged(Module* m) + void GraphContextManager::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { for (GraphContext* context : mContextTableModel->list()) if (context->modules().contains(m->get_id())) diff --git a/plugins/gui/src/netlist_relay/netlist_relay.cpp b/plugins/gui/src/netlist_relay/netlist_relay.cpp index 92655c372ae..73448a0c97c 100644 --- a/plugins/gui/src/netlist_relay/netlist_relay.cpp +++ b/plugins/gui/src/netlist_relay/netlist_relay.cpp @@ -448,11 +448,12 @@ namespace hal break; } case ModuleEvent::event::pin_changed: { - //< no associated_data - - gGraphContextManager->handleModulePortsChanged(mod); + //< associated_data = [4LSB: type of action] [28HSB: id of pin group or pin] + PinEvent pev = (PinEvent) (associated_data&0xF); + u32 id = (associated_data >> 4); + gGraphContextManager->handleModulePortsChanged(mod,pev,id); - Q_EMIT modulePortsChanged(mod); + Q_EMIT modulePortsChanged(mod,pev,id); break; } case ModuleEvent::event::type_changed: { diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 9b71ca00efd..6db8cc112e9 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -660,13 +660,13 @@ namespace hal { m_output_nets.insert(net); pin->set_direction(PinDirection::inout); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); } else if (direction == PinDirection::output) { m_input_nets.insert(net); pin->set_direction(PinDirection::inout); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); } } else @@ -687,7 +687,7 @@ namespace hal m_input_nets.insert(net); m_output_nets.erase(net); pin->set_direction(PinDirection::input); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); } } else @@ -709,7 +709,7 @@ namespace hal m_output_nets.insert(net); m_input_nets.erase(net); pin->set_direction(PinDirection::output); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); } } else @@ -831,6 +831,7 @@ namespace hal } else { + // create_pin_internal OK if (create_group) { if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name, direction, type, false, 0); group_res.is_error()) @@ -840,6 +841,7 @@ namespace hal } else { + // create_pin_group_internal OK if (const auto assign_res = group_res.get()->assign_pin(pin_res.get()); assign_res.is_error()) { assert(delete_pin_internal(pin_res.get()).is_ok()); @@ -847,9 +849,17 @@ namespace hal return ERR_APPEND(assign_res.get_error(), "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to assign pin to pin group"); } + else + { + // pin assigned to new group OK + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,group_res.get()->get_id())); + } } } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + else + { + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinCreate,pin_res.get()->get_id())); + } return pin_res; } } @@ -1093,7 +1103,7 @@ namespace hal m_pin_names_map.erase(old_name); pin->set_name(new_name); m_pin_names_map[new_name] = pin; - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinRename,pin->get_id())); } return true; @@ -1116,7 +1126,7 @@ namespace hal if (pin->get_type() != new_type) { pin->set_type(new_type); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); } return true; @@ -1161,7 +1171,7 @@ namespace hal m_pin_group_names_map.erase(old_name); pin_group->set_name(new_name); m_pin_group_names_map[new_name] = pin_group; - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupRename,pin_group->get_id())); } return true; @@ -1185,7 +1195,7 @@ namespace hal if (pin_group->get_type() != new_type) { pin_group->set_type(new_type); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupTypeChange,pin_group->get_id())); } return true; } @@ -1212,7 +1222,7 @@ namespace hal if (pin_group->get_direction() != new_direction) { pin_group->set_direction(new_direction); - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupTypeChange,pin_group->get_id())); } return true; } @@ -1260,7 +1270,7 @@ namespace hal } } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,pin_group->get_id())); return OK(pin_group); } @@ -1295,6 +1305,8 @@ namespace hal } } + u32 pin_group_id_to_delete = pin_group->get_id(); + if (auto res = delete_pin_group_internal(pin_group); res.is_error()) { return ERR(res.get_error()); @@ -1302,7 +1314,7 @@ namespace hal if (removed_pins) { - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); } return OK({}); } @@ -1343,7 +1355,7 @@ namespace hal m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it); } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupReorder,pin_group->get_id())); return OK({}); } @@ -1402,7 +1414,7 @@ namespace hal + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id)); } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupPinAssign,pin_group->get_id())); return OK({}); } @@ -1438,7 +1450,7 @@ namespace hal + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id)); } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinReorder,pin->get_id())); return OK({}); } @@ -1533,7 +1545,7 @@ namespace hal } } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,pin->get_group().first->get_id())); return OK(pin); } @@ -1565,6 +1577,8 @@ namespace hal } } + u32 pin_id_to_delete = pin->get_id(); + if (const auto res = delete_pin_internal(pin); res.is_error()) { return ERR_APPEND(res.get_error(), @@ -1572,7 +1586,7 @@ namespace hal + ": failed to delete pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id())); } - m_event_handler->notify(ModuleEvent::event::pin_changed, this); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinDelete,pin_id_to_delete)); return OK({}); } @@ -1705,4 +1719,10 @@ namespace hal return OK({}); } + + u32 Module::pinevent_associated_data(PinEvent pev, u32 id) + { + return (id << 4) | (((u32)pev)&0xF); + } + } // namespace hal From 527138cbf498f47afcbf96fe37820d681a8f4ea7 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 13 Jul 2023 14:47:36 +0200 Subject: [PATCH 05/40] Fix: execute module pin method, avoid direct access to pin(group) method --- plugins/gui/src/user_action/action_pingroup.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index ccdfa68590e..12bb68034e9 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -232,6 +232,7 @@ namespace hal { pins.append(pin->get_id()); } + if (parentModule->delete_pin_group(pgrp).is_error()) return false; if (!undo) { undo = new ActionPingroup(PinAction::Create, pgrp->get_id(), QString::fromStdString(pgrp->get_name())); @@ -289,7 +290,7 @@ namespace hal auto* pin = parentModule->get_pin_by_id(mPinIds.first()); if (!pin) return false; QString oldName = QString::fromStdString(pin->get_name()); - pin->set_name(mName.toStdString()); + if (!parentModule->set_pin_name(pin,mName.toStdString())) return false; // RenamePin if (!undo) { undo = new ActionPingroup(PinAction::RenamePin, pin->get_id(), oldName); @@ -300,7 +301,7 @@ namespace hal auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); if (!pgrp) return false; QString oldName = QString::fromStdString(pgrp->get_name()); - pgrp->set_name(mName.toStdString()); + if (!parentModule->set_pin_group_name(pgrp,mName.toStdString())) return false; // RenameGroup if (!undo) { undo = new ActionPingroup(PinAction::RenameGroup, pgrp->get_id(), oldName); @@ -314,7 +315,7 @@ namespace hal if (!pin) return false; PinType ptype = enum_from_string(mName.toStdString(),PinType::none); PinType oldPtype = pin->get_type(); - pin->set_type(ptype); + if (!parentModule->set_pin_type(pin,ptype)) return false; // TypeChange if (!undo) { undo = new ActionPingroup(PinAction::TypeChange, 0, QString::fromStdString(enum_to_string(oldPtype))); From 9c94b1194beb2b6efbf856ea26bcac169e75ad33 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 17 Jul 2023 09:54:13 +0200 Subject: [PATCH 06/40] add parameter to handleModulePortsChanged --- plugins/gui/include/gui/graph_widget/graph_context_manager.h | 2 +- .../module_details_widget/port_tree_model.h | 3 ++- plugins/gui/src/graph_widget/graph_context_manager.cpp | 2 ++ .../module_details_widget/port_tree_model.cpp | 4 +++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 46ef593ad04..82bf325352d 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -194,7 +194,7 @@ namespace hal * * @param m - The module with the changed port */ - void handleModulePortsChanged(Module* m, hal::PinEvent pev, u32 pgid); + void handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid); /** * Handler to be called after a gate has been removed.
diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 349bc1e0422..d8dc53dc206 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -27,6 +27,7 @@ //#include "gui/new_selection_details_widget/models/base_tree_model.h" #include "gui/basic_tree_model/base_tree_model.h" +#include "hal_core/netlist/gate_library/enums/pin_type.h" #include namespace hal @@ -117,7 +118,7 @@ namespace hal /** @name Event Handler Functions */ ///@{ - void handleModulePortsChanged(Module* m); + void handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid); ///@} //column identifier diff --git a/plugins/gui/src/graph_widget/graph_context_manager.cpp b/plugins/gui/src/graph_widget/graph_context_manager.cpp index 04d21ad52df..08cab39c589 100644 --- a/plugins/gui/src/graph_widget/graph_context_manager.cpp +++ b/plugins/gui/src/graph_widget/graph_context_manager.cpp @@ -350,6 +350,8 @@ namespace hal void GraphContextManager::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { + Q_UNUSED(pev); + Q_UNUSED(pgid); for (GraphContext* context : mContextTableModel->list()) if (context->modules().contains(m->get_id())) { diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index c281c5bcdbf..fe52aefa594 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -469,8 +469,10 @@ namespace hal return item->getAdditionalData(keyId).toInt(); } - void ModulePinsTreeModel::handleModulePortsChanged(Module* m) + void ModulePinsTreeModel::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { + Q_UNUSED(pev); + Q_UNUSED(pgid); if ((int)m->get_id() == mModuleId) { if (!mIgnoreEventsFlag) From 7a95b05a6e2f9c6bee58d5f4f9c5a6c8159a7507 Mon Sep 17 00:00:00 2001 From: joern274 Date: Sun, 23 Jul 2023 12:11:56 +0200 Subject: [PATCH 07/40] action_pingroup re-organized (work in progress, does not build) --- .../include/gui/user_action/action_pingroup.h | 110 +++++---- .../gui/src/user_action/action_pingroup.cpp | 215 +++++++++++------- 2 files changed, 207 insertions(+), 118 deletions(-) diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 9a1e27e8c84..5a79b8b382e 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -31,59 +31,91 @@ namespace hal { - - class PinAction : public QObject + class PinActionType : public QObject { Q_OBJECT public: - enum Type { None, Create, DeleteGroup, RemovePin, MovePin, MoveGroup, RenamePin, RenameGroup, TypeChange, MaxAction }; - Q_ENUM(Type) + enum Type { None, GroupCreate, GroupDelete, GroupMove, GroupRename, GroupTypechange, GroupDirection, + PinAddgroup, PinRename, PinTypechange, PinDirection, PinSetindex, MaxAction }; + Q_ENUM(Type); + public: static QString toString(Type tp); static Type fromString(const QString& s); + static bool useExistingGroup(Type tp); + static bool useExistingPin(Type tp); }; int pinGroupIndex(const Module* mod, const PinGroup* pgrp); + /** * @ingroup user_action * @brief Pingroup user actions * - * Action depends on PinAction::Type: + * Arguments depends on PinActionType::Type: + * + * GroupCreate: + * ID : ID of group to create + * negative ID: call constructor without ID, however, + * ID will be used internally for subsequent commands related to crated group + * name : name of group + * value : start index, assume ascending + * negative value: descending order starting with (-value) + * + * GroupDelete + * ID : ID of group to delete + * + * GroupMove + * ID : ID of group to move + * value : new position in vector of pin groups * - * Create: - * Pingroup with given name gets created. - * Pins listed in pinIds get moved into new group - * Id of created group returned as targetGroupId() + * GroupRename + * ID : ID of group to rename + * name : new name * - * DeleteGroup: - * Pingroup ID=sourceGroupId gets deleted. - * Pins in group are stored for undo command + * GroupTypechange + * ID : ID of group to modifiy + * value : (int) PinType as of hal_core/netlist/gate_library/enums/pin_type.h * - * RemovePin: - * Remove pin from sourceGroup + * GroupDirection + * ID : ID of group to modifiy + * value : (int) PinDirection as of hal_core/netlist/gate_library/enums/pin_direction.h * - * MovePin: - * Must use move constructor with mandatory arguments pinId and pinOrderNo - * One out of targetIndex (existing pingroup) or name (create new pingroup) - * must be given to indicate destination + * PinAddgroup + * ID : ID of pin + * value : ID of group, might be negative if group recently created * - * MoveGroup: - * Move Group identified by sourceGroupId to position groupOrderNo - * RenamePin: - * Set new name to first pin in pinIds - * RenameGroup: - * Set new name to group identified by targetGroupId + * PinRename + * ID : ID of pin to rename + * name : new name + * + * PinTypechange + * ID : ID of pin to modify + * value : (int) PinType + * + * PinDirection + * ID : ID of pin to modify + * value : (int) PinDirection + * + * PinSetindex + * ID : ID of pin + * value : new index in pingroup. Calculated from row by + * index = startindex + a * row with a=1 for ascending, a=-1 for descending */ class ActionPingroup : public UserAction { + class AtomicAction + { + public: + PinActionType::Type mType; + int mId; + QString mName; + int mValue; + AtomicAction(PinActionType::Type tp, int id, const QString& name = QString(), int v=0) : mType(tp), mId(id), mName(name), mValue(v) {;} + }; + private: - QList mPinActions; - QList mPinIds; - u32 mSourceGroupId; - u32 mTargetGroupId; - int mPinOrderNo; - int mGroupOrderNo; - QString mName; + QList mPinActions; public: /** * Action Constructor. @@ -91,22 +123,16 @@ namespace hal * @param type - The UserActionObjectType of the item that should be created (default type: None) * @param objName - The name of the object to create (default name: ""). */ - ActionPingroup(PinAction::Type action = PinAction::None, u32 pingroupId = 0, const QString& name=QString()); - ActionPingroup(u32 pinId, int pinIndex, u32 tgtgroupId=0, const QString& name=QString(), int grpIndex=-1); // action = MovePin + ActionPingroup(PinActionType::Type tp = PinActionType::None, u32 id = 0, const QString& name=QString(), int value=0); bool exec() override; QString tagname() const override; void writeToXml(QXmlStreamWriter& xmlOut) const override; void readFromXml(QXmlStreamReader& xmlIn) override; void addToHash(QCryptographicHash& cryptoHash) const override; - void setPinIds(const QList& ids) { mPinIds = ids; } - void setPinId(u32 id) { mPinIds.clear(); mPinIds.append(id); } - void addPinAction(PinAction::Type action) { mPinActions.prepend(action); } - void setSourceGroupId(u32 id) { mSourceGroupId = id; } - void setTargetGroupId(u32 id) { mTargetGroupId = id; } - void setPinOrderNo(int inx) { mPinOrderNo = inx; } - void setGroupOrderNo(int inx) { mGroupOrderNo = inx; } - void setName(const QString& name) { mName = name; } - u32 targetGroupId() const { return mTargetGroupId; } + + static ActionPingroup* addPinsToExistingGroup(u32 grpId, QList pinIds); + static ActionPingroup* addPinsToNewGroup(const QString& name, QList pinIds); + static ActionPingroup* addPinToNewGroup(const QString& name, u32 pinId); }; /** diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 12bb68034e9..0cf9a00af32 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -20,13 +20,13 @@ namespace hal } - QString PinAction::toString(PinAction::Type tp) + QString PinActionType::toString(PinActionType::Type tp) { QMetaEnum me = QMetaEnum::fromType(); return QString(me.key(tp)); } - PinAction::Type PinAction::fromString(const QString &s) + PinActionType::Type PinActionType::fromString(const QString &s) { QMetaEnum me = QMetaEnum::fromType(); for (int t = None; t < MaxAction; t++) @@ -37,6 +37,18 @@ namespace hal return None; } + bool PinActionType::useExistingGroup(PinActionType::Type tp) + { + static const QSet types = {GroupDelete, GroupMove, GroupRename, GroupTypechange, GroupDirection}; + return types.contains(tp); + } + + bool PinActionType::useExistingPin(PinActionType::Type tp) + { + static const QSet types = {PinAddgroup, PinRename, PinTypechange, PinDirection, PinSetindex}; + return types.contains(tp); + } + ActionPingroupFactory::ActionPingroupFactory() : UserActionFactory("Pingroup") {;} @@ -52,97 +64,57 @@ namespace hal return ActionPingroupFactory::sFactory->tagname(); } - ActionPingroup::ActionPingroup(PinAction::Type action, u32 pingroupId, const QString &name) - : mSourceGroupId(pingroupId), mTargetGroupId(pingroupId), mPinOrderNo(-1), mGroupOrderNo(-1), mName(name) + ActionPingroup::ActionPingroup(PinActionType::Type tp, u32 id, const QString &name, int value) { - switch (action) - { - case PinAction::None: - break; - case PinAction::MovePin: - // use move constructor - break; - default: - mPinActions.append(action); - } - } - - ActionPingroup::ActionPingroup(u32 pinId, int pinIndex, u32 tgtgroupId, const QString& name, int grpIndex) - : mSourceGroupId(0), mTargetGroupId(tgtgroupId), mPinOrderNo(pinIndex), mGroupOrderNo(grpIndex), mName(name) - { - mPinIds.append(pinId); - mPinActions.append(PinAction::MovePin); + mPinActions.append(AtomicAction(tp, id, name, value)); } void ActionPingroup::addToHash(QCryptographicHash &cryptoHash) const { - for (PinAction::Type tp : mPinActions) - cryptoHash.addData((char*)(&tp),sizeof(tp)); - for (u32 pid: mPinIds) - cryptoHash.addData((char*)(&pid),sizeof(pid)); - cryptoHash.addData((char*)(&mSourceGroupId),sizeof(mSourceGroupId)); - cryptoHash.addData((char*)(&mTargetGroupId),sizeof(mTargetGroupId)); - cryptoHash.addData((char*)(&mPinOrderNo),sizeof(mPinOrderNo)); - cryptoHash.addData((char*)(&mGroupOrderNo),sizeof(mGroupOrderNo)); + for (const AtomicAction& aa : mPinActions) + { + cryptoHash.addData((char*)(&aa.mType),sizeof(aa.mType)); + cryptoHash.addData((char*)(&aa.mId),sizeof(aa.mId)); + cryptoHash.addData(aa.mName.toUtf8()); + cryptoHash.addData((char*)(&aa.mValue),sizeof(aa.mValue)); + } } void ActionPingroup::writeToXml(QXmlStreamWriter& xmlOut) const { - //todo: remove parentId, switch entirely to parentObject - if (!mPinActions.isEmpty()) - { - QString s; - for (PinAction::Type tp : mPinActions) - { - if (!s.isEmpty()) s += ','; - s += PinAction::toString(tp); - } - xmlOut.writeTextElement("pinactions", s); - } - if (!mPinIds.isEmpty()) + // TODO xml parent element + for (const AtomicAction& aa : mPinActions) { - QString s; - for (u32 pinId : mPinIds) - { - if (!s.isEmpty()) s += ','; - s += QString::number(pinId); - } - xmlOut.writeTextElement("pinids", s); + if (aa.mType != PinActionType::None) + xmlOut.writeTextElement("type", PinActionType::toString(aa.mType)); + if (aa.mId) + xmlOut.writeTextElement("id", QString::number(aa.mId)); + if (!aa.mName.isEmpty()) + xmlOut.writeTextElement("name", aa.mName); + if (aa.mValue) + xmlOut.writeTextElement("value", QString::number(aa.mValue)); } - if (mSourceGroupId) - xmlOut.writeTextElement("srcgroupid", QString::number(mSourceGroupId)); - if (mTargetGroupId) - xmlOut.writeTextElement("tgtgroupid", QString::number(mTargetGroupId)); - if (mPinOrderNo >= 0) - xmlOut.writeTextElement("pinorder", QString::number(mPinOrderNo)); - if (mGroupOrderNo >= 0) - xmlOut.writeTextElement("grporder", QString::number(mGroupOrderNo)); } void ActionPingroup::readFromXml(QXmlStreamReader& xmlIn) { + // TODO loop xml parent element while (xmlIn.readNextStartElement()) { - //todo: emove parentId, switch entirely to parentObject - readParentObjectFromXml(xmlIn); - if (xmlIn.name() == "pinactions") - { - for (QString pinact : xmlIn.readElementText().split(',')) - mPinActions.append(PinAction::fromString(pinact)); - } - if (xmlIn.name() == "pinids") - { - for (QString pinid : xmlIn.readElementText().split(',')) - mPinIds.append(pinid.toInt()); - } - if (xmlIn.name() == "srcgroupid") - mSourceGroupId = xmlIn.readElementText().toInt(); - if (xmlIn.name() == "tgtgroupid") - mTargetGroupId = xmlIn.readElementText().toInt(); - if (xmlIn.name() == "pinorder") - mPinOrderNo = xmlIn.readElementText().toInt(); - if (xmlIn.name() == "grporder") - mGroupOrderNo = xmlIn.readElementText().toInt(); + PinActionType::Type tp = PinActionType::None; + int id = 0; + QString name; + int val = 0; + + if (xmlIn.name() == "type") + tp = PinActionType::fromString(xmlIn.readElementText()); + if (xmlIn.name() == "id") + id = xmlIn.readElementText().toInt(); + if (xmlIn.name() == "name") + name = xmlIn.readElementText(); + if (xmlIn.name() == "value") + val = xmlIn.readElementText().toInt(); + mPinActions.append(AtomicAction(tp,id,name,val)); } } @@ -157,6 +129,96 @@ namespace hal ActionPingroup* undo = nullptr; + QHash*> pgroups; + + for (const AtomicAction& aa : mPinActions) + { + PinGroup* pgroup = nullptr; + ModulePin* pin = nullptr; + + if (PinActionType::useExistingGroup(aa.mType)) + { + auto it = pgroups.find(aa.mId); + if (it == pgroups.end()) + { + pgroup = parentModule->get_pin_group_by_id(aa.mId); + if (!pgroup) return false; + pgroups.insert(aa.mId,pgroup); + } + else + pgroup = it.value(); + } + + if (PinActionType::useExistingPin(aa.mType)) + { + pin = parentModule->get_pin_by_id(aa.mId); + } + + switch (aa.mType) + { + case PinActionType::GroupCreate: + { + int startIndex = aa.mValue; + bool ascending = true; + if (aa.mValue < 0) + { + ascending = false; + startIndex = -aa.mValue; + } + if (aa.mId > 0) + { + if (auto res = parentModule->create_pin_group(aa.mId, aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) + pgroups.insert(aa.mId,res.get()); + else + return false; + } + else + { + if (auto res = parentModule->create_pin_group(aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) + pgroups.insert(aa.mId,res.get()); + else + return false; + } + break; + } + case PinActionType::GroupDelete: + if (parentModule->delete_pin_group(pgroup).is_error()) + return false; + break; + case PinActionType::GroupMove: + if (parentModule->move_pin_group(pgroup,aa.mValue).is_error()) + return false; + break; + case PinActionType::GroupRename: + if (!parentModule->set_pin_group_name(pgroup,aa.mName.toStdString())) + return false; + break; + case PinActionType::GroupTypechange: + if (!parentModule->set_pin_group_type(pgroup, (PinType) aa.mValue)) + return false; + break; + case PinActionType::GroupDirection: + if (!parentModule->set_pin_group_direction(pgroup, (PinDirection) aa.mValue)) + return false; + break; + case PinActionType::PinAddgroup: + break; + case PinActionType::PinRename: + if (!parentModule->set_pin_name(pin, aa.mName.toStdString())) + return false; + break; + case PinActionType::PinTypechange: + if (!parentModule->set_pin_type(pin, (PinType) aa.mValue)) + return false; + break; + case PinActionType::PinSetindex: + break; + default: + break; + } + } + + /* if (mPinActions.size()==1 && (mPinActions.at(0) == PinAction::MovePin || mPinActions.at(0) == PinAction::RemovePin)) { @@ -327,6 +389,7 @@ namespace hal break; } } + */ if (undo) undo->setObject(object()); mUndoAction = undo; From d69c988e3dba63395cbe8b858e9e8d00db688ffc Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 24 Jul 2023 19:21:29 +0200 Subject: [PATCH 08/40] action_pingroup re-organized --- .../include/gui/user_action/action_pingroup.h | 47 +- .../module_ports_tree.cpp | 34 +- .../module_details_widget/port_tree_model.cpp | 40 +- .../gui/src/user_action/action_pingroup.cpp | 446 ++++++++++-------- 4 files changed, 317 insertions(+), 250 deletions(-) diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 5a79b8b382e..26703e791e6 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -36,7 +36,7 @@ namespace hal Q_OBJECT public: enum Type { None, GroupCreate, GroupDelete, GroupMove, GroupRename, GroupTypechange, GroupDirection, - PinAddgroup, PinRename, PinTypechange, PinDirection, PinSetindex, MaxAction }; + PinAsignGroup, PinRename, PinTypechange, PinDirection, PinSetindex, MaxAction }; Q_ENUM(Type); public: @@ -81,7 +81,7 @@ namespace hal * ID : ID of group to modifiy * value : (int) PinDirection as of hal_core/netlist/gate_library/enums/pin_direction.h * - * PinAddgroup + * PinAsignGroup * ID : ID of pin * value : ID of group, might be negative if group recently created * @@ -104,6 +104,7 @@ namespace hal */ class ActionPingroup : public UserAction { + private: class AtomicAction { public: @@ -114,25 +115,45 @@ namespace hal AtomicAction(PinActionType::Type tp, int id, const QString& name = QString(), int v=0) : mType(tp), mId(id), mName(name), mValue(v) {;} }; - private: + class GroupRestore + { + public: + int mId; + QString mName; + int mRow; + int mStartIndex; + PinDirection mDirection; + PinType mType; + GroupRestore(Module* m, PinGroup* pgroup); + }; + + QHash*> mPinGroups; QList mPinActions; + Module* mParentModule; + QMap mGroupRestore; + QSet mPinsMoved; + QSet mGroupToRemove; + + PinGroup* getGroup(ModulePin* pin) const; + PinGroup* getGroup(int grpId) const; + void prepareUndoAction(); + void finalizeUndoAction(); + void addUndoAction(PinActionType::Type tp, int id = 0, const QString& name=QString(), int value=0); + static int pinGroupRow(Module* m, PinGroup* pgroup); public: - /** - * Action Constructor. - * - * @param type - The UserActionObjectType of the item that should be created (default type: None) - * @param objName - The name of the object to create (default name: ""). - */ - ActionPingroup(PinActionType::Type tp = PinActionType::None, u32 id = 0, const QString& name=QString(), int value=0); + ActionPingroup(PinActionType::Type tp = PinActionType::None, int id = 0, const QString& name=QString(), int value=0); + ActionPingroup(const QList& aaList); bool exec() override; QString tagname() const override; void writeToXml(QXmlStreamWriter& xmlOut) const override; void readFromXml(QXmlStreamReader& xmlIn) override; void addToHash(QCryptographicHash& cryptoHash) const override; - static ActionPingroup* addPinsToExistingGroup(u32 grpId, QList pinIds); - static ActionPingroup* addPinsToNewGroup(const QString& name, QList pinIds); - static ActionPingroup* addPinToNewGroup(const QString& name, u32 pinId); + static ActionPingroup* addPinsToExistingGroup(const Module* m, u32 grpId, QList pinIds, int irow = -1); + static ActionPingroup* addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int irow = -1); + static ActionPingroup* addPinsToNewGroup(const Module* m, const QString& name, QList pinIds); + static ActionPingroup* addPinToNewGroup(const Module* m, const QString& name, u32 pinId); + static ActionPingroup* removePinsFromGroup(const Module* m, QList pinIds); }; /** diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index 96475ac7079..b45ffc7e309 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -135,10 +135,8 @@ namespace hal return; pins.append(pin->get_id()); } - ActionPingroup* act = new ActionPingroup(PinAction::MovePin,pinGroup->get_id()); - act->setPinIds(pins); - act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); - act->exec(); + ActionPingroup* act = ActionPingroup::addPinsToExistingGroup(mod,pinGroup->get_id(),pins); + if (act) act->exec(); } }); } @@ -154,7 +152,7 @@ namespace hal auto* group = gNetlist->get_module_by_id(modId)->get_pin_group_by_id(itemId); if (group != nullptr) { - ActionPingroup* act = new ActionPingroup(PinAction::RenameGroup,itemId,ipd.textValue()); + ActionPingroup* act = new ActionPingroup(PinActionType::GroupRename,itemId,ipd.textValue()); act->setObject(UserActionObject(modId, UserActionObjectType::Module)); act->exec(); } @@ -164,7 +162,7 @@ namespace hal auto* pinGroup = mod->get_pin_group_by_id(itemId); if (pinGroup != nullptr) { - ActionPingroup* act = new ActionPingroup(PinAction::DeleteGroup,(u32)itemId); + ActionPingroup* act = new ActionPingroup(PinActionType::GroupDelete,(u32)itemId); act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); } @@ -192,8 +190,7 @@ namespace hal auto* pin = mod->get_pin_by_id(itemId); if (pin != nullptr) { - ActionPingroup* act = new ActionPingroup(PinAction::RenamePin,0,ipd.textValue()); - act->setPinId(pin->get_id()); + ActionPingroup* act = new ActionPingroup(PinActionType::PinRename,pin->get_id(),ipd.textValue()); act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); } @@ -213,8 +210,9 @@ namespace hal if (cbd.exec() == QDialog::Accepted) { - ActionPingroup* act = new ActionPingroup(PinAction::TypeChange,0,cbd.textValue()); - act->setPinId(pin->get_id()); + PinType ptype = enum_from_string(cbd.textValue().toStdString(),PinType::none); + + ActionPingroup* act = new ActionPingroup(PinActionType::PinTypechange,pin->get_id(),"",(int)ptype); act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); } @@ -232,15 +230,13 @@ namespace hal //can be both single(simple right-click, no real selection) and multi-selection if (sameGroup.first && mod->get_pin_group_by_id(sameGroup.second)->size() > 1) { - menu.addAction("Remove selection from group", [this, selectedPins, mod, sameGroup]() { + menu.addAction("Remove selection from group", [this, selectedPins, mod /*, sameGroup*/]() { QList pins; for (auto item : selectedPins) pins.append(mPortModel->getIdOfItem(item)); - ActionPingroup* act = new ActionPingroup(PinAction::RemovePin,mod->get_pin_group_by_id(sameGroup.second)->get_id()); - act->setPinIds(pins); - act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); - act->exec(); + ActionPingroup* act = ActionPingroup::removePinsFromGroup(mod, pins); + if (act) act->exec(); }); } @@ -276,7 +272,7 @@ namespace hal if (ipd.exec() == QDialog::Accepted && !ipd.textValue().isEmpty()) { QList pins; - auto mod = gNetlist->get_module_by_id(modId); + Module* mod = gNetlist->get_module_by_id(modId); for (auto item : selectedPins) { auto* pin = mod->get_pin_by_id(mPortModel->getIdOfItem(item)); @@ -285,10 +281,8 @@ namespace hal pins.append(pin->get_id()); } - ActionPingroup* act = new ActionPingroup(PinAction::Create,0,ipd.textValue()); - act->setPinIds(pins); - act->setObject(UserActionObject(modId, UserActionObjectType::Module)); - act->exec(); + ActionPingroup* act = ActionPingroup::addPinsToNewGroup(mod,ipd.textValue(),pins); + if (act) act->exec(); } }); } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index fe52aefa594..8c61b7482ff 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -282,6 +282,7 @@ namespace hal bool ModulePinsTreeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { + Q_UNUSED(column) Q_UNUSED(action) if(!data->formats().contains("pintreemodel/item")) return false; @@ -494,22 +495,9 @@ namespace hal if (pins.isEmpty()) return; // no pins to move auto tgtgroup = mModule->get_pin_group_by_id(getIdOfItem(onDroppedGroup)); - int ntgt = tgtgroup->size(); - if (pins.size()>1) - { - UserActionCompound* compAct = new UserActionCompound; - compAct->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); - compAct->setUseCreatedObject(); - for (u32 pinId : pins) - compAct->addAction(new ActionPingroup(pinId,ntgt++,tgtgroup->get_id())); - compAct->exec(); - } - else - { - ActionPingroup* act = new ActionPingroup(pins.at(0),ntgt,tgtgroup->get_id()); - act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); - act->exec(); - } + + ActionPingroup* act = ActionPingroup::addPinsToExistingGroup(mModule,tgtgroup->get_id(),pins); + if (act) act->exec(); // too keep the order, ActionAddItemsToObject cannot be executed with all pins, but a ComAction must be created // with many ActionAddItemsToObject that contain a single pin each -> set destroys order of pins in source pingroup @@ -525,10 +513,8 @@ namespace hal bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; - ActionPingroup* act = new ActionPingroup(PinAction::MoveGroup); + ActionPingroup* act = new ActionPingroup(PinActionType::GroupMove,getIdOfItem(droppedGroup),"",desiredIdx); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); - act->setGroupOrderNo(getIdOfItem(droppedGroup)); - act->setPinOrderNo(desiredIdx); bool ok = act->exec(); if(ok){ removeItem(droppedGroup); @@ -542,9 +528,7 @@ namespace hal mIgnoreEventsFlag = true; u32 pinId = getIdOfItem(droppedPin); - int inx = onDroppedGroup->getChildCount(); - ActionPingroup* act = new ActionPingroup(pinId,inx, getIdOfItem(onDroppedGroup)); - act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); + ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,pinId,"",getIdOfItem(onDroppedGroup)); act->exec(); auto oldParent = droppedPin->getParent(); removeItem(droppedPin); @@ -561,15 +545,20 @@ namespace hal { mIgnoreEventsFlag = true; int desiredIdx = row; + ActionPingroup* act = nullptr; if(droppedPin->getParent() == onDroppedParent) // same group { int ownRow = droppedPin->getOwnRow(); bool bottomEdge = row == onDroppedParent->getChildCount(); desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; // insert item here + act = new ActionPingroup(PinActionType::PinSetindex,getIdOfItem(droppedPin),"",desiredIdx); // TODO : start_index, descending + } + else + { + act = ActionPingroup::addPinToExistingGroup(mModule,getIdOfItem(onDroppedParent),getIdOfItem(droppedPin),desiredIdx); + if (!act) return; } - - ActionPingroup* act = new ActionPingroup(getIdOfItem(droppedPin),desiredIdx,getIdOfItem(onDroppedParent)); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); act->exec(); auto oldParent = droppedPin->getParent(); @@ -598,7 +587,7 @@ namespace hal while (mModule->get_pin_group_by_name(groupName.toStdString())) // pin group name already exists groupName = QString("%1_%2").arg(baseName).arg(cnt++); - +/* ActionPingroup* actMovePin = new ActionPingroup(pinToMove->get_id(),0,0,groupName); actMovePin->setObject(UserActionObject(mModuleId, UserActionObjectType::Module)); bool ok = actMovePin->exec(); @@ -624,6 +613,7 @@ namespace hal removeItem(droppedPin); insertItem(droppedPin, pinGroupItem, 0); } + */ mIgnoreEventsFlag = false; } diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 0cf9a00af32..86c711b1878 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -19,7 +19,6 @@ namespace hal return -1; } - QString PinActionType::toString(PinActionType::Type tp) { QMetaEnum me = QMetaEnum::fromType(); @@ -45,7 +44,7 @@ namespace hal bool PinActionType::useExistingPin(PinActionType::Type tp) { - static const QSet types = {PinAddgroup, PinRename, PinTypechange, PinDirection, PinSetindex}; + static const QSet types = {PinAsignGroup, PinRename, PinTypechange, PinDirection, PinSetindex}; return types.contains(tp); } @@ -64,11 +63,15 @@ namespace hal return ActionPingroupFactory::sFactory->tagname(); } - ActionPingroup::ActionPingroup(PinActionType::Type tp, u32 id, const QString &name, int value) + ActionPingroup::ActionPingroup(PinActionType::Type tp, int id, const QString &name, int value) { mPinActions.append(AtomicAction(tp, id, name, value)); } + ActionPingroup::ActionPingroup(const QList& aaList) + : mPinActions(aaList) + {;} + void ActionPingroup::addToHash(QCryptographicHash &cryptoHash) const { for (const AtomicAction& aa : mPinActions) @@ -117,19 +120,126 @@ namespace hal mPinActions.append(AtomicAction(tp,id,name,val)); } } + PinGroup* ActionPingroup::getGroup(ModulePin* pin) const + { + return pin->get_group().first; + } + + PinGroup* ActionPingroup::getGroup(int grpId) const + { + PinGroup* pgroup = mPinGroups.value(grpId); + if (pgroup) return pgroup; + if (!mParentModule || grpId<=0) return nullptr; + return mParentModule->get_pin_group_by_id(grpId); + } + + void ActionPingroup::addUndoAction(PinActionType::Type tp, int id, const QString& name, int value) + { + ActionPingroup* undo = nullptr; + if (mUndoAction) + { + undo = static_cast(mUndoAction); + undo->mPinActions.append(AtomicAction(tp,id,name,value)); + } + else + { + undo = new ActionPingroup(tp,id,name,value); + undo->setObject(object()); + } + mUndoAction = undo; + } + + + void ActionPingroup::prepareUndoAction() + { + QHash*,int> remainingPins; + for (const AtomicAction& aa : mPinActions) + { + if (aa.mType != PinActionType::PinAsignGroup) + continue; + ModulePin* pin = mParentModule->get_pin_by_id(aa.mId); + PinGroup* pgroup = pin->get_group().first; + if (remainingPins.contains(pgroup)) + remainingPins[pgroup]--; + else + remainingPins[pgroup] = pgroup->size()-1; + } + + // for groups that will be deleted after pin assign a create action is needed in undo + for (auto it = remainingPins.begin(); it != remainingPins.end(); ++it) + { + if (it.value() > 0) continue; + GroupRestore gr(mParentModule,it.key()); + mGroupRestore.insert(gr.mRow,gr); + } + } + + void ActionPingroup::finalizeUndoAction() + { + QList restoreActions; + for (auto it = mGroupRestore.begin(); it != mGroupRestore.end(); ++it) + { + const GroupRestore& gr = it.value(); + restoreActions.append(AtomicAction(PinActionType::GroupCreate,gr.mId,gr.mName,gr.mStartIndex)); + restoreActions.append(AtomicAction(PinActionType::GroupMove,gr.mId,"",gr.mRow)); + if (gr.mType != PinType::none) + restoreActions.append(AtomicAction(PinActionType::GroupTypechange,gr.mId,"",(int)gr.mType)); + if (gr.mDirection != PinDirection::none) + restoreActions.append(AtomicAction(PinActionType::GroupDirection,gr.mId,"",(int)gr.mDirection)); + } + if (!restoreActions.isEmpty()) + { + if (mUndoAction) + { + ActionPingroup* act = static_cast(mUndoAction); + restoreActions += act->mPinActions; + act->mPinActions = restoreActions; + } + else + { + mUndoAction = new ActionPingroup(restoreActions); + } + } + + for (u32 grpId : mGroupToRemove) + { + if (mUndoAction) + { + ActionPingroup* act = static_cast(mUndoAction); + act->mPinActions.append(AtomicAction(PinActionType::GroupDelete,grpId)); + } + else + mUndoAction = new ActionPingroup(PinActionType::GroupDelete,grpId); + } + + if (mUndoAction) mUndoAction->setObject(object()); + } + + int ActionPingroup::pinGroupRow(Module *m, PinGroup* pgroup) + { + int inx = 0; + for (PinGroup* testgroup : m->get_pin_groups()) + { + if (testgroup == pgroup) return inx; + ++inx; + } + return -1; + } bool ActionPingroup::exec() { + mPinGroups.clear(); + mGroupRestore.clear(); + mPinsMoved.clear(); + mGroupToRemove.clear(); if (mObject.type() != UserActionObjectType::Module) return false; - Module* parentModule = gNetlist->get_module_by_id(mObject.id()); - if (!parentModule) + mParentModule = gNetlist->get_module_by_id(mObject.id()); + if (!mParentModule) return false; - ActionPingroup* undo = nullptr; - - QHash*> pgroups; + prepareUndoAction(); // create pingroups in case we are going to delete some while assigning for (const AtomicAction& aa : mPinActions) { @@ -138,12 +248,12 @@ namespace hal if (PinActionType::useExistingGroup(aa.mType)) { - auto it = pgroups.find(aa.mId); - if (it == pgroups.end()) + auto it = mPinGroups.find(aa.mId); + if (it == mPinGroups.end()) { - pgroup = parentModule->get_pin_group_by_id(aa.mId); + pgroup = mParentModule->get_pin_group_by_id(aa.mId); if (!pgroup) return false; - pgroups.insert(aa.mId,pgroup); + mPinGroups.insert(aa.mId,pgroup); } else pgroup = it.value(); @@ -151,7 +261,7 @@ namespace hal if (PinActionType::useExistingPin(aa.mType)) { - pin = parentModule->get_pin_by_id(aa.mId); + pin = mParentModule->get_pin_by_id(aa.mId); } switch (aa.mType) @@ -167,232 +277,184 @@ namespace hal } if (aa.mId > 0) { - if (auto res = parentModule->create_pin_group(aa.mId, aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) - pgroups.insert(aa.mId,res.get()); + if (auto res = mParentModule->create_pin_group(aa.mId, aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) + pgroup = res.get(); else return false; } else { - if (auto res = parentModule->create_pin_group(aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) - pgroups.insert(aa.mId,res.get()); + if (auto res = mParentModule->create_pin_group(aa.mName.toStdString(), {}, PinDirection::none, PinType::none,ascending,startIndex); res.is_ok()) + pgroup = res.get(); else return false; } + if (pgroup) + { + mPinGroups[aa.mId] = pgroup; + mGroupToRemove.insert(pgroup->get_id()); + } break; } case PinActionType::GroupDelete: - if (parentModule->delete_pin_group(pgroup).is_error()) + { + int v = pgroup->get_start_index(); + if (!pgroup->is_ascending()) v = -v; + u32 id = pgroup->get_id(); + int ptype = (int) pgroup->get_type(); + int pdir = (int) pgroup->get_direction(); + QString name = QString::fromStdString(pgroup->get_name()); + if (mParentModule->delete_pin_group(pgroup).is_error()) return false; + addUndoAction(PinActionType::GroupCreate,id,name,v); + addUndoAction(PinActionType::GroupTypechange,id,"",ptype); + addUndoAction(PinActionType::GroupDirection,id,"",pdir); break; + } case PinActionType::GroupMove: - if (parentModule->move_pin_group(pgroup,aa.mValue).is_error()) + { + int inx = pinGroupRow(mParentModule,pgroup); + if (inx < 0) return false; + addUndoAction(PinActionType::GroupMove,pgroup->get_id(),"",inx); + if (mParentModule->move_pin_group(pgroup,aa.mValue).is_error()) return false; break; + } case PinActionType::GroupRename: - if (!parentModule->set_pin_group_name(pgroup,aa.mName.toStdString())) + addUndoAction(PinActionType::GroupRename,pgroup->get_id(),QString::fromStdString(pgroup->get_name())); + if (!mParentModule->set_pin_group_name(pgroup,aa.mName.toStdString())) return false; break; case PinActionType::GroupTypechange: - if (!parentModule->set_pin_group_type(pgroup, (PinType) aa.mValue)) + addUndoAction(PinActionType::GroupTypechange,pgroup->get_id(),"",(int)pgroup->get_type()); + if (!mParentModule->set_pin_group_type(pgroup, (PinType) aa.mValue)) return false; break; case PinActionType::GroupDirection: - if (!parentModule->set_pin_group_direction(pgroup, (PinDirection) aa.mValue)) + addUndoAction(PinActionType::GroupDirection,pgroup->get_id(),"",(int)pgroup->get_direction()); + if (!mParentModule->set_pin_group_direction(pgroup, (PinDirection) aa.mValue)) return false; break; - case PinActionType::PinAddgroup: + case PinActionType::PinAsignGroup: + addUndoAction(PinActionType::PinAsignGroup,aa.mId,"",pin->get_group().first->get_id()); + addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); + mPinsMoved.insert(aa.mId); + pgroup = getGroup(aa.mValue); + if (!pgroup) return false; + if (mParentModule->assign_pin_to_group(pgroup,pin).is_error()) + return false; break; case PinActionType::PinRename: - if (!parentModule->set_pin_name(pin, aa.mName.toStdString())) + addUndoAction(PinActionType::PinRename,aa.mId, QString::fromStdString(pin->get_name())); + if (!mParentModule->set_pin_name(pin, aa.mName.toStdString())) return false; break; case PinActionType::PinTypechange: - if (!parentModule->set_pin_type(pin, (PinType) aa.mValue)) + addUndoAction(PinActionType::PinTypechange,aa.mId,"",(int)pin->get_type()); + if (!mParentModule->set_pin_type(pin, (PinType) aa.mValue)) return false; break; case PinActionType::PinSetindex: + if (!mPinsMoved.contains(aa.mId)) + addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); + pgroup = pin->get_group().first; + if (!mParentModule->move_pin_within_group(pgroup,pin,aa.mValue).is_ok()) + return false; break; default: break; } } - /* - if (mPinActions.size()==1 && - (mPinActions.at(0) == PinAction::MovePin || mPinActions.at(0) == PinAction::RemovePin)) + finalizeUndoAction(); + + return UserAction::exec(); + } + + ActionPingroup* ActionPingroup::addPinsToExistingGroup(const Module *m, u32 grpId, QList pinIds, int irow) + { + ActionPingroup* retval = nullptr; + for (u32 pinId : pinIds) { - auto* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); - if (!pinToMove) return false; - auto* srcgrp = pinToMove->get_group().first; - if (!srcgrp) return false; - int currentIndex = pinToMove->get_group().second; - mSourceGroupId = srcgrp->get_id(); - undo = new ActionPingroup(pinToMove->get_id(), currentIndex, mSourceGroupId, QString::fromStdString(srcgrp->get_name())); - if (srcgrp->get_pins().size() == 1) mPinActions.append(PinAction::DeleteGroup); - if (mPinActions.at(0) == PinAction::MovePin) - { - if (mTargetGroupId) - { - auto* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - if (!tgtgrp) - tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); - if (!tgtgrp) - mTargetGroupId = 0; - } - else - { - auto* tgtgrp = parentModule->get_pin_group_by_name(mName.toStdString()); - if (tgtgrp) - mTargetGroupId = tgtgrp->get_id(); - } - if (!mTargetGroupId) - { - // target group does not exist, create it - if (mName.isEmpty()) - mName = QString::fromStdString(pinToMove->get_name()); - mPinActions.replace(0,PinAction::Create); // create will place pins in new group - } - } + if (retval) + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",grpId)); + else + retval = new ActionPingroup(PinActionType::PinAsignGroup,pinId,"",grpId); + if (irow >= 0) + retval->mPinActions.append(AtomicAction(PinActionType::PinSetindex,pinId,"",irow++)); } + retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); + return retval; + } + ActionPingroup* ActionPingroup::addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int irow) + { + QList pinIds; + pinIds << pinId; + return addPinsToExistingGroup(m,grpId,pinIds,irow); + } - for (PinAction::Type act : mPinActions) + ActionPingroup* ActionPingroup::addPinsToNewGroup(const Module* m, const QString& name, QList pinIds) + { + static int vid = -9; + ActionPingroup* retval = new ActionPingroup(PinActionType::GroupCreate,vid,name); + if (!pinIds.isEmpty()) { - switch (act) - { - case PinAction::None: - break; - case PinAction::Create: - { - auto res = parentModule->create_pin_group(mName.toStdString()); - if(res.is_error()) - return false; - mTargetGroupId = res.get()->get_id(); - if (!mPinIds.isEmpty()) - { - auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - for (u32 pinId : mPinIds) - { - auto pin = parentModule->get_pin_by_id(pinId); - if (pin) pgrp->assign_pin(pin).is_ok(); - } - } - if (mGroupOrderNo >= 0) - parentModule->move_pin_group(res.get(),mGroupOrderNo).is_ok(); - if (!undo) - undo = new ActionPingroup(PinAction::DeleteGroup, mTargetGroupId); - break; - } - case PinAction::DeleteGroup: + ModulePin* pin = m->get_pin_by_id(pinIds.first()); + if (pin) { - auto* pgrp = parentModule->get_pin_group_by_id(mSourceGroupId); - if (!pgrp) return false; - int currentIndex = pinGroupIndex(parentModule,pgrp); - QList pins; - for (const auto& pin : pgrp->get_pins()) - { - pins.append(pin->get_id()); - } - if (parentModule->delete_pin_group(pgrp).is_error()) return false; - if (!undo) - { - undo = new ActionPingroup(PinAction::Create, pgrp->get_id(), QString::fromStdString(pgrp->get_name())); - undo->setPinIds(pins); - undo->setGroupOrderNo(currentIndex); - } - break; + retval->mPinActions.append(AtomicAction(PinActionType::GroupDirection,vid,"",(int)pin->get_direction())); + retval->mPinActions.append(AtomicAction(PinActionType::GroupTypechange,vid,"",(int)pin->get_type())); } - case PinAction::MovePin: - { - PinGroup* tgtgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - ModulePin* pinToMove = parentModule->get_pin_by_id(mPinIds.at(0)); - if (!tgtgrp || !pinToMove) return false; - auto* srcgrp = pinToMove->get_group().first; + } + for (u32 pinId : pinIds) + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",vid)); + retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); + return retval; + } - if (srcgrp != tgtgrp) - { - if (tgtgrp->assign_pin(pinToMove).is_ok()) return false; - } - tgtgrp->move_pin(pinToMove,mPinOrderNo).is_ok(); - break; - } - case PinAction::RemovePin: - { - PinGroup* srcgrp = parentModule->get_pin_group_by_id(mSourceGroupId); - ModulePin* pinToRemove = parentModule->get_pin_by_id(mPinIds.at(0)); - if (!srcgrp || !pinToRemove) return false; - srcgrp->remove_pin(pinToRemove).is_ok(); - break; - } - case PinAction::MoveGroup: - { - PinGroup* srcgrp = nullptr; - int currentIndex = 0; - for (PinGroup* pgrp : parentModule->get_pin_groups()) - { - if (pgrp->get_id() == mSourceGroupId) - { - srcgrp = pgrp; - break; - } - ++ currentIndex; - } - if (!srcgrp) return false; - if (parentModule->move_pin_group(srcgrp,mPinOrderNo).is_error()) return false; - if (!undo) - { - undo = new ActionPingroup(PinAction::MoveGroup, mSourceGroupId); - undo->setPinOrderNo(currentIndex); - } - } - case PinAction::RenamePin: - { - if (mPinIds.isEmpty()) return false; - auto* pin = parentModule->get_pin_by_id(mPinIds.first()); - if (!pin) return false; - QString oldName = QString::fromStdString(pin->get_name()); - if (!parentModule->set_pin_name(pin,mName.toStdString())) return false; // RenamePin - if (!undo) - { - undo = new ActionPingroup(PinAction::RenamePin, pin->get_id(), oldName); - } - } - case PinAction::RenameGroup: - { - auto* pgrp = parentModule->get_pin_group_by_id(mTargetGroupId); - if (!pgrp) return false; - QString oldName = QString::fromStdString(pgrp->get_name()); - if (!parentModule->set_pin_group_name(pgrp,mName.toStdString())) return false; // RenameGroup - if (!undo) - { - undo = new ActionPingroup(PinAction::RenameGroup, pgrp->get_id(), oldName); - } - break; - } - case PinAction::TypeChange: - { - if (mPinIds.isEmpty()) return false; - auto* pin = parentModule->get_pin_by_id(mPinIds.first()); - if (!pin) return false; - PinType ptype = enum_from_string(mName.toStdString(),PinType::none); - PinType oldPtype = pin->get_type(); - if (!parentModule->set_pin_type(pin,ptype)) return false; // TypeChange - if (!undo) - { - undo = new ActionPingroup(PinAction::TypeChange, 0, QString::fromStdString(enum_to_string(oldPtype))); - undo->setPinId(pin->get_id()); - } - break; - } - default: - break; - } + ActionPingroup* ActionPingroup::addPinToNewGroup(const Module *m, const QString& name, u32 pinId) + { + QList pinIds; + pinIds << pinId; + return addPinsToNewGroup(m,name,pinIds); + } + + ActionPingroup* ActionPingroup::removePinsFromGroup(const Module* m, QList pinIds) + { + ActionPingroup* retval = nullptr; + QSet existingGroupNames; + for (PinGroup* pgroup : m->get_pin_groups()) + existingGroupNames.insert(QString::fromStdString(pgroup->get_name())); + int vid = -1; + QString basename; + for (u32 pinId : pinIds) + { + ModulePin* pin = m->get_pin_by_id(pinId); + if (!pin) return nullptr; + int count = 2; + QString name = basename = QString::fromStdString(pin->get_name()); + while (existingGroupNames.contains(name)) + name = QString("%1_%2").arg(basename).arg(count++); + if (retval) + retval->mPinActions.append(AtomicAction(PinActionType::GroupCreate,vid,name)); + else + retval = new ActionPingroup(PinActionType::GroupCreate,vid,name); + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",vid)); + --vid; } - */ - if (undo) - undo->setObject(object()); - mUndoAction = undo; - return UserAction::exec(); + retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); + return retval; + } + + ActionPingroup::GroupRestore::GroupRestore(Module* m, PinGroup* pgroup) + : mId(pgroup->get_id()), + mName(QString::fromStdString(pgroup->get_name())), + mRow(pinGroupRow(m,pgroup)), + mStartIndex(pgroup->get_start_index()), + mDirection(pgroup->get_direction()), + mType(pgroup->get_type()) + { + if (!pgroup->is_ascending()) mStartIndex = -mStartIndex; } } From a21ff3d68f2d881703af8f3ed3c504faa4f12ceb Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 2 Aug 2023 15:34:16 +0200 Subject: [PATCH 09/40] replace 'AdditionalData' from BaseTreeItem by more specific data fields (work in progress, does not compile yet) --- .../gui/basic_tree_model/base_tree_item.h | 29 +---- .../gate_details_widget/gate_pin_tree.h | 6 +- .../gate_details_widget/pin_tree_model.h | 49 ++++---- .../module_details_widget/module_tree_model.h | 32 +++-- .../module_details_widget/port_tree_model.h | 26 ++-- .../src/basic_tree_model/base_tree_item.cpp | 10 -- .../gate_details_widget/gate_pin_tree.cpp | 33 ++--- .../gate_details_widget/pin_tree_model.cpp | 32 ++--- .../module_elements_tree.cpp | 24 ++-- .../module_ports_tree.cpp | 12 +- .../module_tree_model.cpp | 116 ++++++++---------- .../module_details_widget/port_tree_model.cpp | 15 ++- 12 files changed, 161 insertions(+), 223 deletions(-) diff --git a/plugins/gui/include/gui/basic_tree_model/base_tree_item.h b/plugins/gui/include/gui/basic_tree_model/base_tree_item.h index 68f5ea461a9..8e05c2c63b6 100644 --- a/plugins/gui/include/gui/basic_tree_model/base_tree_item.h +++ b/plugins/gui/include/gui/basic_tree_model/base_tree_item.h @@ -35,15 +35,10 @@ namespace hal /** * @brief (Future) Base class for all tree models related to the details widget. * - * This class functions as a generic data container for all tree models. For this - * purpose, it uses QVariants as its main type of storage for its columns. (Note: Perhaps add - * additional data in form of a list or map (split it from "normal" displayed column data) + * This class functions as a generic data container for all tree models. */ class BaseTreeItem { - // maybe add enum type for all possible scenarios? or use additional data with key to access type - // and handle type handling in model...e.g.: item->getAddData("type")(structure, more generalization,...) - private: /** * Copy constructor. Copies the item's data, not the parent/children. @@ -194,31 +189,9 @@ namespace hal */ virtual int getOwnRow(); - /** - * Stores additional data. Can be accessed by getAdditionalData. - * (For example, a menu or color) - * - * @param key - The key to store the data under. - * @param data - The actual data to store. - */ - virtual void setAdditionalData(QString key, QVariant data); - - /** - * Retrieve the data stored under the given key. - * - * @param key - The key for the requested data. - * @return The data if something was stored under the key, empty QVariant otherwise. - */ - virtual QVariant getAdditionalData(QString key) const; - private: BaseTreeItem* mParent; QList mChildren; - - // experimental, additional data (for anything) - QMap mAdditionalData; - //QList mAdditionalData; - }; /** diff --git a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/gate_pin_tree.h b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/gate_pin_tree.h index 1d23ff76df1..746eb58931e 100644 --- a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/gate_pin_tree.h +++ b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/gate_pin_tree.h @@ -33,7 +33,7 @@ namespace hal { class GatePinsTreeModel; class Gate; - class BaseTreeItem; + class PinTreeItem; class GraphNavigationWidget; /** @@ -98,8 +98,8 @@ namespace hal bool mClearSelection; //helper functions - void buildPythonMenuForPin(QMenu &menu, BaseTreeItem* clickedPinItem); - void buildPythonMenuForPinGroup(QMenu &menu, BaseTreeItem* clickedPinIGrouptem); + void buildPythonMenuForPin(QMenu &menu, PinTreeItem* clickedPinItem); + void buildPythonMenuForPinGroup(QMenu &menu, PinTreeItem* clickedPinIGrouptem); void addSourceOurDestinationToSelection(int netId, bool isInputPin); void handleNavigationCloseRequested(); void handleNavigationJumpRequested(const Node& origin, const u32 via_net, const QSet& to_gates, const QSet& to_modules); diff --git a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h index 142601fa32a..9a938078830 100644 --- a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h @@ -26,8 +26,10 @@ #pragma once //#include "gui/new_selection_details_widget/models/base_tree_model.h" +#include "hal_core/defines.h" #include "gui/basic_tree_model/base_tree_model.h" #include +#include namespace hal { @@ -36,8 +38,12 @@ namespace hal class PinTreeItem : public BaseTreeItem { + public: + enum Type {None, Pin, Group}; private: + Type mType; + QList mNetIds; std::string mPinName; QString mPinDirection; QString mPinType; @@ -51,6 +57,24 @@ namespace hal void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; + void setType(Type tp) { mType = tp; } + + /** + * Get the type (enum) of a given item. + * + * @return The item's type. + */ + Type type() const { return mType; } + void setNetIds(const QList& nids) { mNetIds = nids; } + + /** + * Get the connected nets for a given treeitem (represents a pin). If the + * item is grouping type or the pin has no connected net, an empty list + * is returned. In case of an inout pin, even multiple connected nets are possible. + * + * @return A list of net ids. + */ + QList netIds() const { return mNetIds; } }; /** @@ -63,9 +87,6 @@ class GatePinsTreeModel : public BaseTreeModel public: - //metatype declaration at the end of file - enum class itemType {grouping = 0, pin = 1}; - /** * The constructor. * @@ -98,24 +119,6 @@ class GatePinsTreeModel : public BaseTreeModel */ int getCurrentGateID(); - /** - * Get the connected nets for a given treeitem (represents a pin). If the - * item is grouping type or the pin has no connected net, an empty list - * is returned. In case of an inout pin, even multiple connected nets are possible. - * - * @param item - The treeitem from which to get the connected nets. - * @return A list of net ids. - */ - QList getNetIDsOfTreeItem(BaseTreeItem* item); - - /** - * Get the type (enum) of a given item. - * - * @param item - The item for which the type is requested. - * @return The item's type. - */ - itemType getTypeOfItem(BaseTreeItem* item); - /** * Get the number of displayed pins (the number of pins of all types). * @@ -136,10 +139,8 @@ class GatePinsTreeModel : public BaseTreeModel private: int mGateId; - QMap mPinGroupingToTreeItem; + QMap mPinGroupToTreeItem; }; } - -Q_DECLARE_METATYPE(hal::GatePinsTreeModel::itemType) diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/module_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/module_tree_model.h index bf2c7d7ee29..a8a139e1b24 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/module_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/module_tree_model.h @@ -39,19 +39,30 @@ namespace hal class ModuleTreeitem : public BaseTreeItem { + public: + enum ItemType { None, Module, Gate}; private: - std::string mType; + ItemType mItemType; int mId; - std::string mName; + QString mName; + QString mNodeType; public: - ModuleTreeitem(const std::string& name, int id, std::string tp); + ModuleTreeitem(ItemType itp, int id, const QString& name, const QString& ntp); QVariant getData(int column) const override; void setData(QList data) override; void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; + + /** + * Get the type (enum) of a given item. + * + * @param item - The item for which the type is requested. + * @return The item's type. + */ + ItemType itemType() const { return mItemType; } }; class ModuleTreeModel : public BaseTreeModel @@ -59,9 +70,6 @@ namespace hal Q_OBJECT public: - //metatype declaration at the end of file - enum class itemType {module = 0, gate = 1}; - ModuleTreeModel(QObject* parent = nullptr); ~ModuleTreeModel(); @@ -81,14 +89,6 @@ namespace hal QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; ///@} - /** - * Get the type (enum) of a given item. - * - * @param item - The item for which the type is requested. - * @return The item's type. - */ - itemType getTypeOfItem(BaseTreeItem* item) const; - /** * Disconnects all events from the model. Can be called to increase performance when * no module is displayed. @@ -142,7 +142,7 @@ namespace hal * @param item - The requested item. * @return A module, net, or gate icon depending on the item's type. */ - QIcon getIconFromItem(BaseTreeItem* item) const; + QIcon getIconFromItem(ModuleTreeitem* item) const; void clearOwnStructures(); @@ -165,5 +165,3 @@ namespace hal }; } - -Q_DECLARE_METATYPE(hal::ModuleTreeModel::itemType) diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index e5fe4d1e6c0..17080bafb79 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -38,21 +38,29 @@ namespace hal class PortTreeItem : public BaseTreeItem { + public: + enum Type {None, Pin, Group}; private: + Type mType; + u32 mId; QString mPinName; QString mPinDirection; QString mPinType; QString mNetName; public: - PortTreeItem(QString pinName, QString pinDirection, QString pinType, QString netName); - PortTreeItem(); + PortTreeItem(Type tp, QString pinName, QString pinDirection, QString pinType, QString netName); + PortTreeItem() : mType(None), mId(0) {;} QVariant getData(int column) const override; void setData(QList data) override; void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; + setType(Type tp) { mType = tp; } + Type type() const { return mType; } + void setId(u32 id_) { mId = id_; } + u32 id() const { return mId; } }; /** @@ -63,10 +71,6 @@ namespace hal Q_OBJECT public: - //metatype declaration at the end of file (portSingleBit and portMultiBit are deprecated) - //important now are pins and groups - enum class itemType{portSingleBit = 0, portMultiBit = 1, pin = 2, group = 3}; - /** * The constructor. * @@ -117,14 +121,6 @@ namespace hal */ int getRepresentedModuleId(); - /** - * Get the type (enum) of a given item. - * - * @param item - The item for which the type is requested. - * @return The item's type. - */ - itemType getTypeOfItem(PortTreeItem* item) const; - /** * Returns the pin-id if the item represents a pin or the pingroup-id * if the item represents a pingroup. @@ -179,5 +175,3 @@ namespace hal void dndPinBetweenGroup(PortTreeItem* droppedPin, int row); }; } - -Q_DECLARE_METATYPE(hal::ModulePinsTreeModel::itemType) diff --git a/plugins/gui/src/basic_tree_model/base_tree_item.cpp b/plugins/gui/src/basic_tree_model/base_tree_item.cpp index c0d0ce9e539..5bf967777ea 100644 --- a/plugins/gui/src/basic_tree_model/base_tree_item.cpp +++ b/plugins/gui/src/basic_tree_model/base_tree_item.cpp @@ -99,16 +99,6 @@ namespace hal return mParent->getRowForChild(this); } - void BaseTreeItem::setAdditionalData(QString key, QVariant data) - { - mAdditionalData.insert(key, data); - } - - QVariant BaseTreeItem::getAdditionalData(QString key) const - { - return mAdditionalData.value(key, QVariant()); - } - QVariant RootTreeItem::getData(int column) const { if (column <= mHeaderLabels.size()) diff --git a/plugins/gui/src/selection_details_widget/gate_details_widget/gate_pin_tree.cpp b/plugins/gui/src/selection_details_widget/gate_details_widget/gate_pin_tree.cpp index f1ed3a05928..754770955ef 100644 --- a/plugins/gui/src/selection_details_widget/gate_details_widget/gate_pin_tree.cpp +++ b/plugins/gui/src/selection_details_widget/gate_details_widget/gate_pin_tree.cpp @@ -69,11 +69,11 @@ namespace hal if(!idx.isValid()) return; - auto clickedItem = mPinModel->getItemFromIndex(idx); - if(mPinModel->getTypeOfItem(clickedItem) != GatePinsTreeModel::itemType::pin) + PinTreeItem* clickedItem = dynamic_cast(mPinModel->getItemFromIndex(idx)); + if(!clickedItem || clickedItem->type() != PinTreeItem::Pin) return; - auto netId = mPinModel->getNetIDsOfTreeItem(clickedItem).front(); + auto netId = clickedItem->netIds().front(); auto clickedNet = gNetlist->get_net_by_id(netId); if(clickedNet) { @@ -96,9 +96,8 @@ namespace hal if(!idx.isValid()) return; - BaseTreeItem* clickedItem = mPinModel->getItemFromIndex(idx); + PinTreeItem* clickedItem = dynamic_cast(mPinModel->getItemFromIndex(idx)); QMenu menu; - GatePinsTreeModel::itemType type = mPinModel->getTypeOfItem(clickedItem); bool isMiscSectionSet = false;//so that the misc-section is not set multiple times //PLAINTEXT: NAME, DIRECTION, TYPE @@ -118,9 +117,9 @@ namespace hal }); //Check if jump to source or destination is possible - if(type == GatePinsTreeModel::itemType::pin && mPinModel->getNetIDsOfTreeItem(clickedItem).size()==1) + if(clickedItem->type() == PinTreeItem::Pin && clickedItem->netIds().size()==1) { - auto netId = mPinModel->getNetIDsOfTreeItem(clickedItem).front(); + auto netId = clickedItem->netIds().front(); auto clickedNet = gNetlist->get_net_by_id(netId); if(clickedNet) { @@ -156,15 +155,19 @@ namespace hal } //Add nets to selection if possible - QList netIds; - if(type == GatePinsTreeModel::itemType::pin) + QList netIds; + if(clickedItem->type() == PinTreeItem::Pin) { - netIds = mPinModel->getNetIDsOfTreeItem(clickedItem); + netIds = clickedItem->netIds(); } else { for(auto childItem : clickedItem->getChildren()) - netIds.append(mPinModel->getNetIDsOfTreeItem(childItem)); + { + PinTreeItem* pti = dynamic_cast(childItem); + if (pti) + netIds.append(pti->netIds()); + } } if(netIds.size() != 0) { @@ -191,7 +194,7 @@ namespace hal menu.addSection("Python"); - if(type == GatePinsTreeModel::itemType::pin) + if(clickedItem->type() == PinTreeItem::Pin) buildPythonMenuForPin(menu, clickedItem); else buildPythonMenuForPinGroup(menu, clickedItem); @@ -201,10 +204,10 @@ namespace hal } - void GatePinTree::buildPythonMenuForPin(QMenu &menu, BaseTreeItem *clickedPinItem) + void GatePinTree::buildPythonMenuForPin(QMenu &menu, PinTreeItem *clickedPinItem) { // 1.) NET-OBJECT - QList netIdsOfItem = mPinModel->getNetIDsOfTreeItem(clickedPinItem); + QList netIdsOfItem = clickedPinItem->netIds(); QString pythonCommandNetIds, pythonCommandName; if(netIdsOfItem.size() == 1) @@ -243,7 +246,7 @@ namespace hal } - void GatePinTree::buildPythonMenuForPinGroup(QMenu &menu, BaseTreeItem *clickedPinIGrouptem) + void GatePinTree::buildPythonMenuForPinGroup(QMenu &menu, PinTreeItem *clickedPinIGrouptem) { // 1. PYTHON LIST OF PIN GROUPS QString pythonList = "["; diff --git a/plugins/gui/src/selection_details_widget/gate_details_widget/pin_tree_model.cpp b/plugins/gui/src/selection_details_widget/gate_details_widget/pin_tree_model.cpp index f9b7ea9703f..1890580ec9f 100644 --- a/plugins/gui/src/selection_details_widget/gate_details_widget/pin_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/gate_details_widget/pin_tree_model.cpp @@ -101,7 +101,7 @@ namespace hal void GatePinsTreeModel::clear() { BaseTreeModel::clear(); - mPinGroupingToTreeItem.clear(); + mPinGroupToTreeItem.clear(); mGateId = -1; } @@ -123,7 +123,7 @@ namespace hal //evaluate netname (in case of inout multiple possible nets), method depends on pindirection (kind of ugly switch) QString netName = ""; - QList netIDs; + QList netIDs; switch (direction) { case PinDirection::input: @@ -161,20 +161,20 @@ namespace hal } pinItem->setData(QList() << QString::fromStdString(pin->get_name()) << pinDirection << pinType << netName); - pinItem->setAdditionalData(keyType, QVariant::fromValue(itemType::pin)); - pinItem->setAdditionalData(keyRepresentedNetsID, QVariant::fromValue(netIDs)); + pinItem->setType(PinTreeItem::Pin); + pinItem->setNetIds(netIDs); if (!grouping.empty()) { - BaseTreeItem* groupingsItem = mPinGroupingToTreeItem.value(grouping, nullptr); //since its a map, its okay - if (!groupingsItem) + PinTreeItem* pingroupItem = dynamic_cast(mPinGroupToTreeItem.value(grouping, nullptr)); //since its a map, its okay + if (!pingroupItem) { //assume all items in the same grouping habe the same direction and type, so the grouping-item has also these types - groupingsItem = new PinTreeItem(grouping, pinDirection, pinType, ""); - groupingsItem->setAdditionalData(keyType, QVariant::fromValue(itemType::grouping)); - mRootItem->appendChild(groupingsItem); - mPinGroupingToTreeItem.insert(grouping, groupingsItem); + pingroupItem = new PinTreeItem(grouping, pinDirection, pinType, ""); + pingroupItem->setType(PinTreeItem::Group); + mRootItem->appendChild(pingroupItem); + mPinGroupToTreeItem.insert(grouping, pingroupItem); } - groupingsItem->appendChild(pinItem); + pingroupItem->appendChild(pinItem); } else mRootItem->appendChild(pinItem); @@ -187,16 +187,6 @@ namespace hal return mGateId; } - QList GatePinsTreeModel::getNetIDsOfTreeItem(BaseTreeItem* item) - { - return item->getAdditionalData(keyRepresentedNetsID).value>(); - } - - GatePinsTreeModel::itemType GatePinsTreeModel::getTypeOfItem(BaseTreeItem* item) - { - return item->getAdditionalData(keyType).value(); - } - int GatePinsTreeModel::getNumberOfDisplayedPins() { Gate* g = gNetlist->get_gate_by_id(mGateId); diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_elements_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_elements_tree.cpp index 208a6c1d362..30e3cf47006 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_elements_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_elements_tree.cpp @@ -61,9 +61,9 @@ namespace hal if(!clickedIndex.isValid()) return; - BaseTreeItem* clickedItem = mModel->getItemFromIndex(clickedIndex); + ModuleTreeitem* clickedItem = dynamic_cast(mModel->getItemFromIndex(clickedIndex)); int id = clickedItem->getData(ModuleTreeModel::sIdColumn).toInt(); - ModuleTreeModel::itemType type = mModel->getTypeOfItem(clickedItem); + ModuleTreeitem::ItemType type = clickedItem->itemType(); QMenu menu; //menu.addSection("here comes the plaintext"); @@ -97,8 +97,8 @@ namespace hal gSelectionRelay->clear(); switch(type) { - case ModuleTreeModel::itemType::module: gSelectionRelay->addModule(id); break; - case ModuleTreeModel::itemType::gate: gSelectionRelay->addGate(id); break; + case ModuleTreeitem::Module: gSelectionRelay->addModule(id); break; + case ModuleTreeitem::Gate: gSelectionRelay->addGate(id); break; } gSelectionRelay->relaySelectionChanged(this); } @@ -109,8 +109,8 @@ namespace hal { switch(type) { - case ModuleTreeModel::itemType::module: gSelectionRelay->addModule(id); break; - case ModuleTreeModel::itemType::gate: gSelectionRelay->addGate(id); break; + case ModuleTreeitem::Module: gSelectionRelay->addModule(id); break; + case ModuleTreeitem::Gate: gSelectionRelay->addGate(id); break; } gSelectionRelay->relaySelectionChanged(this); } @@ -122,8 +122,8 @@ namespace hal Node nd; switch(type) { - case ModuleTreeModel::itemType::module: nd = Node(id, Node::Module); break; - case ModuleTreeModel::itemType::gate: nd = Node(id, Node::Gate); break; + case ModuleTreeitem::Module: nd = Node(id, Node::Module); break; + case ModuleTreeitem::Gate: nd = Node(id, Node::Gate); break; } SelectionTreeView::isolateInNewViewAction(nd); } @@ -134,16 +134,16 @@ namespace hal { switch(type) { - case ModuleTreeModel::itemType::module: gContentManager->getGraphTabWidget()->handleModuleFocus(id); break; - case ModuleTreeModel::itemType::gate: gContentManager->getGraphTabWidget()->handleGateFocus(id); break; + case ModuleTreeitem::Module: gContentManager->getGraphTabWidget()->handleModuleFocus(id); break; + case ModuleTreeitem::Gate: gContentManager->getGraphTabWidget()->handleGateFocus(id); break; } } ); menu.addSection("Python Code"); - QString pythonGetObject = (type == ModuleTreeModel::itemType::module) ? PyCodeProvider::pyCodeModule(id) : PyCodeProvider::pyCodeGate(id); - QString pythonDescription = (type == ModuleTreeModel::itemType::module) ? "Get module" : "Get gate"; + QString pythonGetObject = (type == ModuleTreeitem::Module) ? PyCodeProvider::pyCodeModule(id) : PyCodeProvider::pyCodeGate(id); + QString pythonDescription = (type == ModuleTreeitem::Module) ? "Get module" : "Get gate"; menu.addAction(QIcon(":/icons/python"), pythonDescription, [pythonGetObject]() { diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index 376f2005070..f2f4e988463 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -88,8 +88,7 @@ namespace hal return; //all relevant information - PortTreeItem* clickedItem = static_cast(mPortModel->getItemFromIndex(clickedIndex)); - ModulePinsTreeModel::itemType type = mPortModel->getTypeOfItem(clickedItem); + PortTreeItem* clickedItem = static_cast(mPortModel->getItemFromIndex(clickedIndex)); Net* n = mPortModel->getNetFromItem(clickedItem); QString name = clickedItem->getData(ModulePinsTreeModel::sNameColumn).toString(); u32 modId = mPortModel->getRepresentedModuleId(); @@ -141,7 +140,7 @@ namespace hal }); } - if (type == ModulePinsTreeModel::itemType::group) //group specific context, own helper function? (returns at the end) + if (clickedItem->type() == PortTreeItem::Group) //group specific context, own helper function? (returns at the end) { menu.addAction("Change name", [name, modId, itemId]() { InputDialog ipd("Change pin group name", "New group name", name); @@ -245,7 +244,7 @@ namespace hal appendMultiSelectionEntries(menu, modId); menu.addSection("Python"); - if(type == ModulePinsTreeModel::itemType::pin) + if(clickedItem->type()==PortTreeItem::Pin) menu.addAction(QIcon(":/icons/python"), "Get pin", [modId, itemId]() { QApplication::clipboard()->setText(PyCodeProvider::pyCodeModulePinById(modId, itemId)); }); else menu.addAction(QIcon(":/icons/python"), "Get group", [modId, itemId]() { QApplication::clipboard()->setText(PyCodeProvider::pyCodeModulePinGroup(modId, itemId)); }); @@ -298,8 +297,7 @@ namespace hal for (auto index : selectionModel()->selectedRows()) { PortTreeItem* item = static_cast(mPortModel->getItemFromIndex(index)); - auto itemType = mPortModel->getTypeOfItem(item); - if (itemType == ModulePinsTreeModel::itemType::pin) + if (item->type() == PortTreeItem::Pin) { if (!alreadyProcessedPins.contains(item)) { @@ -307,7 +305,7 @@ namespace hal alreadyProcessedPins.insert(item); } } - else if (itemType == ModulePinsTreeModel::itemType::group) + else if (item->type() == PortTreeItem::Group) { onlyPins = false; for (auto pinItem : item->getChildren()) diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_tree_model.cpp index d04b547c2f5..38f2e058d32 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_tree_model.cpp @@ -10,34 +10,28 @@ namespace hal { - ModuleTreeitem::ModuleTreeitem(const std::string &name, int id, std::string tp) - : mType(tp), mId(id), mName(name) + ModuleTreeitem::ModuleTreeitem(ItemType itp, int id, const QString &name, const QString &ntp) + : mItemType(itp), mId(id), mName(name), mNodeType(ntp) {;} QVariant ModuleTreeitem::getData(int index) const { switch (index) { - case 0: { - QVariant qvName = QVariant(QString::fromStdString(mName)); - return qvName; - break;} - case 1: { - QVariant qvId = QVariant(mId); - return qvId; - break;} - case 2: { - QVariant qvType = QVariant(QString::fromStdString(mType)); - return qvType; - break;} + case 0: + return mName; + case 1: + return mId; + case 2: + return mNodeType; } } void ModuleTreeitem::setData(QList data) { - mName = data[0].toString().toStdString(); + mName = data[0].toString(); mId = data[1].toInt(); - mType = data[2].toString().toStdString(); + mNodeType = data[2].toString(); } void ModuleTreeitem::setDataAtIndex(int index, QVariant &data) @@ -46,13 +40,13 @@ namespace hal switch (index) { - case 0: mName = data.toString().toStdString(); break; + case 0: mName = data.toString(); break; case 1: mId = data.toInt(); break; case 2: for (int j=0; j<3; j++) if (data.toString() == ctyp[j]) { - mType = data.toString().toStdString(); + mNodeType = data.toString(); break; } } @@ -101,21 +95,21 @@ namespace hal //add modules for(auto mod : m->get_submodules()) { - ModuleTreeitem* modItem = new ModuleTreeitem(mod->get_name(), - mod->get_id(), mod->get_type()); + ModuleTreeitem* modItem = new ModuleTreeitem(ModuleTreeitem::Module, + mod->get_id(), + QString::fromStdString(mod->get_name()), + QString::fromStdString(mod->get_type())); moduleRecursive(mod, modItem); - modItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::module)); - modItem->setAdditionalData(mKeyRepId, mod->get_id()); mRootItem->appendChild(modItem); mModuleToTreeitems.insert(mod, modItem); } //add gates for(auto gate : m->get_gates()) { - ModuleTreeitem* gateItem = new ModuleTreeitem(gate->get_name(), - gate->get_id(), gate->get_type()->get_name()); - gateItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(mKeyRepId, gate->get_id()); + ModuleTreeitem* gateItem = new ModuleTreeitem(ModuleTreeitem::Gate, + gate->get_id(), + QString::fromStdString(gate->get_name()), + QString::fromStdString(gate->get_type()->get_name())); mRootItem->appendChild(gateItem); mGateToTreeitems.insert(gate, gateItem); } @@ -138,42 +132,37 @@ namespace hal if(!index.isValid()) return QVariant(); - BaseTreeItem* item = getItemFromIndex(index); + ModuleTreeitem* item = dynamic_cast(getItemFromIndex(index)); if(!item) return QVariant(); if(role == Qt::DecorationRole && index.column() == 0) - return getIconFromItem(getItemFromIndex(index)); + return getIconFromItem(item); //yes, it performs the same two checks again, should be okay though (in terms of performance) return BaseTreeModel::data(index, role); } - ModuleTreeModel::itemType ModuleTreeModel::getTypeOfItem(BaseTreeItem *item) const - { - return item->getAdditionalData(mKeyItemType).value(); - } - void ModuleTreeModel::moduleRecursive(Module *mod, BaseTreeItem *modItem) { ModuleTreeitem* subModItem = nullptr; for(Module* subMod : mod->get_submodules()) { - subModItem = new ModuleTreeitem(subMod->get_name(), - subMod->get_id(), subMod->get_type()); + subModItem = new ModuleTreeitem(ModuleTreeitem::Module, + subMod->get_id(), + QString::fromStdString(subMod->get_name()), + QString::fromStdString(subMod->get_type())); moduleRecursive(subMod, subModItem); - subModItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::module)); - subModItem->setAdditionalData(mKeyRepId, subMod->get_id()); modItem->appendChild(subModItem); mModuleToTreeitems.insert(subMod, subModItem); } for(auto gate : mod->get_gates()) { - ModuleTreeitem* gateItem = new ModuleTreeitem(gate->get_name(), - gate->get_id(), gate->get_type()->get_name()); - gateItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(mKeyRepId, gate->get_id()); + ModuleTreeitem* gateItem = new ModuleTreeitem(ModuleTreeitem::Gate, + gate->get_id(), + QString::fromStdString(gate->get_name()), + QString::fromStdString(gate->get_type()->get_name())); modItem->appendChild(gateItem); mGateToTreeitems.insert(gate, gateItem); } @@ -190,8 +179,10 @@ namespace hal //1. Find index of first gate-type item int startIndex = 0; for(; startIndex < modItem->getChildCount(); startIndex++) - if(getTypeOfItem(modItem->getChild(startIndex)) != itemType::module) + { + if(static_cast(modItem->getChild(startIndex))->itemType() != ModuleTreeitem::Module) break; + } beginResetModel(); @@ -213,10 +204,10 @@ namespace hal beginResetModel(); for(auto gate : mod->get_gates()) { - ModuleTreeitem* gateItem = new ModuleTreeitem(gate->get_name(), - gate->get_id(), gate->get_type()->get_name()); - gateItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(mKeyRepId, gate->get_id()); + ModuleTreeitem* gateItem = new ModuleTreeitem(ModuleTreeitem::Gate, + gate->get_id(), + QString::fromStdString(gate->get_name()), + QString::fromStdString(gate->get_type()->get_name())); modItem->appendChild(gateItem); mGateToTreeitems.insert(gate, gateItem); } @@ -224,17 +215,17 @@ namespace hal endResetModel(); } - QIcon ModuleTreeModel::getIconFromItem(BaseTreeItem *item) const + QIcon ModuleTreeModel::getIconFromItem(ModuleTreeitem *item) const { if(!item) return QIcon(); u32 id = item->getData(1).toInt(); - switch (getTypeOfItem(item)) + switch (item->itemType()) { - case itemType::module: + case ModuleTreeitem::Module: return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::ModuleIcon,id)); - case itemType::gate: + case ModuleTreeitem::Gate: return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::GateIcon,id)); default: return QIcon(); @@ -298,11 +289,11 @@ namespace hal { beginResetModel(); auto addedMod = gNetlist->get_module_by_id(added_module); - ModuleTreeitem* addedSubmodItem = new ModuleTreeitem(addedMod->get_name(), addedMod->get_id(), - addedMod->get_type()); + ModuleTreeitem* addedSubmodItem = new ModuleTreeitem(ModuleTreeitem::Module, + addedMod->get_id(), + QString::fromStdString(addedMod->get_name()), + QString::fromStdString(addedMod->get_type())); moduleRecursive(addedMod, addedSubmodItem); - addedSubmodItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::module)); - addedSubmodItem->setAdditionalData(mKeyRepId, addedMod->get_id()); parentModItem ? parentModItem->insertChild(0, addedSubmodItem) : mRootItem->insertChild(0, addedSubmodItem); mModuleToTreeitems.insert(addedMod, addedSubmodItem); endResetModel(); @@ -322,11 +313,11 @@ namespace hal treeItemsQueue.enqueue(removedModItem); while(!treeItemsQueue.isEmpty()) { - BaseTreeItem* current = treeItemsQueue.dequeue(); - switch (getTypeOfItem(current)) + ModuleTreeitem* current = static_cast(treeItemsQueue.dequeue()); + switch (current->itemType()) { - case itemType::module: mModuleToTreeitems.remove(gNetlist->get_module_by_id(current->getData(ModuleTreeModel::sIdColumn).toInt())); break; - case itemType::gate: mGateToTreeitems.remove(gNetlist->get_gate_by_id(current->getData(ModuleTreeModel::sIdColumn).toInt()));break; + case ModuleTreeitem::Module: mModuleToTreeitems.remove(gNetlist->get_module_by_id(current->getData(ModuleTreeModel::sIdColumn).toInt())); break; + case ModuleTreeitem::Gate: mGateToTreeitems.remove(gNetlist->get_gate_by_id(current->getData(ModuleTreeModel::sIdColumn).toInt()));break; } for(auto child : current->getChildren()) treeItemsQueue.enqueue(child); @@ -353,12 +344,13 @@ namespace hal auto assignedGate = gNetlist->get_gate_by_id(assigned_gate); int indexToInsert = 0; //first item after the modules for(; indexToInsert < modItem->getChildCount(); indexToInsert++) - if(getTypeOfItem(modItem->getChild(indexToInsert)) != itemType::module) + if(static_cast(modItem->getChild(indexToInsert))->itemType() != ModuleTreeitem::Module) break; - ModuleTreeitem* gateItem = new ModuleTreeitem(assignedGate->get_name(), - assignedGate->get_id(), assignedGate->get_type()->get_name()); - gateItem->setAdditionalData(mKeyItemType, QVariant::fromValue(itemType::gate)); + ModuleTreeitem* gateItem = new ModuleTreeitem(ModuleTreeitem::Gate, + assignedGate->get_id(), + QString::fromStdString(assignedGate->get_name()), + QString::fromStdString(assignedGate->get_type()->get_name())); mGateToTreeitems.insert(assignedGate, gateItem); //beginInsertRows(getIndexFromItem(modItem), indexToInsert, indexToInsert); beginResetModel(); diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 2c4d45ff116..e2743ec7928 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -19,8 +19,8 @@ namespace hal { - PortTreeItem::PortTreeItem(QString pinName, QString pinDirection, QString pinTypee, QString netName) - : mPinName(pinName), mPinDirection(pinDirection), mPinType(pinTypee), mNetName(netName) + PortTreeItem::PortTreeItem(Type tp, QString pinName, QString pinDirection, QString pinTypee, QString netName) + : mType(tp), mPinName(pinName), mPinDirection(pinDirection), mPinType(pinTypee), mNetName(netName) {;} QVariant PortTreeItem::getData(int index) const @@ -146,7 +146,7 @@ namespace hal auto item = static_cast(getItemFromIndex(indexes.at(0))); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); - QString type = getTypeOfItem(item) == itemType::pin ? "pin" : "group"; + QString type = item->type() == PortTreeItem::Pin ? "pin" : "group"; stream << type << getIdOfItem(item); data->setText(item->getData(sNameColumn).toString()); data->setData("pintreemodel/item", encodedData); @@ -364,11 +364,10 @@ namespace hal // 5: drop adjecent index to itself, must be at least 1 item apart if(type == "group") { - auto item = mIdToGroupItem[id]; + auto item = static_cast(mIdToGroupItem[id]); if(parentItem) { - auto type = getTypeOfItem(parentItem); - if(type == itemType::pin || (type == itemType::group && row != -1) || item == parentItem) + if(item->type() == PortTreeItem::Pin || (item->type() == PortTreeItem::Group && row != -1) || item == parentItem) return false; } else // here, only check for adjacent rows @@ -384,7 +383,7 @@ namespace hal // otherwise it does not make much sense...perhaps change this check auto item = mIdToPinItem[id]; if((!parentItem && item->getParent()->getChildCount() == 1) || (item->getParent() == parentItem && row == -1) || item == parentItem - || (parentItem && (getTypeOfItem(parentItem) == itemType::pin))) + || (parentItem && (parentItem->type() == PortTreeItem::Pin))) return false; // case if one wants to drop between pins in same group, check if its not adjacent row (other cases are handled on case above if(item->getParent() == parentItem) @@ -423,7 +422,7 @@ namespace hal auto pinGroupDirection = QString::fromStdString(enum_to_string((pinGroup->get_direction()))); auto pinGroupType = QString::fromStdString(enum_to_string(pinGroup->get_type())); - PortTreeItem* pinGroupItem = new PortTreeItem(pinGroupName, pinGroupDirection, pinGroupType, ""); + PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group,pinGroupName, pinGroupDirection, pinGroupType, ""); pinGroupItem->setAdditionalData(keyType, QVariant::fromValue(itemType::group)); // port multi bit pinGroupItem->setAdditionalData(keyId, pinGroup->get_id()); mIdToGroupItem.insert(pinGroup->get_id(), pinGroupItem); From a97293d9989e8d3736f4b1622628b69acd96beee Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 14 Aug 2023 15:43:59 +0200 Subject: [PATCH 10/40] replace 'AdditionalData' from BaseTreeItem by more specific data fields --- .../gate_details_widget/pin_tree_model.h | 4 - .../netlist_elements_tree_model.h | 30 ++-- .../module_details_widget/port_tree_model.h | 23 ++- .../module_ports_tree.cpp | 18 +-- .../netlist_elements_tree_model.cpp | 135 ++++++++---------- .../module_details_widget/port_tree_model.cpp | 53 +++---- 6 files changed, 112 insertions(+), 151 deletions(-) diff --git a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h index 9a938078830..81c06e3f4b2 100644 --- a/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/gate_details_widget/pin_tree_model.h @@ -133,10 +133,6 @@ class GatePinsTreeModel : public BaseTreeModel static const int sTypeColumn = 2; static const int sConnectedNetColumn = 3; - //additional data keys - const QString keyType = "type"; - const QString keyRepresentedNetsID = "netID"; //might not be needed - private: int mGateId; QMap mPinGroupToTreeItem; diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/netlist_elements_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/netlist_elements_tree_model.h index 5bb90aa7240..b6540d1855e 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/netlist_elements_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/netlist_elements_tree_model.h @@ -29,6 +29,7 @@ #include //#include "gui/new_selection_details_widget/models/base_tree_item.h" #include "gui/basic_tree_model/base_tree_model.h" +#include "hal_core/defines.h" namespace hal { @@ -39,19 +40,30 @@ namespace hal class NetlistElementsTreeitem : public BaseTreeItem { + public: + enum ItemType { None, Module, Gate, Net}; private: - QString mType; - int mId; + ItemType mItemType; + u32 mId; QString mName; + QString mNodeType; public: - NetlistElementsTreeitem(const QString& name, int id, QString tp); + NetlistElementsTreeitem(ItemType itp, u32 id_, const QString& name, const QString& ntp = QString()); QVariant getData(int column) const override; void setData(QList data) override; void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; + + u32 id() const { return mId; } + /** + * Get the type (enum) of a given item. + * + * @return The item's type. + */ + ItemType itemType() const { return mItemType; } }; /** @@ -63,8 +75,6 @@ namespace hal Q_OBJECT public: - //metatype declaration at the end of file - enum class itemType {module = 0, gate = 1, net = 2}; /** * The constructor. @@ -121,14 +131,6 @@ namespace hal */ void setModule(Module* mod, bool showGates = true, bool showNets = true, bool displayModulesRecursive = true); - /** - * Get the type (enum) of a given item. - * - * @param item - The item for which the type is requested. - * @return The item's type. - */ - itemType getTypeOfItem(NetlistElementsTreeitem* item) const; - /** * Get the module/gate/net id that the given item represents. * To know the type of the item, call getTypeOfItem(). @@ -217,5 +219,3 @@ namespace hal }; } - -Q_DECLARE_METATYPE(hal::NetlistElementsTreeModel::itemType) diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 17080bafb79..45d5b02b91e 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -57,9 +57,17 @@ namespace hal void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; - setType(Type tp) { mType = tp; } + void setType(Type tp) { mType = tp; } Type type() const { return mType; } void setId(u32 id_) { mId = id_; } + + /** + * Returns the pin-id if the item represents a pin or the pingroup-id + * if the item represents a pingroup. + * + * @param item - The item. + * @return The pin- or pingroup-id. + */ u32 id() const { return mId; } }; @@ -121,15 +129,6 @@ namespace hal */ int getRepresentedModuleId(); - /** - * Returns the pin-id if the item represents a pin or the pingroup-id - * if the item represents a pingroup. - * - * @param item - The item. - * @return The pin- or pingroup-id. - */ - int getIdOfItem(BaseTreeItem* item) const; - /** @name Event Handler Functions */ ///@{ @@ -142,10 +141,6 @@ namespace hal static const int sTypeColumn = 2; static const int sNetColumn = 3; - //additional data keys - const QString keyType = "type"; - const QString keyId = "id"; - Q_SIGNALS: /** * Q_SIGNAL that is emitted when the number of the model's port changed. diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index f2f4e988463..7b2c60d973e 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -97,7 +97,7 @@ namespace hal std::pair sameGroup; bool onlyPins; std::tie(selectedPins, sameGroup, onlyPins) = getSelectedPins(); - int itemId = mPortModel->getIdOfItem(clickedItem); + int itemId = clickedItem->id(); QMenu menu; //shared plaintext entries: NAME, DIRECTION, TYPE (shared with pins and groups) @@ -119,7 +119,7 @@ namespace hal // } if (addToExistingActionPossible) { - menu.addAction("Add selection to existing pin group", [this, selectedPins, mod]() { + menu.addAction("Add selection to existing pin group", [selectedPins, mod]() { PingroupSelectorDialog psd("Pingroup selector", "Select pingroup", mod, false); if (psd.exec() == QDialog::Accepted) { @@ -129,7 +129,7 @@ namespace hal return; for (auto item : selectedPins) { - auto* pin = mod->get_pin_by_id(mPortModel->getIdOfItem(item)); + auto* pin = mod->get_pin_by_id(static_cast(item)->id()); if (pin == nullptr) return; pins.append(pin->get_id()); @@ -229,10 +229,10 @@ namespace hal //can be both single(simple right-click, no real selection) and multi-selection if (sameGroup.first && mod->get_pin_group_by_id(sameGroup.second)->size() > 1) { - menu.addAction("Remove selection from group", [this, selectedPins, mod /*, sameGroup*/]() { + menu.addAction("Remove selection from group", [selectedPins, mod /*, sameGroup*/]() { QList pins; for (auto item : selectedPins) - pins.append(mPortModel->getIdOfItem(item)); + pins.append(static_cast(item)->id()); ActionPingroup* act = ActionPingroup::removePinsFromGroup(mod, pins); if (act) act->exec(); @@ -266,7 +266,7 @@ namespace hal std::tie(selectedPins, sameGroup, onlyPins) = getSelectedPins(); if (selectedPins.size() > 1) { - menu.addAction("Add objects to new pin group", [this, selectedPins, modId]() { + menu.addAction("Add objects to new pin group", [selectedPins, modId]() { InputDialog ipd("Pingroup name", "New pingroup name", "ExampleName"); if (ipd.exec() == QDialog::Accepted && !ipd.textValue().isEmpty()) { @@ -274,7 +274,7 @@ namespace hal Module* mod = gNetlist->get_module_by_id(modId); for (auto item : selectedPins) { - auto* pin = mod->get_pin_by_id(mPortModel->getIdOfItem(item)); + auto* pin = mod->get_pin_by_id(static_cast(item)->id()); if (pin == nullptr) return; pins.append(pin->get_id()); @@ -322,11 +322,11 @@ namespace hal if (!selectedPins.isEmpty()) { auto mod = gNetlist->get_module_by_id(mModuleID); - auto* firstPin = mod->get_pin_by_id(mPortModel->getIdOfItem(selectedPins.front())); + auto* firstPin = mod->get_pin_by_id(static_cast(selectedPins.front())->id()); groupId = firstPin->get_group().first->get_id(); for (auto pinTreeItem : selectedPins) { - auto pin = mod->get_pin_by_id(mPortModel->getIdOfItem(pinTreeItem)); + auto pin = mod->get_pin_by_id(static_cast(pinTreeItem)->id()); if (groupId != (int)pin->get_group().first->get_id()) { sameGroup = false; diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/netlist_elements_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/netlist_elements_tree_model.cpp index 536d24d6103..b20df579034 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/netlist_elements_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/netlist_elements_tree_model.cpp @@ -10,34 +10,29 @@ namespace hal { - NetlistElementsTreeitem::NetlistElementsTreeitem(const QString &name, int id, QString tp) - : mType(tp), mId(id), mName(name) + NetlistElementsTreeitem::NetlistElementsTreeitem(ItemType itp, u32 id_, const QString &name, const QString &ntp) + : mItemType(itp), mId(id_), mName(name), mNodeType(ntp) {;} QVariant NetlistElementsTreeitem::getData(int index) const { switch (index) { - case 0: { - QVariant qvName = QVariant(mName); - return qvName; - break;} - case 1: { - QVariant qvId = QVariant(mId); - return qvId; - break;} - case 2: { - QVariant qvType = QVariant(mType); - return qvType; - break;} + case 0: + return mName; + case 1: + return mId; + case 2: + return mNodeType; } + return QVariant(); } void NetlistElementsTreeitem::setData(QList data) { mName = data[0].toString(); mId = data[1].toInt(); - mType = data[2].toString(); + mNodeType = data[2].toString(); } @@ -53,7 +48,7 @@ namespace hal for (int j=0; j<3; j++) if (data.toString() == ctyp[j]) { - mType = data.toString(); + mNodeType = data.toString(); break; } } @@ -145,12 +140,12 @@ namespace hal Module* mod = gNetlist->get_module_by_id(id); if(!mod) continue; - NetlistElementsTreeitem* modItem = new NetlistElementsTreeitem(QString::fromStdString(mod->get_name()), - mod->get_id(), QString::fromStdString(mod->get_type())); + NetlistElementsTreeitem* modItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Module, + mod->get_id(), + QString::fromStdString(mod->get_name()), + QString::fromStdString(mod->get_type())); if(displayModulesRecursive) moduleRecursive(mod, modItem, showGatesInSubmods, showNetsInSubmods); - modItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::module)); - modItem->setAdditionalData(keyRepresentedID, mod->get_id()); mRootItem->appendChild(modItem); mModuleToTreeitems.insert(mod, modItem); } @@ -158,20 +153,19 @@ namespace hal for(int id : gateIds) { Gate* gate = gNetlist->get_gate_by_id(id); - NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(QString::fromStdString(gate->get_name()), - gate->get_id(), QString::fromStdString(gate->get_type()->get_name())); - gateItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(keyRepresentedID, gate->get_id()); + NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Gate, + gate->get_id(), + QString::fromStdString(gate->get_name()), + QString::fromStdString(gate->get_type()->get_name())); mRootItem->appendChild(gateItem); mGateToTreeitems.insert(gate, gateItem); } for(int id : netIds) { Net* net = gNetlist->get_net_by_id(id); - NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(QString::fromStdString(net->get_name()), - net->get_id(), ""); - netItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::net)); - netItem->setAdditionalData(keyRepresentedID, net->get_id()); + NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Net, + net->get_id(), + QString::fromStdString(net->get_name())); mRootItem->appendChild(netItem); mNetToTreeitems.insert(net, netItem); } @@ -199,16 +193,6 @@ namespace hal Q_EMIT numberOfSubmodulesChanged(mod->get_submodules().size()); } - NetlistElementsTreeModel::itemType NetlistElementsTreeModel::getTypeOfItem(NetlistElementsTreeitem *item) const - { - return item->getAdditionalData(keyItemType).value(); - } - - int NetlistElementsTreeModel::getRepresentedIdOfItem(NetlistElementsTreeitem *item) const - { - return item->getAdditionalData(keyRepresentedID).toInt(); - } - void NetlistElementsTreeModel::gateNameChanged(Gate *g) { for(BaseTreeItem* gateItem : mGateToTreeitems.values(g)) @@ -302,13 +286,13 @@ namespace hal while(!treeItemsQueue.isEmpty()) { NetlistElementsTreeitem* currentItem = treeItemsQueue.dequeue(); - int id = currentItem->getAdditionalData(keyRepresentedID).toUInt(); + int id = currentItem->id(); - switch (getTypeOfItem(currentItem)) + switch (currentItem->itemType()) { - case itemType::module: mModuleToTreeitems.remove(gNetlist->get_module_by_id(id),currentItem); break; - case itemType::gate: mGateToTreeitems.remove(gNetlist->get_gate_by_id(id), currentItem); break; - case itemType::net: mNetToTreeitems.remove(gNetlist->get_net_by_id(id), currentItem); break; + case NetlistElementsTreeitem::Module : mModuleToTreeitems.remove(gNetlist->get_module_by_id(id),currentItem); break; + case NetlistElementsTreeitem::Gate : mGateToTreeitems.remove(gNetlist->get_gate_by_id(id), currentItem); break; + case NetlistElementsTreeitem::Net : mNetToTreeitems.remove(gNetlist->get_net_by_id(id), currentItem); break; } for(BaseTreeItem* child : currentItem->getChildren()){ @@ -349,14 +333,14 @@ namespace hal int indexToInsert = 0; for(; indexToInsert < modItem->getChildCount(); indexToInsert++) { NetlistElementsTreeitem* neti = static_cast(modItem->getChild(indexToInsert)); - if(getTypeOfItem(neti) != itemType::module) + if(neti->itemType() != NetlistElementsTreeitem::Module) break; } - NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(QString::fromStdString(assignedGate->get_name()), - assignedGate->get_id(), QString::fromStdString(assignedGate->get_type()->get_name())); - gateItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(keyRepresentedID, assignedGate->get_id()); + NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Gate, + assignedGate->get_id(), + QString::fromStdString(assignedGate->get_name()), + QString::fromStdString(assignedGate->get_type()->get_name())); //beginInsertRows(getIndexFromItem(modItem), indexToInsert, indexToInsert); beginResetModel(); modItem->insertChild(indexToInsert, gateItem); @@ -393,11 +377,11 @@ namespace hal Module* addedModule = gNetlist->get_module_by_id(added_module); auto appendNewSubmodItem = [this, addedModule](BaseTreeItem* parentModItem){ - NetlistElementsTreeitem* addedSubmodItem = new NetlistElementsTreeitem(QString::fromStdString(addedModule->get_name()), - addedModule->get_id(), QString::fromStdString(addedModule->get_type())); + NetlistElementsTreeitem* addedSubmodItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Module, + addedModule->get_id(), + QString::fromStdString(addedModule->get_name()), + QString::fromStdString(addedModule->get_type())); moduleRecursive(addedModule, addedSubmodItem, mGatesDisplayed, mNetsDisplayed); - addedSubmodItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::module)); - addedSubmodItem->setAdditionalData(keyRepresentedID, addedModule->get_id()); parentModItem->insertChild(0, addedSubmodItem); mModuleToTreeitems.insert(addedModule, addedSubmodItem); if(mNetsDisplayed) { @@ -425,11 +409,11 @@ namespace hal NetlistElementsTreeitem* subModItem = nullptr; for(Module* subMod : mod->get_submodules()) { - subModItem = new NetlistElementsTreeitem(QString::fromStdString(subMod->get_name()), - subMod->get_id(), QString::fromStdString(subMod->get_type())); + subModItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Module, + subMod->get_id(), + QString::fromStdString(subMod->get_name()), + QString::fromStdString(subMod->get_type())); moduleRecursive(subMod, subModItem, showGates); - subModItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::module)); - subModItem->setAdditionalData(keyRepresentedID, subMod->get_id()); modItem->appendChild(subModItem); mModuleToTreeitems.insert(subMod, subModItem); } @@ -437,10 +421,10 @@ namespace hal { for(auto gate : mod->get_gates()) { - NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(QString::fromStdString(gate->get_name()), - gate->get_id(), QString::fromStdString(gate->get_type()->get_name())); - gateItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::gate)); - gateItem->setAdditionalData(keyRepresentedID, gate->get_id()); + NetlistElementsTreeitem* gateItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Gate, + gate->get_id(), + QString::fromStdString(gate->get_name()), + QString::fromStdString(gate->get_type()->get_name())); modItem->appendChild(gateItem); mGateToTreeitems.insert(gate, gateItem); } @@ -449,10 +433,10 @@ namespace hal { for(auto net : mod->get_internal_nets()) { - NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(QString::fromStdString(net->get_name()), - net->get_id(), ""); - netItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::net)); - netItem->setAdditionalData(keyRepresentedID, net->get_id()); + NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Net, + net->get_id(), + QString::fromStdString(net->get_name()), + ""); modItem->appendChild(netItem); mNetToTreeitems.insert(net, netItem); } @@ -465,11 +449,11 @@ namespace hal return QIcon(); u32 id = item->getData(1).toInt(); - switch (getTypeOfItem(item)) + switch (item->itemType()) { - case itemType::module: + case NetlistElementsTreeitem::Module: return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::ModuleIcon,id)); - case itemType::gate: + case NetlistElementsTreeitem::Gate: return QIcon(*SelectionDetailsIconProvider::instance()->getIcon(SelectionDetailsIconProvider::GateIcon,id)); default: return QIcon(); @@ -479,27 +463,26 @@ namespace hal void NetlistElementsTreeModel::updateInternalNetsOfModule(NetlistElementsTreeitem *moduleItem) { BaseTreeItem* moduleItemBase = static_cast(moduleItem); - BaseTreeItem* mRootBase = static_cast(mRootItem); - int moduleId = (moduleItemBase == mRootBase) ? mModId : moduleItem->getAdditionalData(keyRepresentedID).toInt(); + BaseTreeItem* mRootBase = static_cast(mRootItem); + int moduleId = (moduleItemBase == mRootBase) ? mModId : moduleItem->id(); Module* mod = gNetlist->get_module_by_id(moduleId); //remove and delte the last child of the module-item until no net items are left - while(moduleItem->getChildCount() > 0 && getTypeOfItem(static_cast(moduleItem->getChild(moduleItem->getChildCount()-1))) == itemType::net) + while(moduleItem->getChildCount() > 0 && static_cast(moduleItem->getChild(moduleItem->getChildCount()-1))->itemType() == NetlistElementsTreeitem::Net) { NetlistElementsTreeitem* lastNetItem = static_cast(moduleItem->removeChildAtPos(moduleItem->getChildCount()-1)); - mNetToTreeitems.remove(gNetlist->get_net_by_id(lastNetItem->getAdditionalData(keyRepresentedID).toUInt()), lastNetItem); + mNetToTreeitems.remove(gNetlist->get_net_by_id(lastNetItem->id()), lastNetItem); delete lastNetItem; } //append (potentionally) new internal nets for(Net* n : mod->get_internal_nets()) { - NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(QString::fromStdString(n->get_name()),n->get_id(), ""); + NetlistElementsTreeitem* netItem = new NetlistElementsTreeitem(NetlistElementsTreeitem::Net, + n->get_id(), + QString::fromStdString(n->get_name()), + ""); //netItem->setAdditionalData(keyItemType, itemType::net); - netItem->setAdditionalData(keyItemType, QVariant::fromValue(itemType::net)); - netItem->setAdditionalData(keyRepresentedID, n->get_id()); mNetToTreeitems.insert(n, netItem); moduleItem->appendChild(netItem); } } - - } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index e2743ec7928..0b0fe67cfb2 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -143,11 +143,11 @@ namespace hal return new QMimeData(); QMimeData* data = new QMimeData(); - auto item = static_cast(getItemFromIndex(indexes.at(0))); + PortTreeItem* item = static_cast(getItemFromIndex(indexes.at(0))); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); QString type = item->type() == PortTreeItem::Pin ? "pin" : "group"; - stream << type << getIdOfItem(item); + stream << type << item->id(); data->setText(item->getData(sNameColumn).toString()); data->setData("pintreemodel/item", encodedData); return data; @@ -423,17 +423,16 @@ namespace hal auto pinGroupType = QString::fromStdString(enum_to_string(pinGroup->get_type())); PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group,pinGroupName, pinGroupDirection, pinGroupType, ""); - pinGroupItem->setAdditionalData(keyType, QVariant::fromValue(itemType::group)); // port multi bit - pinGroupItem->setAdditionalData(keyId, pinGroup->get_id()); + pinGroupItem->setId(pinGroup->get_id()); mIdToGroupItem.insert(pinGroup->get_id(), pinGroupItem); for(ModulePin* pin : pinGroup->get_pins()) { - PortTreeItem* pinItem = new PortTreeItem(QString::fromStdString(pin->get_name()), - QString::fromStdString(enum_to_string(pin->get_direction())), - QString::fromStdString(enum_to_string(pin->get_type())), - QString::fromStdString(pin->get_net()->get_name())); - pinItem->setAdditionalData(keyType, QVariant::fromValue(itemType::pin)); - pinItem->setAdditionalData(keyId, pin->get_id()); + PortTreeItem* pinItem = new PortTreeItem(PortTreeItem::Pin, + QString::fromStdString(pin->get_name()), + QString::fromStdString(enum_to_string(pin->get_direction())), + QString::fromStdString(enum_to_string(pin->get_type())), + QString::fromStdString(pin->get_net()->get_name())); + pinItem->setId(pin->get_id()); pinGroupItem->appendChild(pinItem); mNameToTreeItem.insert(QString::fromStdString(pin->get_name()), pinItem); mIdToPinItem.insert(pin->get_id(), pinItem); @@ -501,8 +500,7 @@ namespace hal if (mModuleId == -1) //no current module = no represented net return nullptr; - itemType type = getTypeOfItem(item); - if (type == itemType::portMultiBit) + if (item->type() == PortTreeItem::Group && item->getChildCount() > 1) return nullptr; Module* m = gNetlist->get_module_by_id(mModuleId); @@ -510,7 +508,7 @@ namespace hal return nullptr; //std::string name = item->getData(sNameColumn).toString().toStdString(); - if (auto* pin = m->get_pin_by_id(getIdOfItem(item)); pin != nullptr) + if (auto* pin = m->get_pin_by_id(item->id()); pin != nullptr) { return pin->get_net(); } @@ -523,16 +521,6 @@ namespace hal return mModuleId; } - ModulePinsTreeModel::itemType ModulePinsTreeModel::getTypeOfItem(PortTreeItem* item) const - { - return item->getAdditionalData(keyType).value(); - } - - int ModulePinsTreeModel::getIdOfItem(BaseTreeItem* item) const - { - return item->getAdditionalData(keyId).toInt(); - } - void ModulePinsTreeModel::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { Q_UNUSED(pev); @@ -552,12 +540,12 @@ namespace hal // if(ipd.exec() == QDialog::Rejected) return false; mIgnoreEventsFlag = true; QList pins; - auto srcgroup = mModule->get_pin_group_by_id(getIdOfItem(droppedGroup)); + auto srcgroup = mModule->get_pin_group_by_id(static_cast(droppedGroup)->id()); for(const auto &pin : srcgroup->get_pins()) pins.append(pin->get_id()); if (pins.isEmpty()) return; // no pins to move - auto tgtgroup = mModule->get_pin_group_by_id(getIdOfItem(onDroppedGroup)); + auto tgtgroup = mModule->get_pin_group_by_id(static_cast(onDroppedGroup)->id()); ActionPingroup* act = ActionPingroup::addPinsToExistingGroup(mModule,tgtgroup->get_id(),pins); if (act) act->exec(); @@ -576,7 +564,7 @@ namespace hal bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; - ActionPingroup* act = new ActionPingroup(PinActionType::GroupMove,getIdOfItem(droppedGroup),"",desiredIdx); + ActionPingroup* act = new ActionPingroup(PinActionType::GroupMove,droppedGroup->id(),"",desiredIdx); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); bool ok = act->exec(); if(ok){ @@ -589,9 +577,8 @@ namespace hal void ModulePinsTreeModel::dndPinOnGroup(PortTreeItem *droppedPin, BaseTreeItem *onDroppedGroup) { mIgnoreEventsFlag = true; - u32 pinId = getIdOfItem(droppedPin); - ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,pinId,"",getIdOfItem(onDroppedGroup)); + ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); act->exec(); auto oldParent = droppedPin->getParent(); removeItem(droppedPin); @@ -615,11 +602,11 @@ namespace hal bool bottomEdge = row == onDroppedParent->getChildCount(); desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; // insert item here - act = new ActionPingroup(PinActionType::PinSetindex,getIdOfItem(droppedPin),"",desiredIdx); // TODO : start_index, descending + act = new ActionPingroup(PinActionType::PinSetindex,droppedPin->id(),"",desiredIdx); // TODO : start_index, descending } else { - act = ActionPingroup::addPinToExistingGroup(mModule,getIdOfItem(onDroppedParent),getIdOfItem(droppedPin),desiredIdx); + act = ActionPingroup::addPinToExistingGroup(mModule,static_cast(onDroppedParent)->id(),droppedPin->id(),desiredIdx); if (!act) return; } act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); @@ -641,7 +628,7 @@ namespace hal Q_UNUSED(row) mIgnoreEventsFlag = true; - auto pinToMove = mModule->get_pin_by_id(getIdOfItem(droppedPin)); + auto pinToMove = mModule->get_pin_by_id(droppedPin->id()); if (!pinToMove) return; QString groupName = QString::fromStdString(pinToMove->get_name()); @@ -687,7 +674,7 @@ namespace hal parent->insertChild(index, item); endInsertRows(); //mNameToTreeItem.insert(item->getData(sNameColumn).toString(), item); - getTypeOfItem(item) == itemType::pin ? mIdToPinItem.insert(getIdOfItem(item), item) : mIdToGroupItem.insert(getIdOfItem(item), item); + item->type() == PortTreeItem::Pin ? mIdToPinItem.insert(item->id(), item) : mIdToGroupItem.insert(item->id(), item); //mIdToPinItem.insert(getIdOfItem(item), item); } void ModulePinsTreeModel::removeItem(PortTreeItem* item) @@ -697,7 +684,7 @@ namespace hal endRemoveRows(); //mNameToTreeItem.remove(item->getData(sNameColumn).toString()); //for now, only ids of pin-items (since these functions are only relevant for dnd) - getTypeOfItem(item) == itemType::pin ? mIdToPinItem.remove(getIdOfItem(item)) : mIdToGroupItem.remove(getIdOfItem(item)); + item->type() == PortTreeItem::Pin ? mIdToPinItem.remove(item->id()) : mIdToGroupItem.remove(item->id()); //mIdToPinItem.remove(getIdOfItem(item)); //delete item; } From c46a098e631f7014ddb7546a71b1ec6fbb422f9d Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 7 Sep 2023 20:43:10 +0200 Subject: [PATCH 11/40] Replace Result with bool --- .../hal_core/netlist/gate_library/gate_type.h | 6 +- include/hal_core/netlist/module.h | 24 +- .../src/plugin_bitorder_propagation.cpp | 5 +- plugins/dataflow_analysis/src/api/result.cpp | 14 +- .../module_details_widget/port_tree_model.cpp | 2 +- .../action_add_items_to_object.cpp | 2 +- .../gui/src/user_action/action_pingroup.cpp | 8 +- .../action_remove_items_from_object.cpp | 2 +- .../src/user_action/action_reorder_object.cpp | 3 +- .../netlist_modification_decorator.cpp | 7 +- src/netlist/gate_library/gate_type.cpp | 35 +-- src/netlist/module.cpp | 205 ++++++++++-------- src/python_bindings/bindings/gate_type.cpp | 5 +- src/python_bindings/bindings/module.cpp | 25 +-- tests/netlist/module.cpp | 32 +-- 15 files changed, 193 insertions(+), 182 deletions(-) diff --git a/include/hal_core/netlist/gate_library/gate_type.h b/include/hal_core/netlist/gate_library/gate_type.h index 34399a46661..17fcdf81893 100644 --- a/include/hal_core/netlist/gate_library/gate_type.h +++ b/include/hal_core/netlist/gate_library/gate_type.h @@ -354,9 +354,9 @@ namespace hal * Delete the given pin group. * * @param[in] pin_group - The pin group to be deleted. - * @returns Ok on success, an error message otherwise. + * @returns true on success, false otherwise. */ - Result delete_pin_group(PinGroup* pin_group); + bool delete_pin_group(PinGroup* pin_group); /** * Assign a pin to a pin group. @@ -469,6 +469,6 @@ namespace hal GateType& operator=(const GateType&) = delete; Result*> create_pin_group_internal(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending, u32 start_index); - Result delete_pin_group_internal(PinGroup* pin_group); + bool delete_pin_group_internal(PinGroup* pin_group); }; } // namespace hal diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index 02cabb44aa4..874102df6cc 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -519,9 +519,9 @@ namespace hal * Delete the given pin group. * * @param[in] pin_group - The pin group to be deleted. - * @returns Ok on success, an error message otherwise. + * @returns true on success, false otherwise. */ - Result delete_pin_group(PinGroup* pin_group); + bool delete_pin_group(PinGroup* pin_group); /** * Move a pin group to another index within the module. @@ -531,7 +531,7 @@ namespace hal * @param[in] new_index - The index to which the pin group is moved. * @returns Ok on success, an error message otherwise. */ - Result move_pin_group(PinGroup* pin_group, u32 new_index); + bool move_pin_group(PinGroup* pin_group, u32 new_index); /** * Set the name of the given pin group. @@ -566,9 +566,9 @@ namespace hal * @param[in] pin_group - The new pin group. * @param[in] pin - The pin to be added. * @param[in] delete_empty_groups - Set `true` to delete groups that are empty after the pin has been assigned to the new group, `false` to keep empty groups. Defaults to `true`. - * @returns Ok on success, an error message otherwise. + * @returns `true` on success, `false` otherwise. */ - Result assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true); + bool assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true); /** * Move a pin to another index within the given pin group. @@ -577,9 +577,9 @@ namespace hal * @param[in] pin_group - The pin group. * @param[in] pin - The pin to be moved. * @param[in] new_index - The index to which the pin is moved. - * @returns Ok on success, an error message otherwise. + * @returns `true` on success, `false` otherwise. */ - Result move_pin_within_group(PinGroup* pin_group, ModulePin* pin, u32 new_index); + bool move_pin_within_group(PinGroup* pin_group, ModulePin* pin, u32 new_index); /** * Remove a pin from a pin group. @@ -588,9 +588,9 @@ namespace hal * @param[in] pin_group - The old pin group. * @param[in] pin - The pin to be removed. * @param[in] delete_empty_groups - Set `true` to delete the group of it is empty after the pin has been removed, `false` to keep the empty group. Defaults to `true`. - * @returns Ok on success, an error message otherwise. + * @returns `true` on success, `false` otherwise. */ - Result remove_pin_from_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true); + bool remove_pin_from_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true); /* * ################################################################ @@ -736,10 +736,10 @@ namespace hal NetConnectivity check_net_endpoints(const Net* net) const; Result check_net(Net* net, bool recursive = false); Result assign_pin_net(const u32 pin_id, Net* net, PinDirection direction, const std::string& name = "", PinType type = PinType::none); - Result remove_pin_net(Net* net); + bool remove_pin_net(Net* net); Result create_pin_internal(const u32 id, const std::string& name, Net* net, PinDirection direction, PinType type); - Result delete_pin_internal(ModulePin* pin); + bool delete_pin_internal(ModulePin* pin); Result*> create_pin_group_internal(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending, u32 start_index); - Result delete_pin_group_internal(PinGroup* pin_group); + bool delete_pin_group_internal(PinGroup* pin_group); }; } // namespace hal diff --git a/plugins/bitorder_propagation/src/plugin_bitorder_propagation.cpp b/plugins/bitorder_propagation/src/plugin_bitorder_propagation.cpp index 32df78b9850..7e839e0d7ac 100644 --- a/plugins/bitorder_propagation/src/plugin_bitorder_propagation.cpp +++ b/plugins/bitorder_propagation/src/plugin_bitorder_propagation.cpp @@ -928,10 +928,9 @@ namespace hal for (const auto& [index, pin] : index_to_pin) { - auto move_res = m->move_pin_within_group(pg, pin, index); - if (move_res.is_error()) + if (!m->move_pin_within_group(pg, pin, index)) { - return ERR_APPEND(move_res.get_error(), + return ERR( "cannot reorder module pin groups: failed to move pin " + pin->get_name() + " in pin group " + pg->get_name() + " of module with ID " + std::to_string(m->get_id()) + " to new index " + std::to_string(index)); } diff --git a/plugins/dataflow_analysis/src/api/result.cpp b/plugins/dataflow_analysis/src/api/result.cpp index 1aecd57dcaf..d8441ec5c2c 100644 --- a/plugins/dataflow_analysis/src/api/result.cpp +++ b/plugins/dataflow_analysis/src/api/result.cpp @@ -519,9 +519,9 @@ namespace hal } else { - if (const auto res = new_mod->assign_pin_to_group(data_in_group, pin); res.is_error()) + if (!new_mod->assign_pin_to_group(data_in_group, pin)) { - log_warning("dataflow", "{}", res.get_error().get()); + log_warning("dataflow", "Assign pin to group failed."); } } @@ -542,9 +542,9 @@ namespace hal } else { - if (const auto res = new_mod->assign_pin_to_group(data_out_group, pin); res.is_error()) + if (!new_mod->assign_pin_to_group(data_out_group, pin)) { - log_warning("dataflow", "{}", res.get_error().get()); + log_warning("dataflow", "Assign pin to group failed."); } } @@ -588,9 +588,9 @@ namespace hal } else { - if (const auto res = new_mod->assign_pin_to_group(pin_group, pin); res.is_error()) + if (!new_mod->assign_pin_to_group(pin_group, pin)) { - log_warning("dataflow", "{}", res.get_error().get()); + log_warning("dataflow", "Assign pin to group failed."); } } @@ -814,4 +814,4 @@ namespace hal return OK(new_group_ids); } } // namespace dataflow -} // namespace hal \ No newline at end of file +} // namespace hal diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 0b0fe67cfb2..84e15af7392 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -325,7 +325,7 @@ namespace hal // if (droppedParentItem != onDroppedItem) // { // mIgnoreEventsFlag = true; -// //int ret = mod->assign_pin_to_group(onDroppedGroup, droppedPin).is_ok(); +// //bool ret = mod->assign_pin_to_group(onDroppedGroup, droppedPin); // ActionAddItemsToObject* addAct = new ActionAddItemsToObject(QSet(), QSet(), QSet(), QSet() << droppedPin->get_id()); // addAct->setObject(UserActionObject(onDroppedGroup->get_id(), UserActionObjectType::PinGroup)); // addAct->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); diff --git a/plugins/gui/src/user_action/action_add_items_to_object.cpp b/plugins/gui/src/user_action/action_add_items_to_object.cpp index 25a201b5c0c..4ba1022590b 100644 --- a/plugins/gui/src/user_action/action_add_items_to_object.cpp +++ b/plugins/gui/src/user_action/action_add_items_to_object.cpp @@ -201,7 +201,7 @@ namespace hal for (auto id : mPins) { - if (mod->assign_pin_to_group(pinGrp, mod->get_pin_by_id(id), false).is_error()) + if (!mod->assign_pin_to_group(pinGrp, mod->get_pin_by_id(id), false)) { return false; } diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 86c711b1878..a59affc1332 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -304,7 +304,7 @@ namespace hal int ptype = (int) pgroup->get_type(); int pdir = (int) pgroup->get_direction(); QString name = QString::fromStdString(pgroup->get_name()); - if (mParentModule->delete_pin_group(pgroup).is_error()) + if (!mParentModule->delete_pin_group(pgroup)) return false; addUndoAction(PinActionType::GroupCreate,id,name,v); addUndoAction(PinActionType::GroupTypechange,id,"",ptype); @@ -316,7 +316,7 @@ namespace hal int inx = pinGroupRow(mParentModule,pgroup); if (inx < 0) return false; addUndoAction(PinActionType::GroupMove,pgroup->get_id(),"",inx); - if (mParentModule->move_pin_group(pgroup,aa.mValue).is_error()) + if (!mParentModule->move_pin_group(pgroup,aa.mValue)) return false; break; } @@ -341,7 +341,7 @@ namespace hal mPinsMoved.insert(aa.mId); pgroup = getGroup(aa.mValue); if (!pgroup) return false; - if (mParentModule->assign_pin_to_group(pgroup,pin).is_error()) + if (!mParentModule->assign_pin_to_group(pgroup,pin)) return false; break; case PinActionType::PinRename: @@ -358,7 +358,7 @@ namespace hal if (!mPinsMoved.contains(aa.mId)) addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); pgroup = pin->get_group().first; - if (!mParentModule->move_pin_within_group(pgroup,pin,aa.mValue).is_ok()) + if (!mParentModule->move_pin_within_group(pgroup,pin,aa.mValue)) return false; break; default: diff --git a/plugins/gui/src/user_action/action_remove_items_from_object.cpp b/plugins/gui/src/user_action/action_remove_items_from_object.cpp index 79212b7e558..d5a20fc738b 100644 --- a/plugins/gui/src/user_action/action_remove_items_from_object.cpp +++ b/plugins/gui/src/user_action/action_remove_items_from_object.cpp @@ -136,7 +136,7 @@ namespace hal } for (u32 id : mPins) { - if (mod->remove_pin_from_group(pinGroup, mod->get_pin_by_id(id), false).is_error()) + if (!mod->remove_pin_from_group(pinGroup, mod->get_pin_by_id(id), false)) { return false; } diff --git a/plugins/gui/src/user_action/action_reorder_object.cpp b/plugins/gui/src/user_action/action_reorder_object.cpp index d3f915fb716..120aedb02d4 100644 --- a/plugins/gui/src/user_action/action_reorder_object.cpp +++ b/plugins/gui/src/user_action/action_reorder_object.cpp @@ -44,8 +44,7 @@ namespace hal if (pinGroup->size() > 1) { oldIndex = pin->get_group().second; - auto result = mod->move_pin_within_group(pinGroup, pin, mNewIndex); - if (result.is_error()) + if (!mod->move_pin_within_group(pinGroup, pin, mNewIndex)) { return false; } diff --git a/src/netlist/decorators/netlist_modification_decorator.cpp b/src/netlist/decorators/netlist_modification_decorator.cpp index 4eee34294d3..1b37bd13f17 100644 --- a/src/netlist/decorators/netlist_modification_decorator.cpp +++ b/src/netlist/decorators/netlist_modification_decorator.cpp @@ -297,10 +297,9 @@ namespace hal // delete old pin group incase it is now empty if (current_pin_group->get_pins().empty()) { - if (const auto res = m->delete_pin_group(current_pin_group); !res.is_ok()) + if (!m->delete_pin_group(current_pin_group)) { - return ERR_APPEND(res.get_error(), - "could not connect master net '" + master_net->get_name() + "' with ID " + std::to_string(master_net->get_id()) + " with slave net '" + slave_net->get_name() + return ERR("could not connect master net '" + master_net->get_name() + "' with ID " + std::to_string(master_net->get_id()) + " with slave net '" + slave_net->get_name() + "' with ID " + std::to_string(slave_net->get_id()) + ": failed to delete pingroup " + current_pin_group->get_name() + "with ID " + std::to_string(current_pin_group->get_id()) + " that is now empty."); } @@ -346,4 +345,4 @@ namespace hal return OK(master_net); } -} // namespace hal \ No newline at end of file +} // namespace hal diff --git a/src/netlist/gate_library/gate_type.cpp b/src/netlist/gate_library/gate_type.cpp index 2d569e30e8d..c8e2d2672ff 100644 --- a/src/netlist/gate_library/gate_type.cpp +++ b/src/netlist/gate_library/gate_type.cpp @@ -383,7 +383,7 @@ namespace hal { if (auto res = assign_pin_to_group(pin_group, pin, delete_empty_groups); res.is_error()) { - assert(delete_pin_group(pin_group).is_ok()); + assert(delete_pin_group(pin_group)); return ERR(res.get_error()); } } @@ -397,17 +397,17 @@ namespace hal return create_pin_group(get_unique_pin_group_id(), name, pins, direction, type, ascending, start_index, delete_empty_groups); } - Result GateType::delete_pin_group_internal(PinGroup* pin_group) + bool GateType::delete_pin_group_internal(PinGroup* pin_group) { // some sanity checks if (pin_group == nullptr) { - return ERR("could not delete pin group of gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("gate", "could not delete pin group of gate type '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not delete pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of gate type '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin group does not belong to gate type"); + log_warning("gate", "could not delete pin group '{}' with ID {} of gate type '{}' with ID {}: pin group does not belong to gate type", pin_group->get_name(), pin_group->get_id(), m_name, m_id); } // erase pin group @@ -422,20 +422,21 @@ namespace hal m_free_pin_group_ids.insert(del_id); m_used_pin_group_ids.erase(del_id); - return OK({}); + return true; } - Result GateType::delete_pin_group(PinGroup* pin_group) + bool GateType::delete_pin_group(PinGroup* pin_group) { if (pin_group == nullptr) { - return ERR("could not delete pin group from gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("gate", "could not delete pin group from gate type '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not delete pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " from gate type '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin group does not belong to gate type"); + log_warning("gate", "could not delete pin group '{}' with ID {} from gate type '{}' with ID {}: pin group does not belong to gate type", pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } bool removed_pins = false; @@ -446,16 +447,17 @@ namespace hal removed_pins = true; if (auto res = create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, false); res.is_error()) { - return ERR(res.get_error()); + log_warning("gate", "{}", res.get_error().get()); + return false; } } - if (auto res = delete_pin_group_internal(pin_group); res.is_error()) + if (!delete_pin_group_internal(pin_group)) { - return ERR(res.get_error()); + return false; } - return OK({}); + return true; } Result GateType::assign_pin_to_group(PinGroup* pin_group, GatePin* pin, bool delete_empty_groups) @@ -496,10 +498,9 @@ namespace hal if (delete_empty_groups && pg->empty()) { - if (auto res = delete_pin_group_internal(pg); res.is_error()) + if (!delete_pin_group_internal(pg)) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + return ERR("could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": unable to delete pin group '" + pg->get_name() + "' with ID " + std::to_string(pg->get_id())); } diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 4bab800c4d8..435f4856423 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -734,9 +734,9 @@ namespace hal { m_output_nets.erase(net); } - if (auto res = remove_pin_net(net); res.is_error()) + if (!remove_pin_net(net)) { - return res; + return ERR("Remove pin net failed"); } } } @@ -836,7 +836,7 @@ namespace hal { if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name, direction, type, true, 0); group_res.is_error()) { - assert(delete_pin_internal(pin_res.get()).is_ok()); + assert(delete_pin_internal(pin_res.get())); return ERR_APPEND(group_res.get_error(), "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to create pin group"); } else @@ -844,8 +844,8 @@ namespace hal // create_pin_group_internal OK if (const auto assign_res = group_res.get()->assign_pin(pin_res.get()); assign_res.is_error()) { - assert(delete_pin_internal(pin_res.get()).is_ok()); - assert(delete_pin_group_internal(group_res.get()).is_ok()); + assert(delete_pin_internal(pin_res.get())); + assert(delete_pin_group_internal(group_res.get())); return ERR_APPEND(assign_res.get_error(), "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to assign pin to pin group"); } @@ -1253,10 +1253,10 @@ namespace hal for (auto* pin : pins) { - if (auto res = assign_pin_to_group(pin_group, pin, delete_empty_groups); res.is_error()) + if (!assign_pin_to_group(pin_group, pin, delete_empty_groups)) { - assert(delete_pin_group(pin_group).is_ok()); - return ERR(res.get_error()); + assert(delete_pin_group(pin_group)); + return ERR("Assign pin to group failed."); } } @@ -1270,17 +1270,20 @@ namespace hal return create_pin_group(get_unique_pin_group_id(), name, pins, direction, type, ascending, start_index, delete_empty_groups); } - Result Module::delete_pin_group(PinGroup* pin_group) + bool Module::delete_pin_group(PinGroup* pin_group) { if (pin_group == nullptr) { - return ERR("could not delete pin group from module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not delete pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " from module '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin group does not belong to module"); + log_warning("module", + "could not delete pin group '{}' with ID {} from module '{}' with ID {}: pin group does not belong to module", + pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } bool removed_pins = false; @@ -1291,41 +1294,44 @@ namespace hal removed_pins = true; if (auto res = create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, false); res.is_error()) { - return ERR(res.get_error()); + return false; } } u32 pin_group_id_to_delete = pin_group->get_id(); - if (auto res = delete_pin_group_internal(pin_group); res.is_error()) + if (!delete_pin_group_internal(pin_group)) { - return ERR(res.get_error()); + return false; } if (removed_pins) { m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); } - return OK({}); + return true; } - Result Module::move_pin_group(PinGroup* pin_group, u32 new_index) + bool Module::move_pin_group(PinGroup* pin_group, u32 new_index) { if (pin_group == nullptr) { - return ERR("could not move pin group of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not move pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not move pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " within module '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin group does not belong to module"); + log_warning("module", "could not move pin group '{}' with ID {} within module '{}' with ID {}: pin group does not belong to module", + pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (new_index >= m_pin_groups_ordered.size()) { - return ERR("could not move pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) - + ": index " + std::to_string(new_index) + " is out of bounds"); + log_warning("module", "could not move pin group '{}' with ID {} of module '{}' with ID {}: index {} is out of bounds", + pin_group->get_name(), pin_group->get_id(), m_name, m_id, new_index); + return false; } auto src_it = std::find(m_pin_groups_ordered.begin(), m_pin_groups_ordered.end(), pin_group); @@ -1333,7 +1339,7 @@ namespace hal std::advance(dst_it, new_index); if (src_it == dst_it) { - return OK({}); + return true; } else if (std::distance(m_pin_groups_ordered.begin(), src_it) < std::distance(m_pin_groups_ordered.begin(), dst_it)) { @@ -1346,32 +1352,36 @@ namespace hal } m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupReorder,pin_group->get_id())); - return OK({}); + return true; } - Result Module::assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) + bool Module::assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) { if (pin_group == nullptr) { - return ERR("could not assign pin to pin group of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (pin == nullptr) { - return ERR("could not assign pin to pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " - + std::to_string(m_id) + ": pin is a 'nullptr'"); + log_warning("module", "could not assign pin to pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", + pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group does not belong to module"); + log_warning("module", "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin) { - return ERR("could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin does not belong to module"); + log_warning("module", "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (PinGroup* pg = pin->get_group().first; pg != nullptr) @@ -1379,104 +1389,111 @@ namespace hal // remove from old group and potentially delete old group if empty if (auto res = pg->remove_pin(pin); res.is_error()) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": unable to remove pin from pin group '" + pg->get_name() - + "' with ID " + std::to_string(pg->get_id())); + log_warning("module", + "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to remove pin from pin group '{}' with ID {}", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id, pg->get_name(), pg->get_id()); + return false; } if (delete_empty_groups && pg->empty()) { - if (auto res = delete_pin_group_internal(pg); res.is_error()) + if (!delete_pin_group_internal(pg)) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": unable to delete pin group '" + pg->get_name() - + "' with ID " + std::to_string(pg->get_id())); + log_warning("module", + "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to delete pin group '{}' with ID {}", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id, pg->get_name(), pg->get_id()); + return false; } } } if (auto res = pin_group->assign_pin(pin); res.is_error()) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id)); + log_warning("module", + "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}", pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupPinAssign,pin_group->get_id())); - return OK({}); + return true;; } - Result Module::move_pin_within_group(PinGroup* pin_group, ModulePin* pin, u32 new_index) + bool Module::move_pin_within_group(PinGroup* pin_group, ModulePin* pin, u32 new_index) { if (pin_group == nullptr) { - return ERR("could not move pin within pin group of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not move pin within pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (pin == nullptr) { - return ERR("could not move pin within pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " - + std::to_string(m_id) + ": pin is a 'nullptr'"); + log_warning("module", "could not move pin within pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", + pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not move pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " within pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group does not belong to module"); + log_warning("module", + "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin) { - return ERR("could not move pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " within pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin does not belong to module"); + log_warning("module", + "could not move pin '{}' with ID {} within pin group '{}' with return ERRID {} of module '{}' with ID {}: pin does not belong to module", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (auto res = pin_group->move_pin(pin, new_index); res.is_error()) { - return ERR_APPEND(res.get_error(), - "could not move pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " within pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id)); + log_warning("module", + "could not move pin '{}' with ID {} within pin group '{}' with ID {} of module '{}' with ID {}", + pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinReorder,pin->get_id())); - return OK({}); + return true; } - Result Module::remove_pin_from_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) + bool Module::remove_pin_from_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) { if (pin_group == nullptr) { - return ERR("could not remove pin from pin group of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not remove pin from pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (pin == nullptr) { - return ERR("could not remove pin from pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " - + std::to_string(m_id) + ": pin is a 'nullptr'"); + log_warning("module", "could not remove pin from pin group '{}' with ID {} of module '{}' with ID {}: pin is a 'nullptr'", pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group does not belong to module"); + log_warning("module", "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin) { - return ERR("could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin does not belong to module"); + log_warning("module", "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } if (auto res = create_pin_group(get_unique_pin_group_id(), pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, delete_empty_groups); res.is_error()) { - return ERR_APPEND(res.get_error(), - "could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from pin group '" + pin_group->get_name() + "' with ID " - + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) + ": unable to create new pin group for pin"); + log_warning("module", "could not remove pin '{}' with ID {} from pin group '{}' with ID {} of module '{}' with ID : unable to create new pin group for pin", pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } - return OK({}); + return true; } Result Module::assign_pin_net(const u32 pin_id, Net* net, PinDirection direction, const std::string& name, PinType type) @@ -1539,12 +1556,13 @@ namespace hal return OK(pin); } - Result Module::remove_pin_net(Net* net) + bool Module::remove_pin_net(Net* net) { auto pin = get_pin_by_net(net); if (pin == nullptr) { - return ERR("could not remove pin from net: failed to get pin corresponding to net"); + log_warning("module", "could not remove pin from net: failed to get pin corresponding to net"); + return false; } PinGroup* pin_group = pin->get_group().first; @@ -1552,32 +1570,29 @@ namespace hal if (auto res = pin_group->remove_pin(pin); res.is_error()) { - return ERR_APPEND(res.get_error(), - "could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from net '" + net->get_name() + "' with ID " + std::to_string(net->get_id()) - + ": failed to remove pin from pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id())); + log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin_group->get_name(), pin_group->get_id()); + return false; } if (pin_group->empty()) { - if (auto res = delete_pin_group_internal(pin_group); res.is_error()) + if (!delete_pin_group_internal(pin_group)) { - return ERR_APPEND(res.get_error(), - "could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from net '" + net->get_name() + "' with ID " - + std::to_string(net->get_id()) + ": failed to delete pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id())); + log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin_group->get_name(), pin_group->get_id()); + return false; } } u32 pin_id_to_delete = pin->get_id(); - if (const auto res = delete_pin_internal(pin); res.is_error()) + if (!delete_pin_internal(pin)) { - return ERR_APPEND(res.get_error(), - "could not remove pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " from net '" + net->get_name() + "' with ID " + std::to_string(net->get_id()) - + ": failed to delete pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id())); + log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin->get_name(), pin->get_id()); + return false; } m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinDelete,pin_id_to_delete)); - return OK({}); + return true; } Result Module::create_pin_internal(const u32 id, const std::string& name, Net* net, PinDirection direction, PinType type) @@ -1621,17 +1636,18 @@ namespace hal return OK(pin); } - Result Module::delete_pin_internal(ModulePin* pin) + bool Module::delete_pin_internal(ModulePin* pin) { // some sanity checks if (pin == nullptr) { - return ERR("could not delete pin of gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": pin is a 'nullptr'"); + log_warning("module", "could not delete pin of gate type '{}' with ID {}: pin is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pins_map.find(pin->get_id()); it == m_pins_map.end() || it->second != pin) { - return ERR("could not delete pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin does not belong to module"); + log_warning("module", "could not delete pin '{}' with ID {} of module '{}' with ID {}: pin does not belong to module", pin->get_name(), pin->get_id(), m_name, m_id); + return false; } // erase pin @@ -1645,7 +1661,7 @@ namespace hal m_free_pin_ids.insert(del_id); m_used_pin_ids.erase(del_id); - return OK({}); + return true; } Result*> Module::create_pin_group_internal(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending, u32 start_index) @@ -1682,17 +1698,20 @@ namespace hal return OK(pin_group); } - Result Module::delete_pin_group_internal(PinGroup* pin_group) + bool Module::delete_pin_group_internal(PinGroup* pin_group) { // some sanity checks if (pin_group == nullptr) { - return ERR("could not delete pin group of module '" + m_name + "' with ID " + std::to_string(m_id) + ": pin group is a 'nullptr'"); + log_warning("module", "could not delete pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); + return false; } if (const auto it = m_pin_groups_map.find(pin_group->get_id()); it == m_pin_groups_map.end() || it->second != pin_group) { - return ERR("could not delete pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of module '" + m_name + "' with ID " + std::to_string(m_id) - + ": pin group does not belong to module"); + log_warning("module", + "could not delete pin group '{}' with ID {} of module '{}' with ID {}: pin group does not belong to module", + pin_group->get_name(), pin_group->get_id(), m_name, m_id); + return false; } // erase pin group @@ -1707,7 +1726,7 @@ namespace hal m_free_pin_group_ids.insert(del_id); m_used_pin_group_ids.erase(del_id); - return OK({}); + return true; } u32 Module::pinevent_associated_data(PinEvent pev, u32 id) diff --git a/src/python_bindings/bindings/gate_type.cpp b/src/python_bindings/bindings/gate_type.cpp index 449940d128f..4875ab91245 100644 --- a/src/python_bindings/bindings/gate_type.cpp +++ b/src/python_bindings/bindings/gate_type.cpp @@ -487,14 +487,13 @@ namespace hal py_gate_type.def( "delete_pin_group", [](GateType& self, PinGroup* pin_group) { - auto res = self.delete_pin_group(pin_group); - if (res.is_ok()) + if (self.delete_pin_group(pin_group)) { return true; } else { - log_error("python_context", "error encountered while deleting pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while deleting pin group"); return false; } }, diff --git a/src/python_bindings/bindings/module.cpp b/src/python_bindings/bindings/module.cpp index 101d2047fe7..9c5f25dafa3 100644 --- a/src/python_bindings/bindings/module.cpp +++ b/src/python_bindings/bindings/module.cpp @@ -770,14 +770,13 @@ namespace hal py_module.def( "delete_pin_group", [](Module& self, PinGroup* pin_group) { - auto res = self.delete_pin_group(pin_group); - if (res.is_ok()) + if (self.delete_pin_group(pin_group)) { return true; } else { - log_error("python_context", "error encountered while deleting pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while deleting pin group."); return false; } }, @@ -793,14 +792,13 @@ namespace hal py_module.def( "move_pin_group", [](Module& self, PinGroup* pin_group, u32 new_index) { - auto res = self.move_pin_group(pin_group, new_index); - if (res.is_ok()) + if (self.move_pin_group(pin_group, new_index)) { return true; } else { - log_error("python_context", "error encountered while moving pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while moving pin group."); return false; } }, @@ -819,14 +817,13 @@ namespace hal py_module.def( "assign_pin_to_group", [](Module& self, PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true) { - auto res = self.assign_pin_to_group(pin_group, pin, delete_empty_groups); - if (res.is_ok()) + if (self.assign_pin_to_group(pin_group, pin, delete_empty_groups)) { return true; } else { - log_error("python_context", "error encountered while assigning pin to pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while assigning pin to pin group."); return false; } }, @@ -846,14 +843,13 @@ namespace hal py_module.def( "move_pin_within_group", [](Module& self, PinGroup* pin_group, ModulePin* pin, u32 new_index) { - auto res = self.move_pin_within_group(pin_group, pin, new_index); - if (res.is_ok()) + if (self.move_pin_within_group(pin_group, pin, new_index)) { return true; } else { - log_error("python_context", "error encountered while moving pin within pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while moving pin within pin group."); return false; } }, @@ -874,14 +870,13 @@ namespace hal py_module.def( "remove_pin_from_group", [](Module& self, PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups = true) { - auto res = self.remove_pin_from_group(pin_group, pin, delete_empty_groups); - if (res.is_ok()) + if (self.remove_pin_from_group(pin_group, pin, delete_empty_groups)) { return true; } else { - log_error("python_context", "error encountered while removing pin from pin group:\n{}", res.get_error().get()); + log_error("python_context", "error encountered while removing pin from pin group."); return false; } }, diff --git a/tests/netlist/module.cpp b/tests/netlist/module.cpp index 20a2d552561..e8dd56823e4 100644 --- a/tests/netlist/module.cpp +++ b/tests/netlist/module.cpp @@ -980,7 +980,7 @@ namespace hal { // delete pin group u32 group_id = in_group->get_id(); - EXPECT_TRUE(m_1->delete_pin_group(in_group).is_ok()); + EXPECT_TRUE(m_1->delete_pin_group(in_group)); EXPECT_EQ(m_1->get_pin_group_by_id(group_id), nullptr); EXPECT_EQ(m_1->get_pin_groups().size(), 4); PinGroup* in_group_0 = in_pin_0->get_group().first; @@ -995,7 +995,7 @@ namespace hal { EXPECT_EQ(in_group_0->get_index(in_pin_0).get(), 0); // assign pin to group - EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, in_pin_1).is_ok()); + EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, in_pin_1)); EXPECT_EQ(m_1->get_pin_groups().size(), 3); EXPECT_EQ(in_group_0->size(), 2); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group_0, i32(0))); @@ -1006,7 +1006,7 @@ namespace hal { EXPECT_EQ(in_group_0->get_pin_at_index(1).get(), in_pin_1); // move pins within group - EXPECT_TRUE(m_1->move_pin_within_group(in_group_0, in_pin_1, 0).is_ok()); + EXPECT_TRUE(m_1->move_pin_within_group(in_group_0, in_pin_1, 0)); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group_0, i32(1))); EXPECT_EQ(in_group_0->get_index(in_pin_0).get(), 1); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group_0, i32(0))); @@ -1014,7 +1014,7 @@ namespace hal { EXPECT_EQ(in_group_0->get_pin_at_index(1).get(), in_pin_0); EXPECT_EQ(in_group_0->get_pin_at_index(0).get(), in_pin_1); - EXPECT_TRUE(m_1->move_pin_within_group(in_group_0, in_pin_1, 1).is_ok()); + EXPECT_TRUE(m_1->move_pin_within_group(in_group_0, in_pin_1, 1)); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group_0, i32(0))); EXPECT_EQ(in_group_0->get_index(in_pin_0).get(), 0); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group_0, i32(1))); @@ -1024,20 +1024,20 @@ namespace hal { // remove pin from group EXPECT_TRUE(m_1->set_pin_group_name(in_group_0, "I_tmp")); - EXPECT_TRUE(m_1->remove_pin_from_group(in_group_0, in_pin_0).is_ok()); + EXPECT_TRUE(m_1->remove_pin_from_group(in_group_0, in_pin_0)); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group_0, i32(0))); EXPECT_EQ(in_group_0->get_index(in_pin_1).get(), 0); EXPECT_EQ(in_group_0->get_pin_at_index(0).get(), in_pin_1); EXPECT_EQ(in_pin_0->get_group().first->get_name(), in_pin_0->get_name()); EXPECT_EQ(in_pin_0->get_group().second, 0); - EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, in_pin_0).is_ok()); + EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, in_pin_0)); EXPECT_EQ(in_group_0->size(), 2); // try mixed directions and types EXPECT_TRUE(m_1->set_pin_type(out_pin_0, PinType::address)); EXPECT_TRUE(m_1->set_pin_type(out_pin_1, PinType::data)); - EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, out_pin_0).is_ok()); // wrong direction - EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, out_pin_1).is_ok()); // wrong type + EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, out_pin_0)); // wrong direction + EXPECT_TRUE(m_1->assign_pin_to_group(in_group_0, out_pin_1)); // wrong type EXPECT_EQ(in_group_0->size(), 4); EXPECT_TRUE(m_1->create_pin_group("O1", {out_pin_0, out_pin_1}).is_ok()); // different types EXPECT_TRUE(m_1->create_pin_group("O2", {out_pin_0, in_pin_0}).is_ok()); // different directions @@ -1137,7 +1137,7 @@ namespace hal { EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(1))); // move pins within group - EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 2).is_ok()); + EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 2)); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(1))); EXPECT_EQ(in_group->get_index(in_pin_0).get(), 1); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(2))); @@ -1145,7 +1145,7 @@ namespace hal { EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_0); EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); - EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 1).is_ok()); + EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 1)); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(2))); EXPECT_EQ(in_group->get_index(in_pin_0).get(), 2); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(1))); @@ -1154,17 +1154,17 @@ namespace hal { EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_1); // remove pin from group - EXPECT_TRUE(m_1->remove_pin_from_group(in_group, in_pin_0).is_ok()); + EXPECT_TRUE(m_1->remove_pin_from_group(in_group, in_pin_0)); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(2))); EXPECT_EQ(in_group->get_index(in_pin_1).get(), 2); EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); EXPECT_EQ(in_pin_0->get_group().first->get_name(), in_pin_0->get_name()); EXPECT_EQ(in_pin_0->get_group().second, 0); - EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0).is_ok()); + EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0)); EXPECT_EQ(in_group->size(), 2); // assign pin to group - EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0).is_ok()); + EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0)); EXPECT_EQ(m_1->get_pin_groups().size(), 3); EXPECT_EQ(in_group->size(), 2); EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(1))); @@ -1268,7 +1268,7 @@ namespace hal { // Create the listener for the tested event test_utils::EventListener listener; std::function cb = listener.get_conditional_callback( - [=](ModuleEvent::event ev, Module* m, u32 id){return ev == event_type[event_idx] && m == test_mod;} + [=](ModuleEvent::event ev, Module* m, u32 /*id*/){return ev == event_type[event_idx] && m == test_mod;} ); std::string cb_name = "mod_event_callback_" + std::to_string((u32)event_type[event_idx]); // Register a callback of the listener @@ -1288,7 +1288,7 @@ namespace hal { // -- 'created' event test_utils::EventListener listener_created; std::function cb_created = listener_created.get_conditional_callback( - [=](ModuleEvent::event ev, Module* m, u32 id){return ev == ModuleEvent::event::created;} + [=](ModuleEvent::event ev, Module* /*m*/, u32 /*id*/){return ev == ModuleEvent::event::created;} ); std::string cb_name_created = "mod_event_callback_created"; test_nl->get_event_handler()->register_callback(cb_name_created, cb_created); @@ -1303,7 +1303,7 @@ namespace hal { // -- 'removed' event test_utils::EventListener listener_removed; std::function cb_removed = listener_removed.get_conditional_callback( - [=](ModuleEvent::event ev, Module* m, u32 id){return ev == ModuleEvent::event::removed;} + [=](ModuleEvent::event ev, Module* /*m*/, u32 /*id*/){return ev == ModuleEvent::event::removed;} ); std::string cb_name_removed = "mod_event_callback_removed"; test_nl->get_event_handler()->register_callback(cb_name_removed, cb_removed); From a90e15a458ccfba99dade401f5b002e762fb9869 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 18 Sep 2023 14:37:03 +0200 Subject: [PATCH 12/40] Start handling of parameter for pin_changed core event --- .../netlist/gate_library/enums/pin_type.h | 2 ++ .../module_details_widget/port_tree_model.cpp | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/hal_core/netlist/gate_library/enums/pin_type.h b/include/hal_core/netlist/gate_library/enums/pin_type.h index ec073a7768b..63f468c5834 100644 --- a/include/hal_core/netlist/gate_library/enums/pin_type.h +++ b/include/hal_core/netlist/gate_library/enums/pin_type.h @@ -62,12 +62,14 @@ namespace hal GroupReorder, GroupRename, GroupTypeChange, + GroupDirChange, GroupPinAssign, GroupDelete, PinCreate, PinReorder, PinRename, PinTypeChange, + PinDirChange, PinDelete }; } // namespace hal diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 84e15af7392..67964b67636 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -525,11 +525,17 @@ namespace hal { Q_UNUSED(pev); Q_UNUSED(pgid); - if ((int)m->get_id() == mModuleId) - { - if (!mIgnoreEventsFlag) - setModule(m); - } + if ((int)m->get_id() != mModuleId) return; + + if (!mIgnoreEventsFlag) + setModule(m); + + PortTreeItem* pti = nullptr; + + if (pev < PinEvent::PinCreate) + pti = dynamic_cast(mIdToGroupItem.value(pgid)); + else + pti = dynamic_cast(mIdToPinItem.value(pgid)); } void ModulePinsTreeModel::dndGroupOnGroup(BaseTreeItem *droppedGroup, BaseTreeItem *onDroppedGroup) From b7f9bac67380838482de02057e3d3f39c35babd4 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 20 Sep 2023 21:48:55 +0200 Subject: [PATCH 13/40] Handling of individual pin_changed events in GUI (albeit not fully tested) --- .../netlist/gate_library/enums/pin_type.h | 2 +- .../module_details_widget/port_tree_model.h | 27 +- .../net_details_widget/module_table_model.h | 3 +- .../include/gui/user_action/action_pingroup.h | 2 +- .../module_ports_tree.cpp | 8 +- .../module_details_widget/port_tree_model.cpp | 230 +++++++++++++----- .../net_details_widget/module_table_model.cpp | 4 +- src/netlist/module.cpp | 12 +- 8 files changed, 205 insertions(+), 83 deletions(-) diff --git a/include/hal_core/netlist/gate_library/enums/pin_type.h b/include/hal_core/netlist/gate_library/enums/pin_type.h index 63f468c5834..6f8b660ad07 100644 --- a/include/hal_core/netlist/gate_library/enums/pin_type.h +++ b/include/hal_core/netlist/gate_library/enums/pin_type.h @@ -63,10 +63,10 @@ namespace hal GroupRename, GroupTypeChange, GroupDirChange, - GroupPinAssign, GroupDelete, PinCreate, PinReorder, + PinAssignToGroup, PinRename, PinTypeChange, PinDirChange, diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 45d5b02b91e..938f683caa0 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -28,6 +28,7 @@ //#include "gui/new_selection_details_widget/models/base_tree_model.h" #include "gui/basic_tree_model/base_tree_model.h" #include "hal_core/netlist/gate_library/enums/pin_type.h" +#include "hal_core/netlist/gate_library/enums/pin_direction.h" #include namespace hal @@ -42,24 +43,31 @@ namespace hal enum Type {None, Pin, Group}; private: - Type mType; + Type mItemType; u32 mId; QString mPinName; - QString mPinDirection; - QString mPinType; + PinDirection mPinDirection; + PinType mPinType; QString mNetName; + + void setPinType(const QString& type); + void setPinDirection(const QString& dir); public: - PortTreeItem(Type tp, QString pinName, QString pinDirection, QString pinType, QString netName); - PortTreeItem() : mType(None), mId(0) {;} + PortTreeItem(Type itype, QString pinName, PinDirection dir, PinType ptype, QString netName = QString()); + PortTreeItem() : mItemType(None), mId(0) {;} QVariant getData(int column) const override; void setData(QList data) override; void setDataAtIndex(int index, QVariant& data) override; void appendData(QVariant data) override; int getColumnCount() const override; - void setType(Type tp) { mType = tp; } - Type type() const { return mType; } + void setItemType(Type tp) { mItemType = tp; } + Type itemType() const { return mItemType; } void setId(u32 id_) { mId = id_; } + QString name() const { return mPinName; } + void setName(const QString& nam) { mPinName = nam; } + void setPinType(PinType ptype) { mPinType = ptype; } + void setPinDirection(PinDirection dir) { mPinDirection = dir; } /** * Returns the pin-id if the item represents a pin or the pingroup-id @@ -155,9 +163,8 @@ namespace hal Module* mModule; //name is (hopefully) enough to identify QMap mNameToTreeItem; - QMap mIdToPinItem; - QMap mIdToGroupItem; - bool mIgnoreEventsFlag; + QMap mIdToPinItem; + QMap mIdToGroupItem; void insertItem(PortTreeItem* item, BaseTreeItem* parent, int index); void removeItem(PortTreeItem* item); diff --git a/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h b/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h index a1b6a8cdf31..7749794da7e 100644 --- a/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h +++ b/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h @@ -26,6 +26,7 @@ #pragma once #include "hal_core/defines.h" +#include "hal_core/netlist/gate_library/enums/pin_type.h" #include #include @@ -154,7 +155,7 @@ class ModuleTableModel : public QAbstractTableModel /** @name Event Handler Functions */ ///@{ - void handleModulePortsChanged(Module* m); + void handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid); void handleModuleRemoved(Module* m); ///@} diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 26703e791e6..9c9c075129d 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -46,7 +46,7 @@ namespace hal static bool useExistingPin(Type tp); }; - int pinGroupIndex(const Module* mod, const PinGroup* pgrp); + int pinGroupIndex(const Module* mod, const PinGroup* pgrp); /** * @ingroup user_action diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index 7b2c60d973e..cd605847317 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -140,7 +140,7 @@ namespace hal }); } - if (clickedItem->type() == PortTreeItem::Group) //group specific context, own helper function? (returns at the end) + if (clickedItem->itemType() == PortTreeItem::Group) //group specific context, own helper function? (returns at the end) { menu.addAction("Change name", [name, modId, itemId]() { InputDialog ipd("Change pin group name", "New group name", name); @@ -244,7 +244,7 @@ namespace hal appendMultiSelectionEntries(menu, modId); menu.addSection("Python"); - if(clickedItem->type()==PortTreeItem::Pin) + if(clickedItem->itemType()==PortTreeItem::Pin) menu.addAction(QIcon(":/icons/python"), "Get pin", [modId, itemId]() { QApplication::clipboard()->setText(PyCodeProvider::pyCodeModulePinById(modId, itemId)); }); else menu.addAction(QIcon(":/icons/python"), "Get group", [modId, itemId]() { QApplication::clipboard()->setText(PyCodeProvider::pyCodeModulePinGroup(modId, itemId)); }); @@ -297,7 +297,7 @@ namespace hal for (auto index : selectionModel()->selectedRows()) { PortTreeItem* item = static_cast(mPortModel->getItemFromIndex(index)); - if (item->type() == PortTreeItem::Pin) + if (item->itemType() == PortTreeItem::Pin) { if (!alreadyProcessedPins.contains(item)) { @@ -305,7 +305,7 @@ namespace hal alreadyProcessedPins.insert(item); } } - else if (item->type() == PortTreeItem::Group) + else if (item->itemType() == PortTreeItem::Group) { onlyPins = false; for (auto pinItem : item->getChildren()) diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 67964b67636..edaa73f4917 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -19,38 +19,51 @@ namespace hal { - PortTreeItem::PortTreeItem(Type tp, QString pinName, QString pinDirection, QString pinTypee, QString netName) - : mType(tp), mPinName(pinName), mPinDirection(pinDirection), mPinType(pinTypee), mNetName(netName) + PortTreeItem::PortTreeItem(Type itype, QString pinName, PinDirection dir, PinType ptype, QString netName) + : mItemType(itype), mPinName(pinName), mPinDirection(dir), mPinType(ptype), mNetName(netName) {;} QVariant PortTreeItem::getData(int index) const { switch (index) { - case 0: { - QVariant qvPinName = QVariant(mPinName); - return qvPinName; - break;} - case 1: { - QVariant qvPinDirection = QVariant(mPinDirection); - return qvPinDirection; - break;} - case 2: { - QVariant qvPinType = QVariant(mPinType); - return qvPinType; - break;} - case 3: { - QVariant qvNetName = QVariant(mNetName); - return qvNetName; - break;} + case 0: + return mPinName; + case 1: + return QString::fromStdString(enum_to_string(mPinDirection)); + case 2: + return QString::fromStdString(enum_to_string(mPinType)); + case 3: + return mNetName; + } + return QVariant(); + } + + void PortTreeItem::setPinType(const QString& type) + { + mPinType = PinType::none; + for (int pt = 1; pt < (int) PinType::sum; ++pt) + { + if (QString::fromStdString(enum_to_string((PinType)pt)) == type) + mPinType = (PinType)pt; + } + } + + void PortTreeItem::setPinDirection(const QString& dir) + { + mPinDirection = PinDirection::none; + for (int pd = 1; pd <= (int) PinDirection::internal; ++pd) + { + if (QString::fromStdString(enum_to_string((PinDirection)pd)) == dir) + mPinDirection = (PinDirection)pd; } } void PortTreeItem::setData(QList data) { mPinName = data[0].toString(); - mPinDirection = data[1].toString(); - mPinType = data[2].toString(); + setPinDirection(data[1].toString()); + setPinType(data[2].toString()); mNetName = data[3].toString(); } @@ -62,10 +75,10 @@ namespace hal mPinName = data.toString(); break;} case 1: { - mPinDirection = data.toString(); + setPinDirection(data.toString()); break;} case 2: { - mPinType = data.toString(); + setPinType(data.toString()); break;} case 3: { mNetName = data.toString(); @@ -75,7 +88,7 @@ namespace hal void PortTreeItem::appendData(QVariant data) { - + Q_UNUSED(data) } int PortTreeItem::getColumnCount() const @@ -83,7 +96,7 @@ namespace hal return 4; } - ModulePinsTreeModel::ModulePinsTreeModel(QObject* parent) : BaseTreeModel(parent), mIgnoreEventsFlag(false) + ModulePinsTreeModel::ModulePinsTreeModel(QObject* parent) : BaseTreeModel(parent) { setHeaderLabels(QStringList() << "Name" << "Direction" @@ -146,7 +159,7 @@ namespace hal PortTreeItem* item = static_cast(getItemFromIndex(indexes.at(0))); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); - QString type = item->type() == PortTreeItem::Pin ? "pin" : "group"; + QString type = item->itemType() == PortTreeItem::Pin ? "pin" : "group"; stream << type << item->id(); data->setText(item->getData(sNameColumn).toString()); data->setData("pintreemodel/item", encodedData); @@ -249,7 +262,6 @@ namespace hal // return false; // removeItem(droppedItem); -// mIgnoreEventsFlag = true; // if (bottomEdge) // { // insertItem(newItem, droppedParentItem, row - 1); @@ -272,7 +284,6 @@ namespace hal // reorderObj->setParentObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); // reorderObj->exec(); // } -// mIgnoreEventsFlag = false; // return true; // } @@ -284,7 +295,6 @@ namespace hal // if (pinGroup == nullptr) // return false; -// mIgnoreEventsFlag = true; // UserActionCompound* comp = new UserActionCompound; // if (droppedParentItem != mRootItem && onDroppedParentItem != mRootItem) @@ -304,7 +314,6 @@ namespace hal // comp->addAction(addAct); // comp->addAction(reordAct); // bool ret = comp->exec(); -// mIgnoreEventsFlag = false; // if (ret) // { // removeItem(droppedItem); @@ -324,7 +333,6 @@ namespace hal // //if(droppedParentItem == mRootItem)//item which is dropped // if (droppedParentItem != onDroppedItem) // { -// mIgnoreEventsFlag = true; // //bool ret = mod->assign_pin_to_group(onDroppedGroup, droppedPin); // ActionAddItemsToObject* addAct = new ActionAddItemsToObject(QSet(), QSet(), QSet(), QSet() << droppedPin->get_id()); // addAct->setObject(UserActionObject(onDroppedGroup->get_id(), UserActionObjectType::PinGroup)); @@ -334,10 +342,8 @@ namespace hal // { // removeItem(droppedItem); // insertItem(newItem, onDroppedItem, onDroppedItem->getChildCount()); -// mIgnoreEventsFlag = false; // return true; // } -// mIgnoreEventsFlag = false; // return false; // } // } @@ -367,7 +373,7 @@ namespace hal auto item = static_cast(mIdToGroupItem[id]); if(parentItem) { - if(item->type() == PortTreeItem::Pin || (item->type() == PortTreeItem::Group && row != -1) || item == parentItem) + if(item->itemType() == PortTreeItem::Pin || (item->itemType() == PortTreeItem::Group && row != -1) || item == parentItem) return false; } else // here, only check for adjacent rows @@ -383,7 +389,7 @@ namespace hal // otherwise it does not make much sense...perhaps change this check auto item = mIdToPinItem[id]; if((!parentItem && item->getParent()->getChildCount() == 1) || (item->getParent() == parentItem && row == -1) || item == parentItem - || (parentItem && (parentItem->type() == PortTreeItem::Pin))) + || (parentItem && (parentItem->itemType() == PortTreeItem::Pin))) return false; // case if one wants to drop between pins in same group, check if its not adjacent row (other cases are handled on case above if(item->getParent() == parentItem) @@ -419,18 +425,15 @@ namespace hal continue; auto pinGroupName = QString::fromStdString(pinGroup->get_name()); - auto pinGroupDirection = QString::fromStdString(enum_to_string((pinGroup->get_direction()))); - auto pinGroupType = QString::fromStdString(enum_to_string(pinGroup->get_type())); - - PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group,pinGroupName, pinGroupDirection, pinGroupType, ""); + PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group,pinGroupName, pinGroup->get_direction(), pinGroup->get_type()); pinGroupItem->setId(pinGroup->get_id()); mIdToGroupItem.insert(pinGroup->get_id(), pinGroupItem); for(ModulePin* pin : pinGroup->get_pins()) { PortTreeItem* pinItem = new PortTreeItem(PortTreeItem::Pin, QString::fromStdString(pin->get_name()), - QString::fromStdString(enum_to_string(pin->get_direction())), - QString::fromStdString(enum_to_string(pin->get_type())), + pin->get_direction(), + pin->get_type(), QString::fromStdString(pin->get_net()->get_name())); pinItem->setId(pin->get_id()); pinGroupItem->appendChild(pinItem); @@ -500,7 +503,7 @@ namespace hal if (mModuleId == -1) //no current module = no represented net return nullptr; - if (item->type() == PortTreeItem::Group && item->getChildCount() > 1) + if (item->itemType() == PortTreeItem::Group && item->getChildCount() > 1) return nullptr; Module* m = gNetlist->get_module_by_id(mModuleId); @@ -527,15 +530,129 @@ namespace hal Q_UNUSED(pgid); if ((int)m->get_id() != mModuleId) return; - if (!mIgnoreEventsFlag) - setModule(m); - - PortTreeItem* pti = nullptr; + PortTreeItem* ptiPin = nullptr; + PortTreeItem* ptiGroup = nullptr; + const PinGroup* pgroup = nullptr; + const ModulePin* pin = nullptr; + int pinRow = -1; if (pev < PinEvent::PinCreate) - pti = dynamic_cast(mIdToGroupItem.value(pgid)); + { + // group event + ptiGroup = mIdToGroupItem.value(pgid); + pgroup = m->get_pin_group_by_id(pgid); + if (!pgroup) + { + log_warning("gui", "Cannot handle event for pin group ID={}, no such group.", pgid); + return; + } + } else - pti = dynamic_cast(mIdToPinItem.value(pgid)); + { + // pin event + ptiPin = mIdToPinItem.value(pgid); + pin = m->get_pin_by_id(pgid); + if (!pin) + { + log_warning("gui", "Cannot handle event for pin ID={}, no such pid.", pgid); + return; + } + auto pgPair = pin->get_group(); + pgroup = pgPair.first; + pinRow = pgPair.second; + if (pgroup) + ptiGroup = mIdToGroupItem.value(pgroup->get_id()); + } + + switch (pev) + { + case PinEvent::GroupCreate: + { + ptiGroup = new PortTreeItem(PortTreeItem::Group, + QString::fromStdString(pgroup->get_name()), + pgroup->get_direction(), + pgroup->get_type()); + int inx = pinGroupIndex(m,pgroup); + insertItem(ptiGroup, mRootItem, inx); + break; + } + case PinEvent::GroupReorder: + { + int inx = pinGroupIndex(m,pgroup); + removeItem(ptiGroup); + insertItem(ptiGroup, mRootItem, inx); + break; + } + case PinEvent::GroupRename: + ptiGroup->setName(QString::fromStdString(pgroup->get_name())); + break; + case PinEvent::GroupTypeChange: + ptiGroup->setPinType(pgroup->get_type()); + break; + case PinEvent::GroupDirChange: + ptiGroup->setPinDirection(pgroup->get_direction()); + break; + case PinEvent::GroupDelete: + removeItem(ptiGroup); + delete ptiGroup; + break; + case PinEvent::PinCreate: + { + if (!pgroup || !ptiGroup) + { + log_warning("gui", "Cannot handle pin create event for pin ID={}, pin is not assigned to any group.", pgid); + return; + } + QString netName; + if (pin->get_net()) + netName = QString::fromStdString(pin->get_net()->get_name()); + ptiPin = new PortTreeItem(PortTreeItem::Pin, + QString::fromStdString(pin->get_name()), + pin->get_direction(), + pin->get_type(), + netName); + + insertItem(ptiPin, ptiGroup, pinRow); + break; + } + case PinEvent::PinReorder: + { + if (!pgroup || !ptiGroup) + { + log_warning("gui", "Cannot handle pin reorder event for pin ID={}, pin is not assigned to any group.", pgid); + return; + } + removeItem(ptiPin); + insertItem(ptiPin, ptiGroup, pinRow); + break; + } + case PinEvent::PinAssignToGroup: + { + if (!pgroup || !ptiGroup) + { + log_warning("gui", "Cannot handle pin assign event for pin ID={}, pin is not assigned to any group.", pgid); + return; + } + removeItem(ptiPin); + insertItem(ptiPin, ptiGroup, pinRow); + break; + } + case PinEvent::PinRename: + ptiPin->setName(QString::fromStdString(pin->get_name())); + break; + case PinEvent::PinTypeChange: + ptiPin->setPinType(pin->get_type()); + break; + case PinEvent::PinDirChange: + ptiPin->setPinDirection(pin->get_direction()); + break; + case PinEvent::PinDelete: + removeItem(ptiPin); + delete ptiPin; + break; + default: + break; + } } void ModulePinsTreeModel::dndGroupOnGroup(BaseTreeItem *droppedGroup, BaseTreeItem *onDroppedGroup) @@ -544,7 +661,6 @@ namespace hal // 2) just add all pins from dropped group to "ondroppedgroup", then rename? // InputDialog ipd("Name of new group", "Name of new group:", onDroppedGroup->getData(sNameColumn).toString()); // if(ipd.exec() == QDialog::Rejected) return false; - mIgnoreEventsFlag = true; QList pins; auto srcgroup = mModule->get_pin_group_by_id(static_cast(droppedGroup)->id()); for(const auto &pin : srcgroup->get_pins()) @@ -558,14 +674,10 @@ namespace hal // too keep the order, ActionAddItemsToObject cannot be executed with all pins, but a ComAction must be created // with many ActionAddItemsToObject that contain a single pin each -> set destroys order of pins in source pingroup - setModule(mModule); - mIgnoreEventsFlag = false; - } void ModulePinsTreeModel::dndGroupBetweenGroup(PortTreeItem *droppedGroup, int row) { - mIgnoreEventsFlag = true; int ownRow = droppedGroup->getOwnRow(); bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; @@ -577,13 +689,10 @@ namespace hal removeItem(droppedGroup); insertItem(droppedGroup, mRootItem, desiredIdx); } - mIgnoreEventsFlag = false; } void ModulePinsTreeModel::dndPinOnGroup(PortTreeItem *droppedPin, BaseTreeItem *onDroppedGroup) { - mIgnoreEventsFlag = true; - ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); act->exec(); auto oldParent = droppedPin->getParent(); @@ -593,13 +702,10 @@ namespace hal removeItem(static_cast(oldParent)); delete oldParent; } - //setModule(mModule); - mIgnoreEventsFlag = false; } void ModulePinsTreeModel::dndPinBetweenPin(PortTreeItem *droppedPin, BaseTreeItem *onDroppedParent, int row) { - mIgnoreEventsFlag = true; int desiredIdx = row; ActionPingroup* act = nullptr; if(droppedPin->getParent() == onDroppedParent) // same group @@ -624,15 +730,12 @@ namespace hal removeItem(static_cast(oldParent)); delete oldParent; } - //setModule(mModule); - mIgnoreEventsFlag = false; } void ModulePinsTreeModel::dndPinBetweenGroup(PortTreeItem *droppedPin, int row) { // row is needed for when groups can change its order within the module Q_UNUSED(row) - mIgnoreEventsFlag = true; auto pinToMove = mModule->get_pin_by_id(droppedPin->id()); if (!pinToMove) return; @@ -670,7 +773,6 @@ namespace hal insertItem(droppedPin, pinGroupItem, 0); } */ - mIgnoreEventsFlag = false; } void ModulePinsTreeModel::insertItem(PortTreeItem* item, BaseTreeItem* parent, int index) @@ -680,7 +782,7 @@ namespace hal parent->insertChild(index, item); endInsertRows(); //mNameToTreeItem.insert(item->getData(sNameColumn).toString(), item); - item->type() == PortTreeItem::Pin ? mIdToPinItem.insert(item->id(), item) : mIdToGroupItem.insert(item->id(), item); + item->itemType() == PortTreeItem::Pin ? mIdToPinItem.insert(item->id(), item) : mIdToGroupItem.insert(item->id(), item); //mIdToPinItem.insert(getIdOfItem(item), item); } void ModulePinsTreeModel::removeItem(PortTreeItem* item) @@ -690,7 +792,7 @@ namespace hal endRemoveRows(); //mNameToTreeItem.remove(item->getData(sNameColumn).toString()); //for now, only ids of pin-items (since these functions are only relevant for dnd) - item->type() == PortTreeItem::Pin ? mIdToPinItem.remove(item->id()) : mIdToGroupItem.remove(item->id()); + item->itemType() == PortTreeItem::Pin ? mIdToPinItem.remove(item->id()) : mIdToGroupItem.remove(item->id()); //mIdToPinItem.remove(getIdOfItem(item)); //delete item; } diff --git a/plugins/gui/src/selection_details_widget/net_details_widget/module_table_model.cpp b/plugins/gui/src/selection_details_widget/net_details_widget/module_table_model.cpp index 1dccb1bdf49..4bdebadb2bf 100644 --- a/plugins/gui/src/selection_details_widget/net_details_widget/module_table_model.cpp +++ b/plugins/gui/src/selection_details_widget/net_details_widget/module_table_model.cpp @@ -178,8 +178,10 @@ namespace hal return mEntries[index.row()].name; } - void ModuleTableModel::handleModulePortsChanged(Module* m) + void ModuleTableModel::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { + Q_UNUSED(pev); + Q_UNUSED(pgid); if (mModIds.find((int)m->get_id()) != mModIds.end()) { Net* net = gNetlist->get_net_by_id(mNetId); diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 435f4856423..f65fd5d8c54 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -1357,6 +1357,8 @@ namespace hal bool Module::assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) { + u32 pin_group_id_to_delete = 0; + if (pin_group == nullptr) { log_warning("module", "could not assign pin to pin group of module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); @@ -1397,6 +1399,7 @@ namespace hal if (delete_empty_groups && pg->empty()) { + pin_group_id_to_delete = pin_group->get_id(); if (!delete_pin_group_internal(pg)) { log_warning("module", @@ -1414,7 +1417,9 @@ namespace hal return false; } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupPinAssign,pin_group->get_id())); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinAssignToGroup,pin->get_id())); + if (pin_group_id_to_delete) + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); return true;; } @@ -1558,6 +1563,7 @@ namespace hal bool Module::remove_pin_net(Net* net) { + u32 pin_group_id_to_delete = 0; auto pin = get_pin_by_net(net); if (pin == nullptr) { @@ -1576,6 +1582,7 @@ namespace hal if (pin_group->empty()) { + pin_group_id_to_delete = pin_group->get_id(); if (!delete_pin_group_internal(pin_group)) { log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin_group->get_name(), pin_group->get_id()); @@ -1587,11 +1594,14 @@ namespace hal if (!delete_pin_internal(pin)) { + log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin->get_name(), pin->get_id()); return false; } m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinDelete,pin_id_to_delete)); + if (pin_group_id_to_delete) + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); return true; } From 9abb832ce08be4bd798966600c42e86041e96335 Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 22 Sep 2023 11:24:10 +0200 Subject: [PATCH 14/40] Errors in pin_changed event handling fixed --- .../netlist/gate_library/enums/pin_type.h | 3 + .../module_details_widget/port_tree_model.h | 2 - .../module_details_widget/port_tree_model.cpp | 102 ++++++++---------- src/netlist/gate_library/enums/pin_type.cpp | 20 +++- src/netlist/module.cpp | 18 ++-- 5 files changed, 74 insertions(+), 71 deletions(-) diff --git a/include/hal_core/netlist/gate_library/enums/pin_type.h b/include/hal_core/netlist/gate_library/enums/pin_type.h index 6f8b660ad07..9f595c660ad 100644 --- a/include/hal_core/netlist/gate_library/enums/pin_type.h +++ b/include/hal_core/netlist/gate_library/enums/pin_type.h @@ -72,4 +72,7 @@ namespace hal PinDirChange, PinDelete }; + + template<> + std::map EnumStrings::data; } // namespace hal diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 938f683caa0..52604b5dd51 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -50,8 +50,6 @@ namespace hal PinType mPinType; QString mNetName; - void setPinType(const QString& type); - void setPinDirection(const QString& dir); public: PortTreeItem(Type itype, QString pinName, PinDirection dir, PinType ptype, QString netName = QString()); diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index edaa73f4917..4263aea1c22 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -39,32 +39,12 @@ namespace hal return QVariant(); } - void PortTreeItem::setPinType(const QString& type) - { - mPinType = PinType::none; - for (int pt = 1; pt < (int) PinType::sum; ++pt) - { - if (QString::fromStdString(enum_to_string((PinType)pt)) == type) - mPinType = (PinType)pt; - } - } - - void PortTreeItem::setPinDirection(const QString& dir) - { - mPinDirection = PinDirection::none; - for (int pd = 1; pd <= (int) PinDirection::internal; ++pd) - { - if (QString::fromStdString(enum_to_string((PinDirection)pd)) == dir) - mPinDirection = (PinDirection)pd; - } - } - void PortTreeItem::setData(QList data) { - mPinName = data[0].toString(); - setPinDirection(data[1].toString()); - setPinType(data[2].toString()); - mNetName = data[3].toString(); + mPinName = data[0].toString(); + mPinDirection = enum_from_string(data[1].toString().toStdString()); + mPinType = enum_from_string(data[2].toString().toStdString()); + mNetName = data[3].toString(); } void PortTreeItem::setDataAtIndex(int index, QVariant &data) @@ -75,10 +55,10 @@ namespace hal mPinName = data.toString(); break;} case 1: { - setPinDirection(data.toString()); + mPinDirection = enum_from_string(data.toString().toStdString()); break;} case 2: { - setPinType(data.toString()); + mPinType = enum_from_string(data.toString().toStdString()); break;} case 3: { mNetName = data.toString(); @@ -361,7 +341,7 @@ namespace hal QDataStream dataStream(&encItem, QIODevice::ReadOnly); dataStream >> type >> id; auto parentItem = static_cast(getItemFromIndex(parent)); - qDebug() << "type: " << type << ", id" << id << ", row: " << row; + // qDebug() << "type: " << type << ", id" << id << ", row: " << row; // construct a "drop-matrix" here, but only 4(5) things are NOT allowed (so check for these): // 1: drop a pin on its OWN parent @@ -530,40 +510,50 @@ namespace hal Q_UNUSED(pgid); if ((int)m->get_id() != mModuleId) return; + log_info("gui", "Handle pin_changed event {} ID={}", enum_to_string(pev), pgid); PortTreeItem* ptiPin = nullptr; PortTreeItem* ptiGroup = nullptr; const PinGroup* pgroup = nullptr; const ModulePin* pin = nullptr; int pinRow = -1; + if (pev < PinEvent::PinCreate) { // group event ptiGroup = mIdToGroupItem.value(pgid); - pgroup = m->get_pin_group_by_id(pgid); - if (!pgroup) + if (pev != PinEvent::GroupDelete) { - log_warning("gui", "Cannot handle event for pin group ID={}, no such group.", pgid); - return; + pgroup = m->get_pin_group_by_id(pgid); + if (!pgroup) + { + log_warning("gui", "Cannot handle event for pin group ID={}, no such group.", pgid); + return; + } } } else { // pin event ptiPin = mIdToPinItem.value(pgid); - pin = m->get_pin_by_id(pgid); - if (!pin) + if (pev != PinEvent::PinDelete) { - log_warning("gui", "Cannot handle event for pin ID={}, no such pid.", pgid); - return; + pin = m->get_pin_by_id(pgid); + if (!pin) + { + log_warning("gui", "Cannot handle event for pin ID={}, no such pid.", pgid); + return; + } + auto pgPair = pin->get_group(); + pgroup = pgPair.first; + pinRow = pgPair.second; + if (pgroup) + ptiGroup = mIdToGroupItem.value(pgroup->get_id()); } - auto pgPair = pin->get_group(); - pgroup = pgPair.first; - pinRow = pgPair.second; - if (pgroup) - ptiGroup = mIdToGroupItem.value(pgroup->get_id()); } + QModelIndex dataChangedIndex; + switch (pev) { case PinEvent::GroupCreate: @@ -585,12 +575,15 @@ namespace hal } case PinEvent::GroupRename: ptiGroup->setName(QString::fromStdString(pgroup->get_name())); + dataChangedIndex = getIndexFromItem(ptiGroup); break; case PinEvent::GroupTypeChange: ptiGroup->setPinType(pgroup->get_type()); + dataChangedIndex = getIndexFromItem(ptiGroup); break; case PinEvent::GroupDirChange: ptiGroup->setPinDirection(pgroup->get_direction()); + dataChangedIndex = getIndexFromItem(ptiGroup); break; case PinEvent::GroupDelete: removeItem(ptiGroup); @@ -639,12 +632,15 @@ namespace hal } case PinEvent::PinRename: ptiPin->setName(QString::fromStdString(pin->get_name())); + dataChangedIndex = getIndexFromItem(ptiPin); break; case PinEvent::PinTypeChange: ptiPin->setPinType(pin->get_type()); + dataChangedIndex = getIndexFromItem(ptiPin); break; case PinEvent::PinDirChange: ptiPin->setPinDirection(pin->get_direction()); + dataChangedIndex = getIndexFromItem(ptiPin); break; case PinEvent::PinDelete: removeItem(ptiPin); @@ -653,6 +649,12 @@ namespace hal default: break; } + + if (dataChangedIndex.isValid()) + { + QModelIndex inxLastCol = createIndex(dataChangedIndex.row(),columnCount()-1,dataChangedIndex.internalPointer()); + Q_EMIT dataChanged(dataChangedIndex,inxLastCol); + } } void ModulePinsTreeModel::dndGroupOnGroup(BaseTreeItem *droppedGroup, BaseTreeItem *onDroppedGroup) @@ -684,24 +686,13 @@ namespace hal if(ownRow < row && !bottomEdge) desiredIdx--; ActionPingroup* act = new ActionPingroup(PinActionType::GroupMove,droppedGroup->id(),"",desiredIdx); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); - bool ok = act->exec(); - if(ok){ - removeItem(droppedGroup); - insertItem(droppedGroup, mRootItem, desiredIdx); - } + act->exec(); } void ModulePinsTreeModel::dndPinOnGroup(PortTreeItem *droppedPin, BaseTreeItem *onDroppedGroup) { ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); act->exec(); - auto oldParent = droppedPin->getParent(); - removeItem(droppedPin); - insertItem(droppedPin, onDroppedGroup, onDroppedGroup->getChildCount()); - if(!(oldParent->getChildCount())){ - removeItem(static_cast(oldParent)); - delete oldParent; - } } void ModulePinsTreeModel::dndPinBetweenPin(PortTreeItem *droppedPin, BaseTreeItem *onDroppedParent, int row) @@ -723,13 +714,6 @@ namespace hal } act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); act->exec(); - auto oldParent = droppedPin->getParent(); - removeItem(droppedPin); - insertItem(droppedPin, onDroppedParent, desiredIdx); - if(!(oldParent->getChildCount())){ - removeItem(static_cast(oldParent)); - delete oldParent; - } } void ModulePinsTreeModel::dndPinBetweenGroup(PortTreeItem *droppedPin, int row) diff --git a/src/netlist/gate_library/enums/pin_type.cpp b/src/netlist/gate_library/enums/pin_type.cpp index e39bee1b366..b9e9c01a296 100644 --- a/src/netlist/gate_library/enums/pin_type.cpp +++ b/src/netlist/gate_library/enums/pin_type.cpp @@ -19,4 +19,22 @@ namespace hal {PinType::select, "select"}, {PinType::carry, "carry"}, {PinType::sum, "sum"}}; -} \ No newline at end of file + + template<> + std::map EnumStrings::data = { + {PinEvent::unknown, "unknown"}, + {PinEvent::GroupCreate, "GroupCreate"}, + {PinEvent::GroupReorder, "GroupReorder"}, + {PinEvent::GroupRename, "GroupRename"}, + {PinEvent::GroupTypeChange, "GroupTypeChange"}, + {PinEvent::GroupDirChange, "GroupDirChange"}, + {PinEvent::GroupDelete, "GroupDelete"}, + {PinEvent::PinCreate, "PinCreate"}, + {PinEvent::PinReorder, "PinReorder"}, + {PinEvent::PinAssignToGroup, "PinAssignToGroup"}, + {PinEvent::PinRename, "PinRename"}, + {PinEvent::PinTypeChange, "PinTypeChange"}, + {PinEvent::PinDirChange, "PinDirChange"}, + {PinEvent::PinDelete, "PinDelete"} + }; +} diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index f65fd5d8c54..5c9fc41aedd 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -1272,6 +1272,7 @@ namespace hal bool Module::delete_pin_group(PinGroup* pin_group) { + std::vector distribute_events; if (pin_group == nullptr) { log_warning("module", "could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); @@ -1286,16 +1287,16 @@ namespace hal return false; } - bool removed_pins = false; - std::vector pins_copy = pin_group->get_pins(); for (ModulePin* pin : pins_copy) { - removed_pins = true; - if (auto res = create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, false); res.is_error()) + auto res = create_pin_group(pin->get_name(), {pin}, pin->get_direction(), pin->get_type(), true, 0, false); + if (res.is_error()) { return false; } + distribute_events.push_back(pinevent_associated_data(PinEvent::GroupCreate,res.get()->get_id())); + distribute_events.push_back(pinevent_associated_data(PinEvent::PinAssignToGroup,pin->get_id())); } u32 pin_group_id_to_delete = pin_group->get_id(); @@ -1305,10 +1306,9 @@ namespace hal return false; } - if (removed_pins) - { - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); - } + for (u32 dist_ev : distribute_events) + m_event_handler->notify(ModuleEvent::event::pin_changed, this, dist_ev); + m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); return true; } @@ -1399,7 +1399,7 @@ namespace hal if (delete_empty_groups && pg->empty()) { - pin_group_id_to_delete = pin_group->get_id(); + pin_group_id_to_delete = pg->get_id(); if (!delete_pin_group_internal(pg)) { log_warning("module", From 7c49225ddbc4e893b783d39e32244777c598ce78 Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 26 Sep 2023 22:28:54 +0200 Subject: [PATCH 15/40] Modified assign behaviour on descending pin groups --- include/hal_core/netlist/pins/base_pin.h | 13 +++++++++- include/hal_core/netlist/pins/pin_group.h | 26 ++++++++++++++----- .../include/gui/user_action/action_pingroup.h | 1 + .../gui/src/user_action/action_pingroup.cpp | 24 +++++++++++++++++ .../netlist_modification_decorator.cpp | 2 +- src/netlist/gate_library/gate_type.cpp | 5 ++-- src/netlist/module.cpp | 11 ++++---- 7 files changed, 64 insertions(+), 18 deletions(-) diff --git a/include/hal_core/netlist/pins/base_pin.h b/include/hal_core/netlist/pins/base_pin.h index 79629f2c34c..b168aeb1655 100644 --- a/include/hal_core/netlist/pins/base_pin.h +++ b/include/hal_core/netlist/pins/base_pin.h @@ -100,6 +100,17 @@ namespace hal m_name = name; } + int get_pos() const + { + auto g = get_group(); + int i = 0; + for (auto p : g.first->get_pins()) + { + if (p == this) return i; + ++i; + } + return -1; + } /** * Get the name of the pin. * @@ -187,4 +198,4 @@ namespace hal { } }; -} // namespace hal \ No newline at end of file +} // namespace hal diff --git a/include/hal_core/netlist/pins/pin_group.h b/include/hal_core/netlist/pins/pin_group.h index b036ab682d1..649467672f3 100644 --- a/include/hal_core/netlist/pins/pin_group.h +++ b/include/hal_core/netlist/pins/pin_group.h @@ -27,6 +27,7 @@ #include "hal_core/defines.h" #include "hal_core/utilities/result.h" +#include "hal_core/utilities/log.h" #include #include @@ -312,19 +313,30 @@ namespace hal * Assign a pin to the pin group. * * @param[in] pin - The pin to assign. - * @returns Ok on success, an error message otherwise. + * @returns true on success, false otherwise. */ - Result assign_pin(T* pin) + bool assign_pin(T* pin) { if (pin == nullptr) { - return ERR("'nullptr' given instead of a pin when trying to assign a pin to pin group '" + m_name + "' with ID " + std::to_string(m_id)); + log_warning("pin_group", "'nullptr' given instead of a pin when trying to assign a pin to pin group '{}' with ID {}", + m_name, m_id); + return false; } - i32 index = m_ascending ? m_next_index++ : m_next_index--; - m_pins.push_back(pin); + i32 index = 0; + if (m_ascending) + { + index = m_next_index++; + m_pins.push_back(pin); + } + else + { + index = ++m_start_index; + m_pins.push_front(pin); + } pin->m_group = std::make_pair(this, index); - return OK({}); + return true; } /** @@ -481,4 +493,4 @@ namespace hal PinGroup& operator=(const PinGroup&) = delete; PinGroup& operator=(PinGroup&&) = delete; }; -} // namespace hal \ No newline at end of file +} // namespace hal diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 9c9c075129d..37fedce3b16 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -48,6 +48,7 @@ namespace hal int pinGroupIndex(const Module* mod, const PinGroup* pgrp); + void dumpPingroups(Module* m = nullptr); /** * @ingroup user_action * @brief Pingroup user actions diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index a59affc1332..80526654db7 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -19,6 +19,22 @@ namespace hal return -1; } + void dumpPingroups(Module *m) + { + if (!m) m = gNetlist->get_top_module(); + std::cerr << "module: " << m->get_id() << " <" << m->get_name() << ">\n"; + for (PinGroup* pg : m->get_pin_groups()) + { + std::cerr << " grp: " << pg->get_id() << (pg->is_ascending()?" asc ": " des ") << pg->get_start_index() + << " <" << pg->get_name() << ">\n"; + for (ModulePin* pin : pg->get_pins()) + std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " pos:" << pin->get_pos() << " <" << pin->get_name() << ">\n"; + } + std::cerr << "-------------" << std::endl; + for (Module* sm : m->get_submodules()) + dumpPingroups(sm); + } + QString PinActionType::toString(PinActionType::Type tp) { QMetaEnum me = QMetaEnum::fromType(); @@ -342,7 +358,11 @@ namespace hal pgroup = getGroup(aa.mValue); if (!pgroup) return false; if (!mParentModule->assign_pin_to_group(pgroup,pin)) + { + qDebug() << "assign_pin_to_group failed"; return false; + } + dumpPingroups(); break; case PinActionType::PinRename: addUndoAction(PinActionType::PinRename,aa.mId, QString::fromStdString(pin->get_name())); @@ -359,7 +379,11 @@ namespace hal addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); pgroup = pin->get_group().first; if (!mParentModule->move_pin_within_group(pgroup,pin,aa.mValue)) + { + qDebug() << "move_pin_within_group failed"; return false; + } + dumpPingroups(); break; default: break; diff --git a/src/netlist/decorators/netlist_modification_decorator.cpp b/src/netlist/decorators/netlist_modification_decorator.cpp index 1b37bd13f17..73bd446de32 100644 --- a/src/netlist/decorators/netlist_modification_decorator.cpp +++ b/src/netlist/decorators/netlist_modification_decorator.cpp @@ -326,7 +326,7 @@ namespace hal pin_group = pin_groups.front(); } - pin_group->assign_pin(pin).get(); + pin_group->assign_pin(pin); if (const auto res = pin_group->move_pin(pin, pin_index); res.is_error()) { return ERR_APPEND(res.get_error(), diff --git a/src/netlist/gate_library/gate_type.cpp b/src/netlist/gate_library/gate_type.cpp index c8e2d2672ff..3a4050ed2f4 100644 --- a/src/netlist/gate_library/gate_type.cpp +++ b/src/netlist/gate_library/gate_type.cpp @@ -507,10 +507,9 @@ namespace hal } } - if (auto res = pin_group->assign_pin(pin); res.is_error()) + if (!pin_group->assign_pin(pin)) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + return ERR("could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of gate type '" + m_name + "' with ID " + std::to_string(m_id)); } diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 5c9fc41aedd..af1e0a16e23 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -842,12 +842,11 @@ namespace hal else { // create_pin_group_internal OK - if (const auto assign_res = group_res.get()->assign_pin(pin_res.get()); assign_res.is_error()) + if (!group_res.get()->assign_pin(pin_res.get())) { assert(delete_pin_internal(pin_res.get())); assert(delete_pin_group_internal(group_res.get())); - return ERR_APPEND(assign_res.get_error(), - "could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to assign pin to pin group"); + return ERR("could not create pin '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id) + ": failed to assign pin to pin group"); } else { @@ -1410,7 +1409,7 @@ namespace hal } } - if (auto res = pin_group->assign_pin(pin); res.is_error()) + if (!pin_group->assign_pin(pin)) { log_warning("module", "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}", pin->get_name(), pin->get_id(), pin_group->get_name(), pin_group->get_id(), m_name, m_id); @@ -1551,9 +1550,9 @@ namespace hal } else { - if (const auto assign_res = group_res.get()->assign_pin(pin); assign_res.is_error()) + if (!group_res.get()->assign_pin(pin)) { - return ERR_APPEND(assign_res.get_error(), "could not assign pin '" + name_internal + "' to net: failed to assign pin to pin group"); + return ERR("could not assign pin '" + name_internal + "' to net: failed to assign pin to pin group"); } } From 05890be0c1ff5f0a2a835e8e4e396dab2b05beb5 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 28 Sep 2023 21:09:56 +0200 Subject: [PATCH 16/40] All pin_changed functions except dndPinBetweenGroup implemented and tested --- include/hal_core/netlist/pins/pin_group.h | 11 +++++++- .../include/gui/user_action/action_pingroup.h | 4 +++ .../module_details_widget/port_tree_model.cpp | 4 ++- .../gui/src/user_action/action_pingroup.cpp | 25 ++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/include/hal_core/netlist/pins/pin_group.h b/include/hal_core/netlist/pins/pin_group.h index 649467672f3..2e125ff46b9 100644 --- a/include/hal_core/netlist/pins/pin_group.h +++ b/include/hal_core/netlist/pins/pin_group.h @@ -332,7 +332,16 @@ namespace hal } else { - index = ++m_start_index; + if (m_start_index == m_next_index) + { + // special case empty pin group + index = m_start_index; + -- m_next_index; + } + else + { + index = ++m_start_index; + } m_pins.push_front(pin); } pin->m_group = std::make_pair(this, index); diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 37fedce3b16..d1562ff4ed7 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -48,6 +48,10 @@ namespace hal int pinGroupIndex(const Module* mod, const PinGroup* pgrp); + int pinIndex2Row(const ModulePin* pin, int index); + + int pinRow2Index(const ModulePin* pin, int row); + void dumpPingroups(Module* m = nullptr); /** * @ingroup user_action diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 4263aea1c22..b0ceed5effe 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -546,7 +546,7 @@ namespace hal } auto pgPair = pin->get_group(); pgroup = pgPair.first; - pinRow = pgPair.second; + pinRow = pinIndex2Row(pin,pgPair.second); if (pgroup) ptiGroup = mIdToGroupItem.value(pgroup->get_id()); } @@ -672,6 +672,7 @@ namespace hal auto tgtgroup = mModule->get_pin_group_by_id(static_cast(onDroppedGroup)->id()); ActionPingroup* act = ActionPingroup::addPinsToExistingGroup(mModule,tgtgroup->get_id(),pins); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); if (act) act->exec(); // too keep the order, ActionAddItemsToObject cannot be executed with all pins, but a ComAction must be created @@ -692,6 +693,7 @@ namespace hal void ModulePinsTreeModel::dndPinOnGroup(PortTreeItem *droppedPin, BaseTreeItem *onDroppedGroup) { ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); + act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); act->exec(); } diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 80526654db7..3eb268f00c9 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -28,13 +28,30 @@ namespace hal std::cerr << " grp: " << pg->get_id() << (pg->is_ascending()?" asc ": " des ") << pg->get_start_index() << " <" << pg->get_name() << ">\n"; for (ModulePin* pin : pg->get_pins()) - std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " pos:" << pin->get_pos() << " <" << pin->get_name() << ">\n"; + std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " pos:" << pin->get_pos() << " row:" + << pinIndex2Row(pin,pin->get_group().second) << " <" << pin->get_name() << ">\n"; } std::cerr << "-------------" << std::endl; for (Module* sm : m->get_submodules()) dumpPingroups(sm); } + int pinIndex2Row(const ModulePin* pin, int index) + { + auto pg = pin->get_group(); + if (pg.first->is_ascending()) + return index - pg.first->get_start_index(); + return pg.first->get_start_index() - index; + } + + int pinRow2Index(const ModulePin* pin, int row) + { + auto pg = pin->get_group(); + if (pg.first->is_ascending()) + return pg.first->get_start_index() + row; + return pg.first->get_start_index() - row; + } + QString PinActionType::toString(PinActionType::Type tp) { QMetaEnum me = QMetaEnum::fromType(); @@ -353,7 +370,7 @@ namespace hal break; case PinActionType::PinAsignGroup: addUndoAction(PinActionType::PinAsignGroup,aa.mId,"",pin->get_group().first->get_id()); - addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); + addUndoAction(PinActionType::PinSetindex,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); mPinsMoved.insert(aa.mId); pgroup = getGroup(aa.mValue); if (!pgroup) return false; @@ -376,9 +393,9 @@ namespace hal break; case PinActionType::PinSetindex: if (!mPinsMoved.contains(aa.mId)) - addUndoAction(PinActionType::PinSetindex,aa.mId,"",pin->get_group().second); + addUndoAction(PinActionType::PinSetindex,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); pgroup = pin->get_group().first; - if (!mParentModule->move_pin_within_group(pgroup,pin,aa.mValue)) + if (!mParentModule->move_pin_within_group(pgroup,pin,pinRow2Index(pin,aa.mValue))) { qDebug() << "move_pin_within_group failed"; return false; From bcaca5d374aefbbd4c68534a8a9fe681ca7e66ca Mon Sep 17 00:00:00 2001 From: joern274 Date: Fri, 29 Sep 2023 17:10:36 +0200 Subject: [PATCH 17/40] Bugfixes and implementation of dndPinBetweenGroup --- .../module_details_widget/port_tree_model.h | 3 +- .../include/gui/user_action/action_pingroup.h | 10 ++-- .../module_details_widget/port_tree_model.cpp | 51 +++++-------------- .../gui/src/user_action/action_pingroup.cpp | 32 +++++++++--- 4 files changed, 44 insertions(+), 52 deletions(-) diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 52604b5dd51..575b4637d93 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -52,7 +52,7 @@ namespace hal public: - PortTreeItem(Type itype, QString pinName, PinDirection dir, PinType ptype, QString netName = QString()); + PortTreeItem(Type itype, u32 id_, QString pinName, PinDirection dir, PinType ptype, QString netName = QString()); PortTreeItem() : mItemType(None), mId(0) {;} QVariant getData(int column) const override; void setData(QList data) override; @@ -61,7 +61,6 @@ namespace hal int getColumnCount() const override; void setItemType(Type tp) { mItemType = tp; } Type itemType() const { return mItemType; } - void setId(u32 id_) { mId = id_; } QString name() const { return mPinName; } void setName(const QString& nam) { mPinName = nam; } void setPinType(PinType ptype) { mPinType = ptype; } diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index d1562ff4ed7..f838cd72a21 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -52,6 +52,8 @@ namespace hal int pinRow2Index(const ModulePin* pin, int row); + QString generateGroupName(const Module* mod, const ModulePin* pin); + void dumpPingroups(Module* m = nullptr); /** * @ingroup user_action @@ -154,10 +156,10 @@ namespace hal void readFromXml(QXmlStreamReader& xmlIn) override; void addToHash(QCryptographicHash& cryptoHash) const override; - static ActionPingroup* addPinsToExistingGroup(const Module* m, u32 grpId, QList pinIds, int irow = -1); - static ActionPingroup* addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int irow = -1); - static ActionPingroup* addPinsToNewGroup(const Module* m, const QString& name, QList pinIds); - static ActionPingroup* addPinToNewGroup(const Module* m, const QString& name, u32 pinId); + static ActionPingroup* addPinsToExistingGroup(const Module* m, u32 grpId, QList pinIds, int pinRow = -1); + static ActionPingroup* addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int pinRow = -1); + static ActionPingroup* addPinsToNewGroup(const Module* m, const QString& name, QList pinIds, int grpRow = -1); + static ActionPingroup* addPinToNewGroup(const Module* m, const QString& name, u32 pinId, int grpRow = -1); static ActionPingroup* removePinsFromGroup(const Module* m, QList pinIds); }; diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index b0ceed5effe..a4e40653a3f 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -19,8 +19,8 @@ namespace hal { - PortTreeItem::PortTreeItem(Type itype, QString pinName, PinDirection dir, PinType ptype, QString netName) - : mItemType(itype), mPinName(pinName), mPinDirection(dir), mPinType(ptype), mNetName(netName) + PortTreeItem::PortTreeItem(Type itype, u32 id_, QString pinName, PinDirection dir, PinType ptype, QString netName) + : mItemType(itype), mId(id_), mPinName(pinName), mPinDirection(dir), mPinType(ptype), mNetName(netName) {;} QVariant PortTreeItem::getData(int index) const @@ -145,6 +145,7 @@ namespace hal data->setData("pintreemodel/item", encodedData); return data; } + bool ModulePinsTreeModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) { Q_UNUSED(action) @@ -154,6 +155,7 @@ namespace hal int id; QByteArray encItem = data->data("pintreemodel/item"); QDataStream dataStream(&encItem, QIODevice::ReadOnly); + qDebug() << "dropMimeData" << encItem << row << column; dataStream >> type >> id; auto droppedItem = (type == "group") ? static_cast(mIdToGroupItem.value(id)) : static_cast(mIdToPinItem.value(id)); @@ -405,17 +407,16 @@ namespace hal continue; auto pinGroupName = QString::fromStdString(pinGroup->get_name()); - PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group,pinGroupName, pinGroup->get_direction(), pinGroup->get_type()); - pinGroupItem->setId(pinGroup->get_id()); + PortTreeItem* pinGroupItem = new PortTreeItem(PortTreeItem::Group, pinGroup->get_id(), pinGroupName, pinGroup->get_direction(), pinGroup->get_type()); mIdToGroupItem.insert(pinGroup->get_id(), pinGroupItem); for(ModulePin* pin : pinGroup->get_pins()) { PortTreeItem* pinItem = new PortTreeItem(PortTreeItem::Pin, + pin->get_id(), QString::fromStdString(pin->get_name()), pin->get_direction(), pin->get_type(), QString::fromStdString(pin->get_net()->get_name())); - pinItem->setId(pin->get_id()); pinGroupItem->appendChild(pinItem); mNameToTreeItem.insert(QString::fromStdString(pin->get_name()), pinItem); mIdToPinItem.insert(pin->get_id(), pinItem); @@ -559,9 +560,11 @@ namespace hal case PinEvent::GroupCreate: { ptiGroup = new PortTreeItem(PortTreeItem::Group, + pgroup->get_id(), QString::fromStdString(pgroup->get_name()), pgroup->get_direction(), pgroup->get_type()); + mIdToGroupItem.insert(ptiGroup->id(), ptiGroup); int inx = pinGroupIndex(m,pgroup); insertItem(ptiGroup, mRootItem, inx); break; @@ -600,11 +603,12 @@ namespace hal if (pin->get_net()) netName = QString::fromStdString(pin->get_net()->get_name()); ptiPin = new PortTreeItem(PortTreeItem::Pin, + pin->get_id(), QString::fromStdString(pin->get_name()), pin->get_direction(), pin->get_type(), netName); - + mIdToPinItem.insert(ptiPin->id(), ptiPin); insertItem(ptiPin, ptiGroup, pinRow); break; } @@ -726,39 +730,10 @@ namespace hal auto pinToMove = mModule->get_pin_by_id(droppedPin->id()); if (!pinToMove) return; - QString groupName = QString::fromStdString(pinToMove->get_name()); - QString baseName = groupName; - int cnt = 2; - while (mModule->get_pin_group_by_name(groupName.toStdString())) - // pin group name already exists - groupName = QString("%1_%2").arg(baseName).arg(cnt++); -/* - ActionPingroup* actMovePin = new ActionPingroup(pinToMove->get_id(),0,0,groupName); - actMovePin->setObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - bool ok = actMovePin->exec(); - if (ok && actMovePin->targetGroupId()) - { - ActionPingroup* actMoveGroup = new ActionPingroup(PinAction::MoveGroup,actMovePin->targetGroupId()); - actMoveGroup->setObject(UserActionObject(mModuleId, UserActionObjectType::Module)); - actMoveGroup->setPinOrderNo(row); - actMoveGroup->exec(); - - auto newGroup = mModule->get_pin_by_id(getIdOfItem(droppedPin))->get_group().first; - auto pinGroupName = QString::fromStdString(newGroup->get_name()); - auto pinGroupDirection = QString::fromStdString(enum_to_string((newGroup->get_direction()))); - auto pinGroupType = QString::fromStdString(enum_to_string(newGroup->get_type())); + QString groupName = generateGroupName(mModule,pinToMove); - PortTreeItem* pinGroupItem = new PortTreeItem(pinGroupName, pinGroupDirection, pinGroupType, ""); - pinGroupItem->setAdditionalData(keyType, QVariant::fromValue(itemType::group)); - pinGroupItem->setAdditionalData(keyId, newGroup->get_id()); - - int pos = mRootItem->getChildCount(); // or query current index - - insertItem(pinGroupItem, mRootItem, pos); - removeItem(droppedPin); - insertItem(droppedPin, pinGroupItem, 0); - } - */ + ActionPingroup* act = ActionPingroup::addPinToNewGroup(mModule, groupName, droppedPin->id(),row); + act->exec(); } void ModulePinsTreeModel::insertItem(PortTreeItem* item, BaseTreeItem* parent, int index) diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 3eb268f00c9..903102888b9 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -52,6 +52,19 @@ namespace hal return pg.first->get_start_index() - row; } + QString generateGroupName(const Module* mod, const ModulePin* pin) + { + QString baseName = QString::fromStdString(pin->get_name()); + QSet existingGroups; + for (auto g : mod->get_pin_groups()) + existingGroups.insert(QString::fromStdString(g->get_name())); + QString retval = baseName; + int count = 1; + while (existingGroups.contains(retval)) + retval = QString("%1_%2").arg(baseName).arg(++count); + return retval; + } + QString PinActionType::toString(PinActionType::Type tp) { QMetaEnum me = QMetaEnum::fromType(); @@ -412,7 +425,7 @@ namespace hal return UserAction::exec(); } - ActionPingroup* ActionPingroup::addPinsToExistingGroup(const Module *m, u32 grpId, QList pinIds, int irow) + ActionPingroup* ActionPingroup::addPinsToExistingGroup(const Module *m, u32 grpId, QList pinIds, int pinRow) { ActionPingroup* retval = nullptr; for (u32 pinId : pinIds) @@ -421,21 +434,21 @@ namespace hal retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",grpId)); else retval = new ActionPingroup(PinActionType::PinAsignGroup,pinId,"",grpId); - if (irow >= 0) - retval->mPinActions.append(AtomicAction(PinActionType::PinSetindex,pinId,"",irow++)); + if (pinRow >= 0) + retval->mPinActions.append(AtomicAction(PinActionType::PinSetindex,pinId,"",pinRow++)); } retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); return retval; } - ActionPingroup* ActionPingroup::addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int irow) + ActionPingroup* ActionPingroup::addPinToExistingGroup(const Module* m, u32 grpId, u32 pinId, int pinRow) { QList pinIds; pinIds << pinId; - return addPinsToExistingGroup(m,grpId,pinIds,irow); + return addPinsToExistingGroup(m,grpId,pinIds,pinRow); } - ActionPingroup* ActionPingroup::addPinsToNewGroup(const Module* m, const QString& name, QList pinIds) + ActionPingroup* ActionPingroup::addPinsToNewGroup(const Module* m, const QString& name, QList pinIds, int grpRow) { static int vid = -9; ActionPingroup* retval = new ActionPingroup(PinActionType::GroupCreate,vid,name); @@ -450,15 +463,18 @@ namespace hal } for (u32 pinId : pinIds) retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",vid)); + + if (grpRow >= 0) + retval->mPinActions.append(AtomicAction(PinActionType::GroupMove,vid,"",grpRow)); retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); return retval; } - ActionPingroup* ActionPingroup::addPinToNewGroup(const Module *m, const QString& name, u32 pinId) + ActionPingroup* ActionPingroup::addPinToNewGroup(const Module *m, const QString& name, u32 pinId, int grpRow) { QList pinIds; pinIds << pinId; - return addPinsToNewGroup(m,name,pinIds); + return addPinsToNewGroup(m,name,pinIds, grpRow); } ActionPingroup* ActionPingroup::removePinsFromGroup(const Module* m, QList pinIds) From 6ca908a297da291f0af9effed2315b5daef2140c Mon Sep 17 00:00:00 2001 From: joern274 Date: Sat, 30 Sep 2023 22:16:33 +0200 Subject: [PATCH 18/40] Stacking of pin_changed events finally solved --- CHANGELOG.md | 5 + .../netlist/gate_library/enums/pin_event.h | 166 ++++++++++++++++++ .../netlist/gate_library/enums/pin_type.h | 20 --- include/hal_core/netlist/module.h | 9 +- .../gui/graph_widget/graph_context_manager.h | 2 +- .../include/gui/netlist_relay/netlist_relay.h | 2 +- .../module_details_widget/port_tree_model.h | 3 +- .../net_details_widget/module_table_model.h | 2 +- .../include/gui/user_action/action_pingroup.h | 2 + .../module_details_widget/port_tree_model.cpp | 8 +- .../gui/src/user_action/action_pingroup.cpp | 5 + src/netlist/gate_library/enums/pin_event.cpp | 102 +++++++++++ src/netlist/gate_library/enums/pin_type.cpp | 18 -- src/netlist/module.cpp | 67 ++++--- 14 files changed, 332 insertions(+), 79 deletions(-) create mode 100644 include/hal_core/netlist/gate_library/enums/pin_event.h create mode 100644 src/netlist/gate_library/enums/pin_event.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index dd0aefd1bb4..854d92cb029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,11 @@ All notable changes to this project will be documented in this file. * fixed order of pins within pin groups not being properly handled for modules and gate types * fixed netlist parsers assigning gate pins in wrong order (compensated by the bug above, imported netlists were still correct) * fixed wrong order of pins within pin groups in provided gate libraries +* module pins + * added qualifier for `pin_changed` core events telling receiver details about the recent modification + * added event scope and stacking classes so that `pin_changed` events can be collected and prioritized + * added specific GUI handler for every `pin_changed` event thus replacing the reload-entire-pingroup-tree policy + * added class `ActionPingroup` so that UNDO function works for all pin / pin group actions issued from GUI ## [4.2.0](v4.2.0) - 2023-05-24 10:02:04-07:00 (urgency: medium) * GUI plugin manager diff --git a/include/hal_core/netlist/gate_library/enums/pin_event.h b/include/hal_core/netlist/gate_library/enums/pin_event.h new file mode 100644 index 00000000000..7f4b6daf3c8 --- /dev/null +++ b/include/hal_core/netlist/gate_library/enums/pin_event.h @@ -0,0 +1,166 @@ +// MIT License +// +// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved. +// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved. +// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved. +// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include "hal_core/utilities/enums.h" +#include "hal_core/defines.h" +#include +#include + +namespace hal +{ + /** + * Spezifies the pin_changed event type + * + * The order of events in enum class defines the order in which events are handled. + * + */ + enum class PinEvent + { + unknown, + GroupCreate, /// new pin group created + GroupRename, /// pin group renamed + GroupTypeChange, /// changed PinType attribute of group (like data) + GroupDirChange, /// changed PinDirection attribute of group (like input) + GroupReorder, /// moved group to a new position within containing module + PinCreate, /// new pin created + PinAssignToGroup, /// pin assigned to new group + PinRename, /// pin renamed + PinTypeChange, /// changed PinType attribute of pin (like data) + PinDirChange, /// changed PinDirection attribute of pin (like input) + PinReorder, /// moved pin to a new position within containing group + PinDelete, /// pin deleted + GroupDelete /// group deleted + }; + + template<> + std::map EnumStrings::data; + + class Module; + + /** + * Wrapper class for core pin_changed events. + * + * Events can be send immediately or stacked and send at according to their priority. + */ + class PinChangedEvent + { + friend bool pin_event_order(const PinChangedEvent& a, const PinChangedEvent& b); + friend class PinChangedEventScope; + + /** + * Subclass for event stack. + */ + class EventStack : public std::vector + { + public: + /** + * Scope count indicates the nesting depth of event-throwing subroutines. + * Only the top level (m_count=0) is allowed to send the events from stack. + */ + int m_count; + + /** + * Construct empty stack + */ + EventStack() : m_count(0) {;} + + /** + * Attempts to send events, typically at the end of a pin-changing subroutine. + * Events will only be send if m_count is zero. + */ + void send_events(Module* m); + }; + + static std::unordered_map s_event_stack; + + Module* m_module; + PinEvent m_event; + u32 m_id; + + public: + /** + * PinChangedEvent class for single event + * @param m - The module comprising pins and pin groups + * @param pev - The pin event enum + * @param id - pin or pin group ID + */ + PinChangedEvent(Module* m, PinEvent pev, u32 id); + + /** + * Returns the module for which pins or pin groups have been changed + * @return The module comprising pins and pin groups + */ + Module* get_module() const; + + /** + * Return bitwise binary encoded PinEvent and ID + * 4LSB = The pin event enum as 4 bit int + * 28HSB = The ID as 28 bit int + * @return The bitcode according to scheme above + */ + u32 associated_data(); + + /** + * Attempts to send event. + * If this routine or any calling routine wants to collect events the event gets written on stack instead. + */ + void send(); + }; + + /** + * By creating an instance of this class a new scope gets created thus collecting events. + */ + class PinChangedEventScope + { + Module* m_module; + public: + + /** + * Constructor for scope instance incrementing scope count + * @param m The module comprising pins and pin groups + */ + PinChangedEventScope(Module* m); + + /** + * Destructor for scope instance decrementing scope count + */ + ~PinChangedEventScope(); + + /** + * Attempts to send all stacked events. Will do nothing if not issued from top-level scope. + */ + void send_events(); + }; + + /** + * Function used by sort algorithm to organize events according to their priority. + * @param a - Pin changed event A + * @param b - Pin changed event B + * @return true if A should be handled before B, false otherwise. + */ + bool pin_event_order(const PinChangedEvent& a, const PinChangedEvent& b); +} diff --git a/include/hal_core/netlist/gate_library/enums/pin_type.h b/include/hal_core/netlist/gate_library/enums/pin_type.h index 9f595c660ad..b8a35ef1a03 100644 --- a/include/hal_core/netlist/gate_library/enums/pin_type.h +++ b/include/hal_core/netlist/gate_library/enums/pin_type.h @@ -55,24 +55,4 @@ namespace hal template<> std::map EnumStrings::data; - enum class PinEvent - { - unknown, - GroupCreate, - GroupReorder, - GroupRename, - GroupTypeChange, - GroupDirChange, - GroupDelete, - PinCreate, - PinReorder, - PinAssignToGroup, - PinRename, - PinTypeChange, - PinDirChange, - PinDelete - }; - - template<> - std::map EnumStrings::data; } // namespace hal diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index 874102df6cc..361571a27cb 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -30,6 +30,7 @@ #include "hal_core/netlist/event_system/event_handler.h" #include "hal_core/netlist/gate_library/enums/pin_direction.h" #include "hal_core/netlist/gate_library/enums/pin_type.h" +#include "hal_core/netlist/gate_library/enums/pin_event.h" #include "hal_core/netlist/gate_library/gate_library.h" #include "hal_core/netlist/pins/module_pin.h" #include "hal_core/netlist/pins/pin_group.h" @@ -672,6 +673,12 @@ namespace hal */ std::vector get_gates(const std::function& filter, bool recursive = false) const; + /** + * Get the event handler connected to module + * @return The event handler; + */ + EventHandler* get_event_handler() const; + private: friend class NetlistInternalManager; Module(NetlistInternalManager* internal_manager, EventHandler* event_handler, u32 id, Module* parent, const std::string& name); @@ -687,8 +694,6 @@ namespace hal bool has_external_destination; }; - static u32 pinevent_associated_data(PinEvent pev, u32 id); - std::string m_name; std::string m_type; diff --git a/plugins/gui/include/gui/graph_widget/graph_context_manager.h b/plugins/gui/include/gui/graph_widget/graph_context_manager.h index 01940b25655..892f8dcb5db 100644 --- a/plugins/gui/include/gui/graph_widget/graph_context_manager.h +++ b/plugins/gui/include/gui/graph_widget/graph_context_manager.h @@ -26,7 +26,7 @@ #pragma once #include "hal_core/defines.h" -#include "hal_core/netlist/gate_library/enums/pin_type.h" +#include "hal_core/netlist/gate_library/enums/pin_event.h" #include #include diff --git a/plugins/gui/include/gui/netlist_relay/netlist_relay.h b/plugins/gui/include/gui/netlist_relay/netlist_relay.h index 6733a89cc50..88c49d1ae84 100644 --- a/plugins/gui/include/gui/netlist_relay/netlist_relay.h +++ b/plugins/gui/include/gui/netlist_relay/netlist_relay.h @@ -26,7 +26,7 @@ #pragma once #include "hal_core/netlist/event_system/event_handler.h" -#include "hal_core/netlist/gate_library/enums/pin_type.h" +#include "hal_core/netlist/gate_library/enums/pin_event.h" #include "gui/grouping/grouping_color_serializer.h" #include #include diff --git a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h index 575b4637d93..d14937a00d7 100644 --- a/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h +++ b/plugins/gui/include/gui/selection_details_widget/module_details_widget/port_tree_model.h @@ -27,8 +27,9 @@ //#include "gui/new_selection_details_widget/models/base_tree_model.h" #include "gui/basic_tree_model/base_tree_model.h" -#include "hal_core/netlist/gate_library/enums/pin_type.h" #include "hal_core/netlist/gate_library/enums/pin_direction.h" +#include "hal_core/netlist/gate_library/enums/pin_event.h" +#include "hal_core/netlist/gate_library/enums/pin_type.h" #include namespace hal diff --git a/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h b/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h index 7749794da7e..cfe0a053e7d 100644 --- a/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h +++ b/plugins/gui/include/gui/selection_details_widget/net_details_widget/module_table_model.h @@ -26,7 +26,7 @@ #pragma once #include "hal_core/defines.h" -#include "hal_core/netlist/gate_library/enums/pin_type.h" +#include "hal_core/netlist/gate_library/enums/pin_event.h" #include #include diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index f838cd72a21..375cc0ff2a1 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -174,4 +174,6 @@ namespace hal UserAction* newAction() const; static ActionPingroupFactory* sFactory; }; + + uint qHash(PinEvent pev); } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index a4e40653a3f..b8ab9496658 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -507,6 +507,12 @@ namespace hal void ModulePinsTreeModel::handleModulePortsChanged(Module* m, PinEvent pev, u32 pgid) { + static const QSet groupEvents = { PinEvent::GroupCreate, + PinEvent::GroupReorder, + PinEvent::GroupRename, + PinEvent::GroupTypeChange, + PinEvent::GroupDirChange, + PinEvent::GroupDelete}; Q_UNUSED(pev); Q_UNUSED(pgid); if ((int)m->get_id() != mModuleId) return; @@ -519,7 +525,7 @@ namespace hal int pinRow = -1; - if (pev < PinEvent::PinCreate) + if (groupEvents.contains(pev)) { // group event ptiGroup = mIdToGroupItem.value(pgid); diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 903102888b9..05d23fdd293 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -52,6 +52,11 @@ namespace hal return pg.first->get_start_index() - row; } + uint qHash(PinEvent pev) + { + return (uint) pev; + } + QString generateGroupName(const Module* mod, const ModulePin* pin) { QString baseName = QString::fromStdString(pin->get_name()); diff --git a/src/netlist/gate_library/enums/pin_event.cpp b/src/netlist/gate_library/enums/pin_event.cpp new file mode 100644 index 00000000000..73bf9f001e4 --- /dev/null +++ b/src/netlist/gate_library/enums/pin_event.cpp @@ -0,0 +1,102 @@ +#include "hal_core/netlist/gate_library/enums/pin_event.h" +#include "hal_core/netlist/event_system/event_handler.h" +#include "hal_core/netlist/module.h" +#include +#include + +namespace hal { + + template<> + std::map EnumStrings::data = { + {PinEvent::unknown, "unknown"}, + {PinEvent::GroupCreate, "GroupCreate"}, + {PinEvent::GroupReorder, "GroupReorder"}, + {PinEvent::GroupRename, "GroupRename"}, + {PinEvent::GroupTypeChange, "GroupTypeChange"}, + {PinEvent::GroupDirChange, "GroupDirChange"}, + {PinEvent::GroupDelete, "GroupDelete"}, + {PinEvent::PinCreate, "PinCreate"}, + {PinEvent::PinReorder, "PinReorder"}, + {PinEvent::PinAssignToGroup, "PinAssignToGroup"}, + {PinEvent::PinRename, "PinRename"}, + {PinEvent::PinTypeChange, "PinTypeChange"}, + {PinEvent::PinDirChange, "PinDirChange"}, + {PinEvent::PinDelete, "PinDelete"} + }; + + std::unordered_map PinChangedEvent::s_event_stack; + + PinChangedEvent::PinChangedEvent(Module* m, PinEvent pev, u32 id) + : m_module(m), m_event(pev), m_id(id) + {;} + + void PinChangedEvent::send() + { + auto it = s_event_stack.find(m_module); + if (it == s_event_stack.end()) + { + // not stacked, send event immediately + m_module->get_event_handler()->notify(ModuleEvent::event::pin_changed, m_module, associated_data()); + return; + } + + // put event on stack to emit it later + it->second->push_back(*this); + } + + Module* PinChangedEvent::get_module() const + { + return m_module; + } + + u32 PinChangedEvent::associated_data() + { + return (m_id << 4) | (((u32)m_event)&0xF); + } + + bool pin_event_order(const PinChangedEvent& a, const PinChangedEvent& b) + { + if (a.m_event < b.m_event) return true; + if (a.m_event > b.m_event) return false; + return a.m_idget_event_handler()->notify(ModuleEvent::event::pin_changed, m, it->associated_data()); + } + + PinChangedEventScope::PinChangedEventScope(Module* m) + : m_module(m) + { + auto it = PinChangedEvent::s_event_stack.find(m); + if (it == PinChangedEvent::s_event_stack.end()) + PinChangedEvent::s_event_stack[m] = new PinChangedEvent::EventStack; + else + ++it->second->m_count; + } + + PinChangedEventScope::~PinChangedEventScope() + { + auto it = PinChangedEvent::s_event_stack.find(m_module); + assert(it != PinChangedEvent::s_event_stack.end()); + if (it->second->m_count > 0) + --it->second->m_count; + else + { + delete it->second; + PinChangedEvent::s_event_stack.erase(it); + } + } + + void PinChangedEventScope::send_events() + { + auto it = PinChangedEvent::s_event_stack.find(m_module); + assert(it != PinChangedEvent::s_event_stack.end()); + if (it->second->m_count > 0) // do not send yet + return; + it->second->send_events(m_module); + } +} diff --git a/src/netlist/gate_library/enums/pin_type.cpp b/src/netlist/gate_library/enums/pin_type.cpp index b9e9c01a296..091c0f98236 100644 --- a/src/netlist/gate_library/enums/pin_type.cpp +++ b/src/netlist/gate_library/enums/pin_type.cpp @@ -19,22 +19,4 @@ namespace hal {PinType::select, "select"}, {PinType::carry, "carry"}, {PinType::sum, "sum"}}; - - template<> - std::map EnumStrings::data = { - {PinEvent::unknown, "unknown"}, - {PinEvent::GroupCreate, "GroupCreate"}, - {PinEvent::GroupReorder, "GroupReorder"}, - {PinEvent::GroupRename, "GroupRename"}, - {PinEvent::GroupTypeChange, "GroupTypeChange"}, - {PinEvent::GroupDirChange, "GroupDirChange"}, - {PinEvent::GroupDelete, "GroupDelete"}, - {PinEvent::PinCreate, "PinCreate"}, - {PinEvent::PinReorder, "PinReorder"}, - {PinEvent::PinAssignToGroup, "PinAssignToGroup"}, - {PinEvent::PinRename, "PinRename"}, - {PinEvent::PinTypeChange, "PinTypeChange"}, - {PinEvent::PinDirChange, "PinDirChange"}, - {PinEvent::PinDelete, "PinDelete"} - }; } diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index af1e0a16e23..0226d386288 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -660,13 +660,13 @@ namespace hal { m_output_nets.insert(net); pin->set_direction(PinDirection::inout); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); + PinChangedEvent(this,PinEvent::PinTypeChange,pin->get_id()).send(); } else if (direction == PinDirection::output) { m_input_nets.insert(net); pin->set_direction(PinDirection::inout); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); + PinChangedEvent(this,PinEvent::PinTypeChange,pin->get_id()).send(); } } else @@ -687,7 +687,7 @@ namespace hal m_input_nets.insert(net); m_output_nets.erase(net); pin->set_direction(PinDirection::input); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); + PinChangedEvent(this,PinEvent::PinTypeChange,pin->get_id()).send(); } } else @@ -709,7 +709,7 @@ namespace hal m_output_nets.insert(net); m_input_nets.erase(net); pin->set_direction(PinDirection::output); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); + PinChangedEvent(this,PinEvent::PinTypeChange,pin->get_id()).send(); } } else @@ -851,13 +851,13 @@ namespace hal else { // pin assigned to new group OK - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,group_res.get()->get_id())); + PinChangedEvent(this,PinEvent::GroupCreate,group_res.get()->get_id()).send(); } } } else { - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinCreate,pin_res.get()->get_id())); + PinChangedEvent(this,PinEvent::PinCreate,pin_res.get()->get_id()).send(); } return pin_res; } @@ -1102,7 +1102,7 @@ namespace hal m_pin_names_map.erase(old_name); pin->set_name(new_name); m_pin_names_map[new_name] = pin; - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinRename,pin->get_id())); + PinChangedEvent(this,PinEvent::PinRename,pin->get_id()).send(); } return true; @@ -1125,7 +1125,7 @@ namespace hal if (pin->get_type() != new_type) { pin->set_type(new_type); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinTypeChange,pin->get_id())); + PinChangedEvent(this,PinEvent::PinTypeChange,pin->get_id()).send(); } return true; @@ -1170,7 +1170,7 @@ namespace hal m_pin_group_names_map.erase(old_name); pin_group->set_name(new_name); m_pin_group_names_map[new_name] = pin_group; - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupRename,pin_group->get_id())); + PinChangedEvent(this,PinEvent::GroupRename,pin_group->get_id()).send(); } return true; @@ -1194,7 +1194,7 @@ namespace hal if (pin_group->get_type() != new_type) { pin_group->set_type(new_type); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupTypeChange,pin_group->get_id())); + PinChangedEvent(this,PinEvent::GroupTypeChange,pin_group->get_id()).send(); } return true; } @@ -1221,7 +1221,7 @@ namespace hal if (pin_group->get_direction() != new_direction) { pin_group->set_direction(new_direction); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupTypeChange,pin_group->get_id())); + PinChangedEvent(this,PinEvent::GroupTypeChange,pin_group->get_id()).send(); } return true; } @@ -1235,6 +1235,8 @@ namespace hal u32 start_index, bool delete_empty_groups) { + PinChangedEventScope scope(this); + if (name.empty()) { return ERR("could not create pin group for module '" + m_name + "' with ID " + std::to_string(m_id) + ": empty string passed as name"); @@ -1259,7 +1261,8 @@ namespace hal } } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,pin_group->get_id())); + PinChangedEvent(this,PinEvent::GroupCreate,pin_group->get_id()).send(); + scope.send_events(); return OK(pin_group); } @@ -1271,7 +1274,7 @@ namespace hal bool Module::delete_pin_group(PinGroup* pin_group) { - std::vector distribute_events; + PinChangedEventScope scope(this); if (pin_group == nullptr) { log_warning("module", "could not delete pin group from module '{}' with ID {}: pin group is a 'nullptr'", m_name, m_id); @@ -1294,8 +1297,8 @@ namespace hal { return false; } - distribute_events.push_back(pinevent_associated_data(PinEvent::GroupCreate,res.get()->get_id())); - distribute_events.push_back(pinevent_associated_data(PinEvent::PinAssignToGroup,pin->get_id())); + PinChangedEvent(this,PinEvent::GroupCreate,res.get()->get_id()).send(); + PinChangedEvent(this,PinEvent::PinAssignToGroup,pin->get_id()).send(); } u32 pin_group_id_to_delete = pin_group->get_id(); @@ -1305,9 +1308,8 @@ namespace hal return false; } - for (u32 dist_ev : distribute_events) - m_event_handler->notify(ModuleEvent::event::pin_changed, this, dist_ev); - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); + PinChangedEvent(this,PinEvent::GroupDelete,pin_group_id_to_delete).send(); + scope.send_events(); return true; } @@ -1350,13 +1352,13 @@ namespace hal m_pin_groups_ordered.splice(dst_it, m_pin_groups_ordered, src_it); } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupReorder,pin_group->get_id())); + PinChangedEvent(this,PinEvent::GroupReorder,pin_group->get_id()).send(); return true; } bool Module::assign_pin_to_group(PinGroup* pin_group, ModulePin* pin, bool delete_empty_groups) { - u32 pin_group_id_to_delete = 0; + PinChangedEventScope scope(this); if (pin_group == nullptr) { @@ -1398,7 +1400,7 @@ namespace hal if (delete_empty_groups && pg->empty()) { - pin_group_id_to_delete = pg->get_id(); + PinChangedEvent(this,PinEvent::GroupDelete,pg->get_id()).send(); if (!delete_pin_group_internal(pg)) { log_warning("module", @@ -1416,9 +1418,8 @@ namespace hal return false; } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinAssignToGroup,pin->get_id())); - if (pin_group_id_to_delete) - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); + PinChangedEvent(this,PinEvent::PinAssignToGroup,pin->get_id()).send(); + scope.send_events(); return true;; } @@ -1461,7 +1462,7 @@ namespace hal return false; } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinReorder,pin->get_id())); + PinChangedEvent(this,PinEvent::PinReorder,pin->get_id()).send(); return true; } @@ -1556,13 +1557,13 @@ namespace hal } } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupCreate,pin->get_group().first->get_id())); + PinChangedEvent(this,PinEvent::GroupCreate,pin->get_group().first->get_id()).send(); return OK(pin); } bool Module::remove_pin_net(Net* net) { - u32 pin_group_id_to_delete = 0; + PinChangedEventScope scope(this); auto pin = get_pin_by_net(net); if (pin == nullptr) { @@ -1581,7 +1582,7 @@ namespace hal if (pin_group->empty()) { - pin_group_id_to_delete = pin_group->get_id(); + PinChangedEvent(this,PinEvent::GroupDelete,pin_group->get_id()).send(); if (!delete_pin_group_internal(pin_group)) { log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to delete pin group '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin_group->get_name(), pin_group->get_id()); @@ -1598,9 +1599,8 @@ namespace hal return false; } - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::PinDelete,pin_id_to_delete)); - if (pin_group_id_to_delete) - m_event_handler->notify(ModuleEvent::event::pin_changed, this, pinevent_associated_data(PinEvent::GroupDelete,pin_group_id_to_delete)); + PinChangedEvent(this,PinEvent::PinDelete,pin_id_to_delete).send(); + scope.send_events(); return true; } @@ -1738,9 +1738,8 @@ namespace hal return true; } - u32 Module::pinevent_associated_data(PinEvent pev, u32 id) + EventHandler* Module::get_event_handler() const { - return (id << 4) | (((u32)pev)&0xF); + return m_event_handler; } - } // namespace hal From 152cc46cf860275fd0f17f70b4090b771026aced Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 2 Oct 2023 16:00:33 +0200 Subject: [PATCH 19/40] minor fixes --- include/hal_core/netlist/module.h | 2 +- include/hal_core/netlist/pins/base_pin.h | 11 ---- .../include/gui/user_action/action_pingroup.h | 25 ++++--- .../module_ports_tree.cpp | 2 +- .../module_details_widget/port_tree_model.cpp | 6 +- .../gui/src/user_action/action_pingroup.cpp | 66 +++++++++---------- 6 files changed, 50 insertions(+), 62 deletions(-) diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index 361571a27cb..7f4c2bd1de6 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -530,7 +530,7 @@ namespace hal * * @param[in] pin_group - The pin group to be moved. * @param[in] new_index - The index to which the pin group is moved. - * @returns Ok on success, an error message otherwise. + * @returns true on success, false message otherwise. */ bool move_pin_group(PinGroup* pin_group, u32 new_index); diff --git a/include/hal_core/netlist/pins/base_pin.h b/include/hal_core/netlist/pins/base_pin.h index b168aeb1655..855db0470bd 100644 --- a/include/hal_core/netlist/pins/base_pin.h +++ b/include/hal_core/netlist/pins/base_pin.h @@ -100,17 +100,6 @@ namespace hal m_name = name; } - int get_pos() const - { - auto g = get_group(); - int i = 0; - for (auto p : g.first->get_pins()) - { - if (p == this) return i; - ++i; - } - return -1; - } /** * Get the name of the pin. * diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index 375cc0ff2a1..e9b31c54f1f 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -35,8 +35,8 @@ namespace hal { Q_OBJECT public: - enum Type { None, GroupCreate, GroupDelete, GroupMove, GroupRename, GroupTypechange, GroupDirection, - PinAsignGroup, PinRename, PinTypechange, PinDirection, PinSetindex, MaxAction }; + enum Type { None, GroupCreate, GroupDelete, GroupMoveToRow, GroupRename, GroupTypeChange, GroupDirChange, + PinAsignToGroup, PinRename, PinTypeChange, PinDirChange, PinMoveToRow, MaxAction }; Q_ENUM(Type); public: @@ -67,28 +67,28 @@ namespace hal * ID will be used internally for subsequent commands related to crated group * name : name of group * value : start index, assume ascending - * negative value: descending order starting with (-value) + * negative value: descending order starting with (-value-1) * * GroupDelete * ID : ID of group to delete * - * GroupMove + * GroupMoveToRow * ID : ID of group to move - * value : new position in vector of pin groups + * value : row to which group get moved within vector of pin groups * * GroupRename * ID : ID of group to rename * name : new name * - * GroupTypechange + * GroupTypeChange * ID : ID of group to modifiy * value : (int) PinType as of hal_core/netlist/gate_library/enums/pin_type.h * - * GroupDirection + * GroupDirChange * ID : ID of group to modifiy * value : (int) PinDirection as of hal_core/netlist/gate_library/enums/pin_direction.h * - * PinAsignGroup + * PinAsignToGroup * ID : ID of pin * value : ID of group, might be negative if group recently created * @@ -96,18 +96,17 @@ namespace hal * ID : ID of pin to rename * name : new name * - * PinTypechange + * PinTypeChange * ID : ID of pin to modify * value : (int) PinType * - * PinDirection + * PinDirChange * ID : ID of pin to modify * value : (int) PinDirection * - * PinSetindex + * PinMoveToRow * ID : ID of pin - * value : new index in pingroup. Calculated from row by - * index = startindex + a * row with a=1 for ascending, a=-1 for descending + * value : row to which pin gets moved in pingroup */ class ActionPingroup : public UserAction { diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index cd605847317..366b8fb1d09 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -211,7 +211,7 @@ namespace hal { PinType ptype = enum_from_string(cbd.textValue().toStdString(),PinType::none); - ActionPingroup* act = new ActionPingroup(PinActionType::PinTypechange,pin->get_id(),"",(int)ptype); + ActionPingroup* act = new ActionPingroup(PinActionType::PinTypeChange,pin->get_id(),"",(int)ptype); act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); act->exec(); } diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index b8ab9496658..d9afcee3858 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -695,14 +695,14 @@ namespace hal bool bottomEdge = row == mRootItem->getChildCount(); auto desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; - ActionPingroup* act = new ActionPingroup(PinActionType::GroupMove,droppedGroup->id(),"",desiredIdx); + ActionPingroup* act = new ActionPingroup(PinActionType::GroupMoveToRow,droppedGroup->id(),"",desiredIdx); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); act->exec(); } void ModulePinsTreeModel::dndPinOnGroup(PortTreeItem *droppedPin, BaseTreeItem *onDroppedGroup) { - ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); + ActionPingroup* act = new ActionPingroup(PinActionType::PinAsignToGroup,droppedPin->id(),"",static_cast(onDroppedGroup)->id()); act->setObject(UserActionObject(mModuleId,UserActionObjectType::Module)); act->exec(); } @@ -717,7 +717,7 @@ namespace hal bool bottomEdge = row == onDroppedParent->getChildCount(); desiredIdx = bottomEdge ? row-1 : row; if(ownRow < row && !bottomEdge) desiredIdx--; // insert item here - act = new ActionPingroup(PinActionType::PinSetindex,droppedPin->id(),"",desiredIdx); // TODO : start_index, descending + act = new ActionPingroup(PinActionType::PinMoveToRow,droppedPin->id(),"",desiredIdx); // TODO : start_index, descending } else { diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 05d23fdd293..892f0d85087 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -28,7 +28,7 @@ namespace hal std::cerr << " grp: " << pg->get_id() << (pg->is_ascending()?" asc ": " des ") << pg->get_start_index() << " <" << pg->get_name() << ">\n"; for (ModulePin* pin : pg->get_pins()) - std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " pos:" << pin->get_pos() << " row:" + std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " row:" << pinIndex2Row(pin,pin->get_group().second) << " <" << pin->get_name() << ">\n"; } std::cerr << "-------------" << std::endl; @@ -89,13 +89,13 @@ namespace hal bool PinActionType::useExistingGroup(PinActionType::Type tp) { - static const QSet types = {GroupDelete, GroupMove, GroupRename, GroupTypechange, GroupDirection}; + static const QSet types = {GroupDelete, GroupMoveToRow, GroupRename, GroupTypeChange, GroupDirChange}; return types.contains(tp); } bool PinActionType::useExistingPin(PinActionType::Type tp) { - static const QSet types = {PinAsignGroup, PinRename, PinTypechange, PinDirection, PinSetindex}; + static const QSet types = {PinAsignToGroup, PinRename, PinTypeChange, PinDirChange, PinMoveToRow}; return types.contains(tp); } @@ -206,7 +206,7 @@ namespace hal QHash*,int> remainingPins; for (const AtomicAction& aa : mPinActions) { - if (aa.mType != PinActionType::PinAsignGroup) + if (aa.mType != PinActionType::PinAsignToGroup) continue; ModulePin* pin = mParentModule->get_pin_by_id(aa.mId); PinGroup* pgroup = pin->get_group().first; @@ -232,11 +232,11 @@ namespace hal { const GroupRestore& gr = it.value(); restoreActions.append(AtomicAction(PinActionType::GroupCreate,gr.mId,gr.mName,gr.mStartIndex)); - restoreActions.append(AtomicAction(PinActionType::GroupMove,gr.mId,"",gr.mRow)); + restoreActions.append(AtomicAction(PinActionType::GroupMoveToRow,gr.mId,"",gr.mRow)); if (gr.mType != PinType::none) - restoreActions.append(AtomicAction(PinActionType::GroupTypechange,gr.mId,"",(int)gr.mType)); + restoreActions.append(AtomicAction(PinActionType::GroupTypeChange,gr.mId,"",(int)gr.mType)); if (gr.mDirection != PinDirection::none) - restoreActions.append(AtomicAction(PinActionType::GroupDirection,gr.mId,"",(int)gr.mDirection)); + restoreActions.append(AtomicAction(PinActionType::GroupDirChange,gr.mId,"",(int)gr.mDirection)); } if (!restoreActions.isEmpty()) { @@ -324,7 +324,7 @@ namespace hal if (aa.mValue < 0) { ascending = false; - startIndex = -aa.mValue; + startIndex = -aa.mValue-1; } if (aa.mId > 0) { @@ -350,7 +350,7 @@ namespace hal case PinActionType::GroupDelete: { int v = pgroup->get_start_index(); - if (!pgroup->is_ascending()) v = -v; + if (!pgroup->is_ascending()) v = -v-1; u32 id = pgroup->get_id(); int ptype = (int) pgroup->get_type(); int pdir = (int) pgroup->get_direction(); @@ -358,15 +358,15 @@ namespace hal if (!mParentModule->delete_pin_group(pgroup)) return false; addUndoAction(PinActionType::GroupCreate,id,name,v); - addUndoAction(PinActionType::GroupTypechange,id,"",ptype); - addUndoAction(PinActionType::GroupDirection,id,"",pdir); + addUndoAction(PinActionType::GroupTypeChange,id,"",ptype); + addUndoAction(PinActionType::GroupDirChange,id,"",pdir); break; } - case PinActionType::GroupMove: + case PinActionType::GroupMoveToRow: { int inx = pinGroupRow(mParentModule,pgroup); if (inx < 0) return false; - addUndoAction(PinActionType::GroupMove,pgroup->get_id(),"",inx); + addUndoAction(PinActionType::GroupMoveToRow,pgroup->get_id(),"",inx); if (!mParentModule->move_pin_group(pgroup,aa.mValue)) return false; break; @@ -376,19 +376,19 @@ namespace hal if (!mParentModule->set_pin_group_name(pgroup,aa.mName.toStdString())) return false; break; - case PinActionType::GroupTypechange: - addUndoAction(PinActionType::GroupTypechange,pgroup->get_id(),"",(int)pgroup->get_type()); + case PinActionType::GroupTypeChange: + addUndoAction(PinActionType::GroupTypeChange,pgroup->get_id(),"",(int)pgroup->get_type()); if (!mParentModule->set_pin_group_type(pgroup, (PinType) aa.mValue)) return false; break; - case PinActionType::GroupDirection: - addUndoAction(PinActionType::GroupDirection,pgroup->get_id(),"",(int)pgroup->get_direction()); + case PinActionType::GroupDirChange: + addUndoAction(PinActionType::GroupDirChange,pgroup->get_id(),"",(int)pgroup->get_direction()); if (!mParentModule->set_pin_group_direction(pgroup, (PinDirection) aa.mValue)) return false; break; - case PinActionType::PinAsignGroup: - addUndoAction(PinActionType::PinAsignGroup,aa.mId,"",pin->get_group().first->get_id()); - addUndoAction(PinActionType::PinSetindex,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); + case PinActionType::PinAsignToGroup: + addUndoAction(PinActionType::PinAsignToGroup,aa.mId,"",pin->get_group().first->get_id()); + addUndoAction(PinActionType::PinMoveToRow,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); mPinsMoved.insert(aa.mId); pgroup = getGroup(aa.mValue); if (!pgroup) return false; @@ -404,14 +404,14 @@ namespace hal if (!mParentModule->set_pin_name(pin, aa.mName.toStdString())) return false; break; - case PinActionType::PinTypechange: - addUndoAction(PinActionType::PinTypechange,aa.mId,"",(int)pin->get_type()); + case PinActionType::PinTypeChange: + addUndoAction(PinActionType::PinTypeChange,aa.mId,"",(int)pin->get_type()); if (!mParentModule->set_pin_type(pin, (PinType) aa.mValue)) return false; break; - case PinActionType::PinSetindex: + case PinActionType::PinMoveToRow: if (!mPinsMoved.contains(aa.mId)) - addUndoAction(PinActionType::PinSetindex,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); + addUndoAction(PinActionType::PinMoveToRow,aa.mId,"",pinIndex2Row(pin,pin->get_group().second)); pgroup = pin->get_group().first; if (!mParentModule->move_pin_within_group(pgroup,pin,pinRow2Index(pin,aa.mValue))) { @@ -436,11 +436,11 @@ namespace hal for (u32 pinId : pinIds) { if (retval) - retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",grpId)); + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignToGroup,pinId,"",grpId)); else - retval = new ActionPingroup(PinActionType::PinAsignGroup,pinId,"",grpId); + retval = new ActionPingroup(PinActionType::PinAsignToGroup,pinId,"",grpId); if (pinRow >= 0) - retval->mPinActions.append(AtomicAction(PinActionType::PinSetindex,pinId,"",pinRow++)); + retval->mPinActions.append(AtomicAction(PinActionType::PinMoveToRow,pinId,"",pinRow++)); } retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); return retval; @@ -462,15 +462,15 @@ namespace hal ModulePin* pin = m->get_pin_by_id(pinIds.first()); if (pin) { - retval->mPinActions.append(AtomicAction(PinActionType::GroupDirection,vid,"",(int)pin->get_direction())); - retval->mPinActions.append(AtomicAction(PinActionType::GroupTypechange,vid,"",(int)pin->get_type())); + retval->mPinActions.append(AtomicAction(PinActionType::GroupDirChange,vid,"",(int)pin->get_direction())); + retval->mPinActions.append(AtomicAction(PinActionType::GroupTypeChange,vid,"",(int)pin->get_type())); } } for (u32 pinId : pinIds) - retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",vid)); + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignToGroup,pinId,"",vid)); if (grpRow >= 0) - retval->mPinActions.append(AtomicAction(PinActionType::GroupMove,vid,"",grpRow)); + retval->mPinActions.append(AtomicAction(PinActionType::GroupMoveToRow,vid,"",grpRow)); retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); return retval; } @@ -502,7 +502,7 @@ namespace hal retval->mPinActions.append(AtomicAction(PinActionType::GroupCreate,vid,name)); else retval = new ActionPingroup(PinActionType::GroupCreate,vid,name); - retval->mPinActions.append(AtomicAction(PinActionType::PinAsignGroup,pinId,"",vid)); + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignToGroup,pinId,"",vid)); --vid; } retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); @@ -517,6 +517,6 @@ namespace hal mDirection(pgroup->get_direction()), mType(pgroup->get_type()) { - if (!pgroup->is_ascending()) mStartIndex = -mStartIndex; + if (!pgroup->is_ascending()) mStartIndex = -mStartIndex-1; } } From bd3aca7eb1e9fd4dd89e0d0732877f8adbca0f7b Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 3 Oct 2023 17:03:08 +0200 Subject: [PATCH 20/40] Fix module and gate-type tests --- include/hal_core/netlist/pins/pin_group.h | 32 ++++++++----- .../netlist_modification_decorator.cpp | 2 +- src/netlist/gate_library/gate_type.cpp | 33 ++++++++++---- src/netlist/module.cpp | 32 +++++++++---- tests/netlist/module.cpp | 45 +++++++++++++------ 5 files changed, 101 insertions(+), 43 deletions(-) diff --git a/include/hal_core/netlist/pins/pin_group.h b/include/hal_core/netlist/pins/pin_group.h index 2e125ff46b9..31f0f526cab 100644 --- a/include/hal_core/netlist/pins/pin_group.h +++ b/include/hal_core/netlist/pins/pin_group.h @@ -426,18 +426,20 @@ namespace hal * Remove a pin from the pin group. * * @param[in] pin - The pin to remove. - * @returns Ok on success, an error message otherwise. + * @returns true on success, false otherwise. */ - Result remove_pin(T* pin) + bool remove_pin(T* pin) { if (pin == nullptr) { - return ERR("'nullptr' given instead of a pin when trying to remove pin from pin group '" + m_name + "' with ID " + std::to_string(m_id)); + log_warning("pin_group", "'nullptr' given instead of a pin when trying to remove pin from pin group '{}' with ID {}.", m_name, m_id); + return false; } if (pin->m_group.first != this) { - return ERR("pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " does not belong to pin group '" + m_name + "' with ID " + std::to_string(m_id)); + log_warning("pin_group", "pin '{}' with ID {} does not belong to pin group '{}' with ID {}.", pin->get_name(), pin->get_id(), m_name, m_id); + return false; } i32 index = pin->m_group.second; @@ -454,16 +456,24 @@ namespace hal } else { - auto it = std::next(m_pins.begin(), m_start_index - index); - it = m_pins.erase(it); - for (; it != m_pins.end(); it++) + if (m_pins.size()==1) { - std::get<1>((*it)->m_group)++; + m_pins.clear(); + m_next_index++; } - m_next_index++; - } + else + { + auto it = m_pins.begin(); + for (int i=m_start_index; i>index;i--) + { + std::get<1>((*(it++))->m_group)--; + } + m_pins.erase(it); + --m_start_index; + } + } - return OK({}); + return true; } /** diff --git a/src/netlist/decorators/netlist_modification_decorator.cpp b/src/netlist/decorators/netlist_modification_decorator.cpp index 73bd446de32..102ac6087c7 100644 --- a/src/netlist/decorators/netlist_modification_decorator.cpp +++ b/src/netlist/decorators/netlist_modification_decorator.cpp @@ -292,7 +292,7 @@ namespace hal // remove pin from current pin group auto current_pin_group = pin->get_group().first; // This get is safe, since we make sure that the pin is a valid pointer and part of the group - current_pin_group->remove_pin(pin).get(); + current_pin_group->remove_pin(pin); // delete old pin group incase it is now empty if (current_pin_group->get_pins().empty()) diff --git a/src/netlist/gate_library/gate_type.cpp b/src/netlist/gate_library/gate_type.cpp index 3a4050ed2f4..7c23a250fd2 100644 --- a/src/netlist/gate_library/gate_type.cpp +++ b/src/netlist/gate_library/gate_type.cpp @@ -370,6 +370,12 @@ namespace hal } PinGroup* pin_group; + if (!ascending && !pins.empty()) + { + // compensate for shifting the start index + start_index -= (pins.size()-1); + } + if (auto res = create_pin_group_internal(id, name, direction, type, ascending, start_index); res.is_error()) { return ERR_APPEND(res.get_error(), "could not create pin group '" + name + "' for gate type '" + m_name + "' with ID " + std::to_string(m_id)); @@ -379,13 +385,23 @@ namespace hal pin_group = res.get(); } - for (auto* pin : pins) + if (ascending) { - if (auto res = assign_pin_to_group(pin_group, pin, delete_empty_groups); res.is_error()) - { - assert(delete_pin_group(pin_group)); - return ERR(res.get_error()); - } + for (auto it = pins.begin(); it != pins.end(); ++it) + if (auto res = assign_pin_to_group(pin_group, *it, delete_empty_groups); res.is_error()) + { + assert(delete_pin_group(pin_group)); + return ERR(res.get_error()); + } + } + else + { + for (auto it = pins.rbegin(); it != pins.rend(); ++it) + if (auto res = assign_pin_to_group(pin_group, *it, delete_empty_groups); res.is_error()) + { + assert(delete_pin_group(pin_group)); + return ERR(res.get_error()); + } } return OK(pin_group); @@ -488,10 +504,9 @@ namespace hal if (PinGroup* pg = pin->get_group().first; pg != nullptr) { // remove from old group and potentially delete old group if empty - if (auto res = pg->remove_pin(pin); res.is_error()) + if (!pg->remove_pin(pin)) { - return ERR_APPEND(res.get_error(), - "could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + return ERR("could not assign pin '" + pin->get_name() + "' with ID " + std::to_string(pin->get_id()) + " to pin group '" + pin_group->get_name() + "' with ID " + std::to_string(pin_group->get_id()) + " of gate type '" + m_name + "' with ID " + std::to_string(m_id) + ": unable to remove pin from pin group '" + pg->get_name() + "' with ID " + std::to_string(pg->get_id())); } diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 0226d386288..79fc829e7c3 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -1243,6 +1243,12 @@ namespace hal } PinGroup* pin_group; + if (!ascending && !pins.empty()) + { + // compensate for shifting the start index + start_index -= (pins.size()-1); + } + if (auto res = create_pin_group_internal(id, name, direction, type, ascending, start_index); res.is_error()) { return ERR_APPEND(res.get_error(), "could not create pin group '" + name + "' for module '" + m_name + "' with ID " + std::to_string(m_id)); @@ -1252,13 +1258,23 @@ namespace hal pin_group = res.get(); } - for (auto* pin : pins) + if (ascending) { - if (!assign_pin_to_group(pin_group, pin, delete_empty_groups)) - { - assert(delete_pin_group(pin_group)); - return ERR("Assign pin to group failed."); - } + for (auto it = pins.begin(); it != pins.end(); ++it) + if (!assign_pin_to_group(pin_group, *it, delete_empty_groups)) + { + assert(delete_pin_group(pin_group)); + return ERR("Assign pin to group failed."); + } + } + else + { + for (auto it = pins.rbegin(); it != pins.rend(); ++it) + if (!assign_pin_to_group(pin_group, *it, delete_empty_groups)) + { + assert(delete_pin_group(pin_group)); + return ERR("Assign pin to group failed."); + } } PinChangedEvent(this,PinEvent::GroupCreate,pin_group->get_id()).send(); @@ -1390,7 +1406,7 @@ namespace hal if (PinGroup* pg = pin->get_group().first; pg != nullptr) { // remove from old group and potentially delete old group if empty - if (auto res = pg->remove_pin(pin); res.is_error()) + if (!pg->remove_pin(pin)) { log_warning("module", "could not assign pin '{}' with ID {} to pin group '{}' with ID {} of module '{}' with ID {}: unable to remove pin from pin group '{}' with ID {}", @@ -1574,7 +1590,7 @@ namespace hal PinGroup* pin_group = pin->get_group().first; assert(pin_group != nullptr); - if (auto res = pin_group->remove_pin(pin); res.is_error()) + if (!pin_group->remove_pin(pin)) { log_warning("module", "could not remove pin '{}' with ID {} from net '{}' with ID {}: failed to remove pin from pin group '{}' with ID {}", pin->get_name(), pin->get_id(), net->get_name(), net->get_id(), pin_group->get_name(), pin_group->get_id()); return false; diff --git a/tests/netlist/module.cpp b/tests/netlist/module.cpp index e8dd56823e4..5e4dc48c573 100644 --- a/tests/netlist/module.cpp +++ b/tests/netlist/module.cpp @@ -1110,6 +1110,9 @@ namespace hal { // create input pin group auto res = m_1->create_pin_group("I", {in_pin_0, in_pin_1}, PinDirection::input, PinType::none, false, 2); ASSERT_TRUE(res.is_ok()); + // descending group start index 2 + // in_pin_0 "I0" index 2 + // in_pin_1 "I1" index 1 PinGroup* in_group = res.get(); ASSERT_NE(in_group, nullptr); EXPECT_EQ(m_1->get_pin_groups().size(), 3); @@ -1138,6 +1141,9 @@ namespace hal { // move pins within group EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 2)); + // descending group start index 2 + // in_pin_1 "I1" index 2 + // in_pin_0 "I0" index 1 EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(1))); EXPECT_EQ(in_group->get_index(in_pin_0).get(), 1); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(2))); @@ -1145,34 +1151,45 @@ namespace hal { EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_0); EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); - EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 1)); + EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_0, 2)); + // descending group start index 2 + // in_pin_0 "I0" index 2 + // in_pin_1 "I1" index 1 EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(2))); EXPECT_EQ(in_group->get_index(in_pin_0).get(), 2); EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(1))); EXPECT_EQ(in_group->get_index(in_pin_1).get(), 1); EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_0); - EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_1); + EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_1); // remove pin from group EXPECT_TRUE(m_1->remove_pin_from_group(in_group, in_pin_0)); - EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(2))); - EXPECT_EQ(in_group->get_index(in_pin_1).get(), 2); - EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); + // descending group start index 1 + // in_pin_1 "I1" index 1 + EXPECT_EQ(in_group->get_start_index(), 1); + EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(1))); + EXPECT_EQ(in_group->get_index(in_pin_1).get(), 1); + EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_1); EXPECT_EQ(in_pin_0->get_group().first->get_name(), in_pin_0->get_name()); EXPECT_EQ(in_pin_0->get_group().second, 0); + + // assign pin to group EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0)); + // descending group start index 2 + // in_pin_0 "I0" index 2 + // in_pin_1 "I1" index 1 EXPECT_EQ(in_group->size(), 2); - // assign pin to group + // assign same pin twice should not do anything EXPECT_TRUE(m_1->assign_pin_to_group(in_group, in_pin_0)); EXPECT_EQ(m_1->get_pin_groups().size(), 3); EXPECT_EQ(in_group->size(), 2); - EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(1))); - EXPECT_EQ(in_group->get_index(in_pin_0).get(), 1); - EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(2))); - EXPECT_EQ(in_group->get_index(in_pin_1).get(), 2); - EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_0); - EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); + EXPECT_EQ(in_pin_0->get_group(), std::pair(in_group, i32(2))); + EXPECT_EQ(in_group->get_index(in_pin_0).get(), 2); + EXPECT_EQ(in_pin_1->get_group(), std::pair(in_group, i32(1))); + EXPECT_EQ(in_group->get_index(in_pin_1).get(), 1); + EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_0); + EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_1); } } TEST_END @@ -1257,8 +1274,8 @@ namespace hal { std::make_tuple(ModuleEvent::event::submodule_added, test_mod, other_mod_sub->get_id()), std::make_tuple(ModuleEvent::event::submodule_removed, test_mod, other_mod_sub->get_id()), std::make_tuple(ModuleEvent::event::gate_assigned, test_mod, test_gate->get_id()), - std::make_tuple(ModuleEvent::event::pin_changed, test_mod, NO_DATA), - std::make_tuple(ModuleEvent::event::pin_changed, test_mod, NO_DATA), + std::make_tuple(ModuleEvent::event::pin_changed, test_mod, PinChangedEvent(test_mod,PinEvent::PinRename,3).associated_data()), + std::make_tuple(ModuleEvent::event::pin_changed, test_mod, PinChangedEvent(test_mod,PinEvent::PinRename,1).associated_data()), std::make_tuple(ModuleEvent::event::gate_removed, test_mod, test_gate->get_id()) }; From e9c95958abea7ae6fe9c2f9cb926fb4b29e61328 Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 3 Oct 2023 19:23:05 +0200 Subject: [PATCH 21/40] HGL-writer test fixed --- .../src/gate_library_test_utils.cpp | 82 +++++++++++-------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/tests/test_utils/src/gate_library_test_utils.cpp b/tests/test_utils/src/gate_library_test_utils.cpp index 019ee656453..83d94cb8edd 100644 --- a/tests/test_utils/src/gate_library_test_utils.cpp +++ b/tests/test_utils/src/gate_library_test_utils.cpp @@ -424,41 +424,45 @@ namespace hal { const auto grp = res_grp.get(); - if (auto res = carry4->create_pin("DI(3)", PinDirection::input, PinType::none, false); res.is_error()) + std::list pins; + if (auto res = carry4->create_pin("DI(0)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("DI(2)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("DI(1)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("DI(1)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("DI(2)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("DI(0)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("DI(3)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } + + for (auto pin : pins) + grp->assign_pin(pin); } if (auto res_grp = carry4->create_pin_group("S", {}, PinDirection::input, PinType::none, false, 3); res_grp.is_error()) @@ -469,41 +473,45 @@ namespace hal { const auto grp = res_grp.get(); - if (auto res = carry4->create_pin("S(3)", PinDirection::input, PinType::none, false); res.is_error()) + std::list pins; + if (auto res = carry4->create_pin("S(0)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("S(2)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("S(1)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("S(1)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("S(2)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("S(0)", PinDirection::input, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("S(3)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } + + for (auto pin : pins) + grp->assign_pin(pin); } if (auto res_grp = carry4->create_pin_group("CO", {}, PinDirection::output, PinType::carry, false, 3); res_grp.is_error()) @@ -514,41 +522,45 @@ namespace hal { const auto grp = res_grp.get(); - if (auto res = carry4->create_pin("CO(3)", PinDirection::output, PinType::carry, false); res.is_error()) + std::list pins; + if (auto res = carry4->create_pin("CO(0)", PinDirection::output, PinType::carry, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("CO(2)", PinDirection::output, PinType::carry, false); res.is_error()) + if (auto res = carry4->create_pin("CO(1)", PinDirection::output, PinType::carry, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("CO(1)", PinDirection::output, PinType::carry, false); res.is_error()) + if (auto res = carry4->create_pin("CO(2)", PinDirection::output, PinType::carry, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("CO(0)", PinDirection::output, PinType::carry, false); res.is_error()) + if (auto res = carry4->create_pin("CO(3)", PinDirection::output, PinType::carry, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } + + for (auto pin : pins) + grp->assign_pin(pin); } if (auto res_grp = carry4->create_pin_group("O", {}, PinDirection::output, PinType::none, false, 3); res_grp.is_error()) @@ -559,41 +571,45 @@ namespace hal { const auto grp = res_grp.get(); - if (auto res = carry4->create_pin("O(3)", PinDirection::output, PinType::none, false); res.is_error()) + std::list pins; + if (auto res = carry4->create_pin("O(0)", PinDirection::output, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("O(2)", PinDirection::output, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("O(1)", PinDirection::output, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("O(1)", PinDirection::output, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("O(2)", PinDirection::output, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } - if (auto res = carry4->create_pin("O(0)", PinDirection::output, PinType::none, false); res.is_error()) + if (auto res = carry4->create_pin("O(3)", PinDirection::output, PinType::none, false); res.is_error()) { return nullptr; } else { - grp->assign_pin(res.get()); + pins.push_front(res.get()); } + + for (auto pin : pins) + grp->assign_pin(pin); } carry4->add_boolean_function("CO(0)", BooleanFunction::from_string("((S(0) & (CI | CYINIT)) | ((! S(0)) & DI(0)))").get()); @@ -1510,4 +1526,4 @@ namespace hal return is_equal; } } // namespace test_utils -} // namespace hal \ No newline at end of file +} // namespace hal From cfb43bc214a955d96c9a609d973e31aecad8985c Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 4 Oct 2023 19:00:30 +0200 Subject: [PATCH 22/40] Pin- and pingroup automatted tests should be fixed by now --- .../src/gate_library_test_utils.cpp | 299 +++++++++--------- 1 file changed, 147 insertions(+), 152 deletions(-) diff --git a/tests/test_utils/src/gate_library_test_utils.cpp b/tests/test_utils/src/gate_library_test_utils.cpp index 83d94cb8edd..c074221da03 100644 --- a/tests/test_utils/src/gate_library_test_utils.cpp +++ b/tests/test_utils/src/gate_library_test_utils.cpp @@ -12,6 +12,21 @@ namespace hal { namespace test_utils { + + void dumpPingroups(const GateType *gt) + { + std::cerr << "gate type: " << gt->get_id() << " <" << gt->get_name() << ">\n"; + for (PinGroup* pg : gt->get_pin_groups()) + { + std::cerr << " grp: " << pg->get_id() << (pg->is_ascending()?" asc ": " des ") << pg->get_start_index() + << " <" << pg->get_name() << ">\n"; + for (GatePin* pin : pg->get_pins()) + std::cerr << " pin: " << pin->get_id() << " inx:" << pin->get_group().second << " <" << pin->get_name() << ">\n"; + } + std::cerr << "-------------" << std::endl; + } + + std::unique_ptr create_gate_library(const std::filesystem::path& file_path) { std::unique_ptr lib = std::unique_ptr(new GateLibrary(file_path, "TESTING_GATE_LIBRARY")); @@ -416,201 +431,179 @@ namespace hal return nullptr; } - if (auto res_grp = carry4->create_pin_group("DI", {}, PinDirection::input, PinType::none, false, 3); res_grp.is_error()) + std::vector temp_pins; + + //--- pingroup DI --- + if (auto res = carry4->create_pin("DI(3)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - const auto grp = res_grp.get(); - - std::list pins; - if (auto res = carry4->create_pin("DI(0)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("DI(1)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("DI(2)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("DI(2)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("DI(1)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("DI(3)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("DI(0)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - for (auto pin : pins) - grp->assign_pin(pin); + if (auto res_grp = carry4->create_pin_group("DI", temp_pins, PinDirection::input, PinType::none, false, 3); res_grp.is_error()) + { + return nullptr; } + temp_pins.clear(); - if (auto res_grp = carry4->create_pin_group("S", {}, PinDirection::input, PinType::none, false, 3); res_grp.is_error()) + //--- pingroup S ---- + if (auto res = carry4->create_pin("S(3)", PinDirection::input, PinType::none, false); res.is_error()) { return nullptr; } else { - const auto grp = res_grp.get(); - - std::list pins; - if (auto res = carry4->create_pin("S(0)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("S(1)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("S(2)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("S(2)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("S(1)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("S(3)", PinDirection::input, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("S(0)", PinDirection::input, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - for (auto pin : pins) - grp->assign_pin(pin); + if (auto res_grp = carry4->create_pin_group("S", temp_pins, PinDirection::input, PinType::none, false, 3); res_grp.is_error()) + { + return nullptr; } + temp_pins.clear(); - if (auto res_grp = carry4->create_pin_group("CO", {}, PinDirection::output, PinType::carry, false, 3); res_grp.is_error()) + //--- pingroup CO --- + if (auto res = carry4->create_pin("CO(3)", PinDirection::output, PinType::carry, false); res.is_error()) { return nullptr; } else { - const auto grp = res_grp.get(); - - std::list pins; - if (auto res = carry4->create_pin("CO(0)", PinDirection::output, PinType::carry, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("CO(1)", PinDirection::output, PinType::carry, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("CO(2)", PinDirection::output, PinType::carry, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("CO(2)", PinDirection::output, PinType::carry, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("CO(1)", PinDirection::output, PinType::carry, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("CO(3)", PinDirection::output, PinType::carry, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("CO(0)", PinDirection::output, PinType::carry, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - for (auto pin : pins) - grp->assign_pin(pin); + if (auto res_grp = carry4->create_pin_group("CO", temp_pins, PinDirection::output, PinType::carry, false, 3); res_grp.is_error()) + { + return nullptr; } + temp_pins.clear(); - if (auto res_grp = carry4->create_pin_group("O", {}, PinDirection::output, PinType::none, false, 3); res_grp.is_error()) + //--- pingroup O ---- + if (auto res = carry4->create_pin("O(3)", PinDirection::output, PinType::none, false); res.is_error()) { return nullptr; } else { - const auto grp = res_grp.get(); - - std::list pins; - if (auto res = carry4->create_pin("O(0)", PinDirection::output, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("O(1)", PinDirection::output, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("O(2)", PinDirection::output, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("O(2)", PinDirection::output, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("O(1)", PinDirection::output, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - if (auto res = carry4->create_pin("O(3)", PinDirection::output, PinType::none, false); res.is_error()) - { - return nullptr; - } - else - { - pins.push_front(res.get()); - } + if (auto res = carry4->create_pin("O(0)", PinDirection::output, PinType::none, false); res.is_error()) + { + return nullptr; + } + else + { + temp_pins.push_back(res.get()); + } - for (auto pin : pins) - grp->assign_pin(pin); + if (auto res_grp = carry4->create_pin_group("O", temp_pins, PinDirection::output, PinType::none, false, 3); res_grp.is_error()) + { + return nullptr; } + temp_pins.clear(); carry4->add_boolean_function("CO(0)", BooleanFunction::from_string("((S(0) & (CI | CYINIT)) | ((! S(0)) & DI(0)))").get()); carry4->add_boolean_function("CO(1)", BooleanFunction::from_string("((S(1) & CO(0)) | ((! S(1)) & DI(1)))").get()); @@ -1389,6 +1382,8 @@ namespace hal if (!gate_pin_groups_are_equal(*pg1_it, *pg2_it)) { log_info("test_utils", "unequal pin groups of gate types with names '{}' and '{}'", gt1->get_name(), gt2->get_name()); + test_utils::dumpPingroups(gt1); + test_utils::dumpPingroups(gt2); return false; } } From 947a6dd2f5591781f87960f34ba719957365648a Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 5 Oct 2023 17:12:40 +0200 Subject: [PATCH 23/40] Modification in pin test reverted --- tests/netlist/module.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/netlist/module.cpp b/tests/netlist/module.cpp index 5e4dc48c573..1c85e69f817 100644 --- a/tests/netlist/module.cpp +++ b/tests/netlist/module.cpp @@ -1151,7 +1151,7 @@ namespace hal { EXPECT_EQ(in_group->get_pin_at_index(1).get(), in_pin_0); EXPECT_EQ(in_group->get_pin_at_index(2).get(), in_pin_1); - EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_0, 2)); + EXPECT_TRUE(m_1->move_pin_within_group(in_group, in_pin_1, 1)); // descending group start index 2 // in_pin_0 "I0" index 2 // in_pin_1 "I1" index 1 From f084a8b7b7842ef72a4035664e980e15ee34e2e7 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 15 Jan 2024 15:10:18 +0100 Subject: [PATCH 24/40] added macro for VALGRIND profiling --- include/hal_core/netlist/netlist.h | 1 + src/netlist/netlist.cpp | 10 ++++++++++ src/python_bindings/bindings/netlist.cpp | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/hal_core/netlist/netlist.h b/include/hal_core/netlist/netlist.h index 415db8badbf..4ecadfc8006 100644 --- a/include/hal_core/netlist/netlist.h +++ b/include/hal_core/netlist/netlist.h @@ -473,6 +473,7 @@ namespace hal * @returns The new module on success, nullptr otherwise. */ Module* create_module(const std::string& name, Module* parent, const std::vector& gates = {}); + Module* create_module_python(const std::string& name, Module* parent, const std::vector& gates = {}); /** * Remove a module from the netlist. diff --git a/src/netlist/netlist.cpp b/src/netlist/netlist.cpp index 24a364b8992..bc73520dd93 100644 --- a/src/netlist/netlist.cpp +++ b/src/netlist/netlist.cpp @@ -7,6 +7,7 @@ #include "hal_core/netlist/net.h" #include "hal_core/netlist/netlist_internal_manager.h" #include "hal_core/utilities/log.h" +#include namespace hal { @@ -566,6 +567,15 @@ namespace hal return create_module(get_unique_module_id(), name, parent, gates); } + Module* Netlist::create_module_python(const std::string &name, Module *parent, const std::vector &gates) + { + CALLGRIND_START_INSTRUMENTATION; + CALLGRIND_TOGGLE_COLLECT; + return create_module(get_unique_module_id(), name, parent, gates); + CALLGRIND_TOGGLE_COLLECT; + CALLGRIND_STOP_INSTRUMENTATION; + } + bool Netlist::delete_module(Module* module) { return m_manager->delete_module(module); diff --git a/src/python_bindings/bindings/netlist.cpp b/src/python_bindings/bindings/netlist.cpp index 3b30eb2b882..1a15960835a 100644 --- a/src/python_bindings/bindings/netlist.cpp +++ b/src/python_bindings/bindings/netlist.cpp @@ -500,7 +500,7 @@ namespace hal )"); py_netlist.def("create_module", - py::overload_cast&>(&Netlist::create_module), + &Netlist::create_module_python, py::arg("name"), py::arg("parent"), py::arg("gates") = std::vector(), From 2ed2c7798c51f4b8b761bd9a99b26beae69d1686 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 17 Jan 2024 21:35:31 +0100 Subject: [PATCH 25/40] 1.ModuleModel instance moved to ModuleWidget 2.net assignment accelerated --- .../include/gui/module_model/module_model.h | 48 +++-- .../include/gui/module_widget/module_widget.h | 9 + .../include/gui/netlist_relay/netlist_relay.h | 9 - .../gui/src/module_dialog/module_dialog.cpp | 3 +- plugins/gui/src/module_model/module_model.cpp | 167 ++++++++++++++++-- .../gui/src/module_widget/module_widget.cpp | 27 ++- .../gui/src/netlist_relay/netlist_relay.cpp | 25 +-- 7 files changed, 228 insertions(+), 60 deletions(-) diff --git a/plugins/gui/include/gui/module_model/module_model.h b/plugins/gui/include/gui/module_model/module_model.h index 11086efdb05..edd4ecd76e8 100644 --- a/plugins/gui/include/gui/module_model/module_model.h +++ b/plugins/gui/include/gui/module_model/module_model.h @@ -171,15 +171,6 @@ namespace hal */ void removeNet(const u32 id); - /** - * Moves the ModuleItem corresponding to the module under it's new parent ModuleItem. - * The items for all nets, that have at least one source or one destination within the module, - * will be updated afterwards. - * - * @param module The module whose parent has changed. - */ - void handleModuleParentChanged(const Module* module); - /** * Handles the assigment of gates to modules. * If the gate does not yet exist in the item model, a new one is created. @@ -195,7 +186,7 @@ namespace hal * * @param net The net whose source or destination might have changed. */ - void updateNet(const Net* net); + void updateNet(const Net* net, const QHash* parentAssignment = nullptr); /** * Reattaches the ModuleItem corresponding to the specified module to a new parent item. @@ -235,6 +226,41 @@ namespace hal */ bool isModifying(); + void debugDump() const; + + private Q_SLOTS: + void handleModuleNameChanged(Module* mod); + + void handleModuleRemoved(Module* mod); + + void handleModuleCreated(Module* mod); + + /** + * Moves the ModuleItem corresponding to the module under it's new parent ModuleItem. + * The items for all nets, that have at least one source or one destination within the module, + * will be updated afterwards. + * + * @param module The module whose parent has changed. + */ + void handleModuleParentChanged(const Module* module); + + void handleModuleGateAssigned(Module* mod, u32 gateId); + + void handleModuleGateRemoved(Module* mod, u32 gateId); + + void handleModuleGatesAssignBegin(Module* mod, u32 numberGates); + + void handleModuleGatesAssignEnd(Module* mod, u32 numberGates); + + void handleGateNameChanged(Gate* gat); + + void handleNetCreated(Net* net); + + void handleNetRemoved(Net* net); + + void handleNetNameChanged(Net* net); + + void handleNetUpdated(Net* net, u32 data); private: /** * Searches for a new parent module, such that it is the deepest module in the hierarchy, that contains all @@ -246,6 +272,8 @@ namespace hal * (e.g. net has no sources or destinations), nullptr is returned instead. */ Module* findNetParent(const Net* net); + void updateAllNets(); + void findNetParentRecursion(BaseTreeItem* parent, QHash& parentAssignment, std::unordered_set& assignedNets) const; QMap mModuleMap; QMap mGateMap; diff --git a/plugins/gui/include/gui/module_widget/module_widget.h b/plugins/gui/include/gui/module_widget/module_widget.h index fb18026a2c7..115a6e7199c 100644 --- a/plugins/gui/include/gui/module_widget/module_widget.h +++ b/plugins/gui/include/gui/module_widget/module_widget.h @@ -45,6 +45,7 @@ class QTreeView; namespace hal { + class ModuleModel; class ModuleProxyModel; /** @@ -93,6 +94,13 @@ namespace hal */ virtual QList createShortcuts() override; + /** + * Accesses the module model. + * + * @returns the module model + */ + ModuleModel* getModuleModel() const; + /** * Opens a existing view that contains the given module, otherwise creates a new context * and opens it. @@ -268,6 +276,7 @@ namespace hal bool mIgnoreSelectionChange; + ModuleModel* mModuleModel; ModuleProxyModel* mModuleProxyModel; QShortcut* mShortCutDeleteItem; diff --git a/plugins/gui/include/gui/netlist_relay/netlist_relay.h b/plugins/gui/include/gui/netlist_relay/netlist_relay.h index 84be264ba83..e8cc5c3275e 100644 --- a/plugins/gui/include/gui/netlist_relay/netlist_relay.h +++ b/plugins/gui/include/gui/netlist_relay/netlist_relay.h @@ -35,7 +35,6 @@ namespace hal { class ModuleItem; - class ModuleModel; class ModuleColorManager; class ModuleColorSerializer; class Module; @@ -87,13 +86,6 @@ namespace hal */ QColor getModuleColor(const u32 id); - /** - * Accesses the module model. - * - * @returns the module model - */ - ModuleModel* getModuleModel() const; - /** * Accesses the module color manager * @@ -620,7 +612,6 @@ namespace hal bool mNotified; QMap mModuleColors; - ModuleModel* mModuleModel; ModuleColorManager* mModuleColorManager; ModuleColorSerializer mColorSerializer; enum ThreadEventType { TetNetlist, TetModule, TetGate, TetNet, TetGrouping }; diff --git a/plugins/gui/src/module_dialog/module_dialog.cpp b/plugins/gui/src/module_dialog/module_dialog.cpp index c2b58d9c436..f3502409b54 100644 --- a/plugins/gui/src/module_dialog/module_dialog.cpp +++ b/plugins/gui/src/module_dialog/module_dialog.cpp @@ -4,6 +4,7 @@ #include "gui/module_model/module_model.h" #include "gui/module_model/module_proxy_model.h" #include "gui/module_model/module_item.h" +#include "gui/module_widget/module_widget.h" #include "gui/graph_tab_widget/graph_tab_widget.h" #include "gui/searchbar/searchbar.h" #include "gui/content_manager/content_manager.h" @@ -81,7 +82,7 @@ namespace hal { mModuleTreeProxyModel = new ModuleProxyModel(this); mModuleTreeProxyModel->setFilterKeyColumn(-1); mModuleTreeProxyModel->setDynamicSortFilter(true); - mModuleTreeProxyModel->setSourceModel(gNetlistRelay->getModuleModel()); + mModuleTreeProxyModel->setSourceModel(gContentManager->getModuleWidget()->getModuleModel()); mTreeView->setModel(mModuleTreeProxyModel); mTreeView->expandAll(); diff --git a/plugins/gui/src/module_model/module_model.cpp b/plugins/gui/src/module_model/module_model.cpp index 7c645b97364..103c8784dc6 100644 --- a/plugins/gui/src/module_model/module_model.cpp +++ b/plugins/gui/src/module_model/module_model.cpp @@ -13,6 +13,22 @@ namespace hal { // use root item to store header information setHeaderLabels(QStringList() << "Name" << "ID" << "Type"); + connect(gNetlistRelay, &NetlistRelay::moduleCreated, this, &ModuleModel::handleModuleCreated); + connect(gNetlistRelay, &NetlistRelay::moduleNameChanged, this, &ModuleModel::handleModuleNameChanged); + connect(gNetlistRelay, &NetlistRelay::moduleParentChanged, this, &ModuleModel::handleModuleParentChanged); + connect(gNetlistRelay, &NetlistRelay::moduleGateAssigned, this, &ModuleModel::handleModuleGateAssigned); + connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignBegin, this, &ModuleModel::handleModuleGatesAssignBegin); + connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignEnd, this, &ModuleModel::handleModuleGatesAssignEnd); + connect(gNetlistRelay, &NetlistRelay::moduleGateRemoved, this, &ModuleModel::handleModuleGateRemoved); + connect(gNetlistRelay, &NetlistRelay::moduleRemoved, this, &ModuleModel::handleModuleRemoved); + connect(gNetlistRelay, &NetlistRelay::gateNameChanged, this, &ModuleModel::handleGateNameChanged); + connect(gNetlistRelay, &NetlistRelay::netCreated, this, &ModuleModel::handleNetCreated); + connect(gNetlistRelay, &NetlistRelay::netRemoved, this, &ModuleModel::handleNetRemoved); + connect(gNetlistRelay, &NetlistRelay::netNameChanged, this, &ModuleModel::handleNetNameChanged); + connect(gNetlistRelay, &NetlistRelay::netSourceAdded, this, &ModuleModel::handleNetUpdated); + connect(gNetlistRelay, &NetlistRelay::netSourceRemoved, this, &ModuleModel::handleNetUpdated); + connect(gNetlistRelay, &NetlistRelay::netDestinationAdded, this, &ModuleModel::handleNetUpdated); + connect(gNetlistRelay, &NetlistRelay::netDestinationRemoved, this, &ModuleModel::handleNetUpdated); } QVariant ModuleModel::data(const QModelIndex& index, int role) const @@ -255,6 +271,71 @@ namespace hal delete item; } + void ModuleModel::handleModuleNameChanged(Module* mod) + { + updateModuleName(mod->get_id()); + } + + void ModuleModel::handleModuleRemoved(Module* mod) + { + removeModule(mod->get_id()); + } + + void ModuleModel::handleModuleCreated(Module* mod) + { + if (mod->get_parent_module() == nullptr) return; + addModule(mod->get_id(), mod->get_parent_module()->get_id()); + } + + void ModuleModel::handleModuleGateAssigned(Module* mod, u32 gateId) + { + handleModuleGateAssinged(gateId, mod->get_id()); + } + + void ModuleModel::handleModuleGateRemoved(Module* mod, u32 gateId) + { + Q_UNUSED(mod); + removeGate(gateId); + } + + void ModuleModel::handleModuleGatesAssignBegin(Module* mod, u32 numberGates) + { + Q_UNUSED(mod); + Q_UNUSED(numberGates); + } + + void ModuleModel::handleModuleGatesAssignEnd(Module* mod, u32 numberGates) + { + Q_UNUSED(mod); + Q_UNUSED(numberGates); + } + + void ModuleModel::handleGateNameChanged(Gate* gat) + { + updateGateName(gat->get_id()); + } + + void ModuleModel::handleNetCreated(Net* net) + { + addNet(net->get_id(), gNetlist->get_top_module()->get_id()); + } + + void ModuleModel::handleNetRemoved(Net* net) + { + removeNet(net->get_id()); + } + + void ModuleModel::handleNetNameChanged(Net* net) + { + updateNetName(net->get_id()); + } + + void ModuleModel::handleNetUpdated(Net* net, u32 data) + { + Q_UNUSED(data); + updateNet(net); + } + void ModuleModel::removeNet(const u32 id) { //assert(gNetlist->get_net_by_id(id)); @@ -289,6 +370,54 @@ namespace hal updateNet(net); } + void ModuleModel::findNetParentRecursion(BaseTreeItem* parent, QHash &parentAssignment, std::unordered_set& assignedNets) const + { + for (BaseTreeItem* bti : parent->getChildren()) + { + ModuleItem* item = dynamic_cast(bti); + if (!item || item->getType() != ModuleItem::TreeItemType::Module) continue; + findNetParentRecursion(item, parentAssignment, assignedNets); + Module* m = gNetlist->get_module_by_id(item->id()); + Q_ASSERT(m); + std::unordered_set internalNets = m->get_internal_nets(); + if (!internalNets.empty()) + { + for (Net* n : assignedNets) + internalNets.erase(n); + for (Net* n : m->get_input_nets()) + internalNets.erase(n); + for (Net* n : m->get_output_nets()) + internalNets.erase(n); + } + for (Net* n : internalNets) + { + parentAssignment[n] = item; + assignedNets.insert(n); + } + } + } + + void ModuleModel::debugDump() const + { + QHash parentAssignment; + std::unordered_set assignedNets; + findNetParentRecursion(mRootItem, parentAssignment, assignedNets); + + QTextStream xout(stdout, QIODevice::WriteOnly); + for (auto it = mModuleMap.begin(); it != mModuleMap.end(); ++it) + { + xout << it.value()->id() << " " << it.value()->name() << " "; + + for (auto jt = parentAssignment.constBegin(); jt != parentAssignment.constEnd(); ++jt) + { + if (it.value() != jt.value()) continue; + xout << " <" << jt.key()->get_id() << ">"; + } + xout << "\n"; + } + xout.flush(); + } + void ModuleModel::handleModuleGateAssinged(const u32 id, const u32 parent_module) { // Don't need new function handleModuleGateRemoved(), because the GateAssinged event always follows GateRemoved @@ -296,15 +425,19 @@ namespace hal if(!mGateMap.contains(id)) addGate(id, parent_module); - + + QHash parentAssignment; + std::unordered_set assignedNets; + findNetParentRecursion(mRootItem, parentAssignment, assignedNets); + Gate* gate = gNetlist->get_gate_by_id(id); for(Net* in_net : gate->get_fan_in_nets()) - updateNet(in_net); + updateNet(in_net, &parentAssignment); for(Net* in_net : gate->get_fan_out_nets()) - updateNet(in_net); + updateNet(in_net, &parentAssignment); } - void ModuleModel::updateNet(const Net* net) + void ModuleModel::updateNet(const Net* net, const QHash *parentAssignment) { assert(net); u32 id = net->get_id(); @@ -316,14 +449,28 @@ namespace hal ModuleItem* oldParentItem = static_cast(item->getParent()); assert(oldParentItem); - Module* newParentModule = findNetParent(net); - if(newParentModule == nullptr) - newParentModule = gNetlist->get_top_module(); - if(newParentModule->get_id() == oldParentItem->id()) + ModuleItem* newParentItem = nullptr; + if (parentAssignment) + newParentItem = parentAssignment->value(net); + else + { + Module* newParentModule = findNetParent(net); + if(newParentModule == nullptr) + newParentModule = gNetlist->get_top_module(); + newParentItem = mModuleMap[newParentModule->get_id()]; + } + + if (!newParentItem) + { + mIsModifying = true; + oldParentItem->removeChild(item); + mIsModifying = false; + return; + } + + if(newParentItem->id() == oldParentItem->id()) return; - assert(mModuleMap.contains(newParentModule->get_id())); - ModuleItem* newParentItem = mModuleMap[newParentModule->get_id()]; QModelIndex newIndex = getIndex(newParentItem); QModelIndex oldIndex = getIndex(oldParentItem); int row = item->row(); diff --git a/plugins/gui/src/module_widget/module_widget.cpp b/plugins/gui/src/module_widget/module_widget.cpp index bde1cf6be42..aaf294f42bc 100644 --- a/plugins/gui/src/module_widget/module_widget.cpp +++ b/plugins/gui/src/module_widget/module_widget.cpp @@ -62,7 +62,8 @@ namespace hal mRenameAction->setToolTip("Rename"); mToggleExpandTreeAction->setToolTip("Toggle expand all / collapse all"); - mModuleProxyModel->setSourceModel(gNetlistRelay->getModuleModel()); + mModuleModel = new ModuleModel(this); + mModuleProxyModel->setSourceModel(mModuleModel); mTreeView->setModel(mModuleProxyModel); mTreeView->setDefaultColumnWidth(); @@ -78,7 +79,7 @@ namespace hal mTreeView->expandAllModules(); mContentLayout->addWidget(mTreeView); - mSearchbar->setColumnNames(gNetlistRelay->getModuleModel()->headerLabels()); + mSearchbar->setColumnNames(mModuleModel->headerLabels()); mContentLayout->addWidget(mSearchbar); mSearchbar->hide(); @@ -91,7 +92,7 @@ namespace hal connect(mTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ModuleWidget::handleTreeSelectionChanged); connect(mTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModuleWidget::handleCurrentChanged); connect(mTreeView, &ModuleTreeView::doubleClicked, this, &ModuleWidget::handleItemDoubleClicked); - connect(gSelectionRelay, &SelectionRelay::selectionChanged, this, &ModuleWidget::handleSelectionChanged); + connect(gSelectionRelay, &SelectionRelay::selectionChanged, this, &ModuleWidget::handleSelectionChanged, Qt::QueuedConnection); connect(gNetlistRelay, &NetlistRelay::moduleSubmoduleRemoved, this, &ModuleWidget::handleModuleRemoved); connect(mSearchAction, &QAction::triggered, this, &ModuleWidget::toggleSearchbar); @@ -113,6 +114,8 @@ namespace hal connect(mToggleGatesAction, &QAction::triggered, this, &ModuleWidget::handleToggleGatesClicked); connect(mToggleExpandTreeAction, &QAction::triggered, this, &ModuleWidget::handleToggleExpandTreeClicked); connect(mRenameAction, &QAction::triggered, this, &ModuleWidget::handleRenameClicked); + + mModuleModel->init(); } void ModuleWidget::enableDeleteAction(bool enable) @@ -242,6 +245,10 @@ namespace hal QAction delete_action; QAction extractPythonAction; QAction focus_in_view; + QAction debug_dump; + debug_dump.setText("Debug dump"); + debug_dump.setParent(&context_menu); + context_menu.addAction(&debug_dump); switch(type) { @@ -384,6 +391,9 @@ namespace hal } } + if (clicked == &debug_dump) + mModuleModel->debugDump(); + if (clicked == &change_type_action) gNetlistRelay->changeModuleType(getModuleItemFromIndex(index)->id()); @@ -432,7 +442,7 @@ namespace hal Q_UNUSED(selected) Q_UNUSED(deselected) - if (mIgnoreSelectionChange || gNetlistRelay->getModuleModel()->isModifying()) + if (mIgnoreSelectionChange || mModuleModel->isModifying()) return; gSelectionRelay->clear(); @@ -608,7 +618,7 @@ namespace hal for (auto module_id : gSelectionRelay->selectedModulesList()) { - QModelIndex index = mModuleProxyModel->mapFromSource(gNetlistRelay->getModuleModel()->getIndex(gNetlistRelay->getModuleModel()->getItem(module_id))); + QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndex(mModuleModel->getItem(module_id))); module_selection.select(index, index); } @@ -619,7 +629,7 @@ namespace hal ModuleItem* ModuleWidget::getModuleItemFromIndex(const QModelIndex& index) { - return gNetlistRelay->getModuleModel()->getItem(mModuleProxyModel->mapToSource(index)); + return mModuleModel->getItem(mModuleProxyModel->mapToSource(index)); } void ModuleWidget::updateSearchIcon() @@ -630,6 +640,11 @@ namespace hal mSearchAction->setIcon(gui_utility::getStyledSvgIcon(mSearchIconStyle, mSearchIconPath)); } + ModuleModel* ModuleWidget::getModuleModel() const + { + return mModuleModel; + } + QString ModuleWidget::disabledIconStyle() const { return mDisabledIconStyle; diff --git a/plugins/gui/src/netlist_relay/netlist_relay.cpp b/plugins/gui/src/netlist_relay/netlist_relay.cpp index 8473b1bf209..541d46e2655 100644 --- a/plugins/gui/src/netlist_relay/netlist_relay.cpp +++ b/plugins/gui/src/netlist_relay/netlist_relay.cpp @@ -28,7 +28,7 @@ namespace hal { NetlistRelay::NetlistRelay(QObject* parent) - : QObject(parent), mModuleModel(new ModuleModel(this)), mModuleColorManager(new ModuleColorManager(this)) + : QObject(parent), mModuleColorManager(new ModuleColorManager(this)) { connect(FileManager::get_instance(), &FileManager::fileOpened, this, &NetlistRelay::debugHandleFileOpened); // DEBUG LINE connect(this, &NetlistRelay::signalThreadEvent, this, &NetlistRelay::handleThreadEvent, Qt::BlockingQueuedConnection); @@ -85,11 +85,6 @@ namespace hal return mModuleColorManager->moduleColor(id); } - ModuleModel* NetlistRelay::getModuleModel() const - { - return mModuleModel; - } - ModuleColorManager* NetlistRelay::getModuleColorManager() const { return mModuleColorManager; @@ -380,7 +375,6 @@ namespace hal // suppress actions if we receive this for the top module if (mod->get_parent_module() != nullptr) { - mModuleModel->addModule(mod->get_id(), mod->get_parent_module()->get_id()); mModuleColorManager->setRandomColor(mod->get_id()); } @@ -393,7 +387,6 @@ namespace hal //< no associated_data mModuleColorManager->removeColor(mod->get_id()); - mModuleModel->removeModule(mod->get_id()); gGraphContextManager->handleModuleRemoved(mod); gSelectionRelay->handleModuleRemoved(mod->get_id()); @@ -404,8 +397,6 @@ namespace hal case ModuleEvent::event::name_changed: { //< no associated_data - mModuleModel->updateModuleName(mod->get_id()); - gGraphContextManager->handleModuleNameChanged(mod); Q_EMIT moduleNameChanged(mod); @@ -414,8 +405,6 @@ namespace hal case ModuleEvent::event::parent_changed: { //< no associated_data - mModuleModel->handleModuleParentChanged(mod); - Q_EMIT moduleParentChanged(mod); break; } @@ -438,7 +427,6 @@ namespace hal case ModuleEvent::event::gate_assigned: { //< associated_data = id of inserted gate - mModuleModel->handleModuleGateAssinged(associated_data, mod->get_id()); gGraphContextManager->handleModuleGateAssigned(mod, associated_data); Q_EMIT moduleGateAssigned(mod, associated_data); @@ -447,7 +435,6 @@ namespace hal case ModuleEvent::event::gate_removed: { //< associated_data = id of removed gate - mModuleModel->removeGate(associated_data); gGraphContextManager->handleModuleGateRemoved(mod, associated_data); Q_EMIT moduleGateRemoved(mod, associated_data); @@ -536,7 +523,6 @@ namespace hal case GateEvent::event::name_changed: { //< no associated_data - mModuleModel->updateGateName(gat->get_id()); gGraphContextManager->handleGateNameChanged(gat); Q_EMIT gateNameChanged(gat); @@ -581,7 +567,6 @@ namespace hal case NetEvent::event::created: { //< no associated_data - mModuleModel->addNet(net->get_id(), gNetlist->get_top_module()->get_id()); gGraphContextManager->handleNetCreated(net); Q_EMIT netCreated(net); @@ -590,7 +575,6 @@ namespace hal case NetEvent::event::removed: { //< no associated_data - mModuleModel->removeNet(net->get_id()); gGraphContextManager->handleNetRemoved(net); gSelectionRelay->handleNetRemoved(net->get_id()); @@ -600,7 +584,6 @@ namespace hal case NetEvent::event::name_changed: { //< no associated_data - mModuleModel->updateNetName(net->get_id()); gGraphContextManager->handleNetNameChanged(net); Q_EMIT netNameChanged(net); @@ -619,7 +602,6 @@ namespace hal case NetEvent::event::src_added: { //< associated_data = id of src gate - mModuleModel->updateNet(net); gGraphContextManager->handleNetSourceAdded(net, associated_data); Q_EMIT netSourceAdded(net, associated_data); @@ -628,7 +610,6 @@ namespace hal case NetEvent::event::src_removed: { //< associated_data = id of src gate - mModuleModel->updateNet(net); gGraphContextManager->handleNetSourceRemoved(net, associated_data); Q_EMIT netSourceRemoved(net, associated_data); @@ -637,7 +618,6 @@ namespace hal case NetEvent::event::dst_added: { //< associated_data = id of dst gate - mModuleModel->updateNet(net); gGraphContextManager->handleNetDestinationAdded(net, associated_data); Q_EMIT netDestinationAdded(net, associated_data); @@ -646,7 +626,6 @@ namespace hal case NetEvent::event::dst_removed: { //< associated_data = id of dst gate - mModuleModel->updateNet(net); gGraphContextManager->handleNetDestinationRemoved(net, associated_data); Q_EMIT netDestinationRemoved(net, associated_data); @@ -686,12 +665,10 @@ namespace hal { for (Module* m : gNetlist->get_modules()) mModuleColorManager->setRandomColor(m->get_id()); - mModuleModel->init(); mColorSerializer.restore(mModuleColorManager); } void NetlistRelay::debugHandleFileClosed() { - mModuleModel->clear(); } } // namespace hal From 3594541516e53f6dacdd90b40d1d0c04a90f3410 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 22 Jan 2024 15:43:53 +0100 Subject: [PATCH 26/40] Bugfixes after new implementing ModuleModel event handler --- .../gui/basic_tree_model/base_tree_item.h | 2 +- .../include/gui/module_model/module_item.h | 16 +- .../include/gui/module_model/module_model.h | 104 ++- plugins/gui/src/module_model/module_item.cpp | 107 ++- plugins/gui/src/module_model/module_model.cpp | 630 ++++++++++-------- .../gui/src/module_widget/module_widget.cpp | 9 +- 6 files changed, 492 insertions(+), 376 deletions(-) diff --git a/plugins/gui/include/gui/basic_tree_model/base_tree_item.h b/plugins/gui/include/gui/basic_tree_model/base_tree_item.h index 39fc926381e..04df7bf683e 100644 --- a/plugins/gui/include/gui/basic_tree_model/base_tree_item.h +++ b/plugins/gui/include/gui/basic_tree_model/base_tree_item.h @@ -189,7 +189,7 @@ namespace hal */ virtual int getOwnRow(); - private: + protected: BaseTreeItem* mParent; QList mChildren; }; diff --git a/plugins/gui/include/gui/module_model/module_item.h b/plugins/gui/include/gui/module_model/module_item.h index 49bbdc9288b..f34143e088c 100644 --- a/plugins/gui/include/gui/module_model/module_item.h +++ b/plugins/gui/include/gui/module_model/module_item.h @@ -107,6 +107,13 @@ namespace hal */ bool highlighted() const; + /** + * Checks if this ModuleItem is direct child to mRootItem + * + * @return + */ + bool isToplevelItem() const; + /** * Gets the type of the netlist item this ModuleItem represents. * @@ -121,6 +128,12 @@ namespace hal */ void setName(const QString& name); + /** + * Set the module type name (gate types are immutable) + * @param moduleType + */ + void setModuleType(const QString& moduleType); + /** * Marks/Unmarks this ModuleItem as highlighted. * @@ -131,8 +144,9 @@ namespace hal private: u32 mId; - TreeItemType mType; + TreeItemType mItemType; QString mName; + QString mModuleType; bool mHighlighted; }; diff --git a/plugins/gui/include/gui/module_model/module_model.h b/plugins/gui/include/gui/module_model/module_model.h index edd4ecd76e8..fd0e5c01755 100644 --- a/plugins/gui/include/gui/module_model/module_model.h +++ b/plugins/gui/include/gui/module_model/module_model.h @@ -36,6 +36,7 @@ #include #include #include +#include namespace hal { @@ -50,6 +51,28 @@ namespace hal { Q_OBJECT + class TempGateAssignment + { + int mAccumulate; + public: + QHash mGateRemove; + QHash mGateAssign; + + TempGateAssignment() : mAccumulate(0) {;} + void removeGateFromModule(u32 gateId, Module* m) + { + if (!mGateRemove.contains(gateId)) + mGateRemove[gateId] = m; + } + void assignGateToModule(u32 gateId, Module* m) + { + mGateAssign[gateId] = m; + } + bool isAccumulate() const { return mAccumulate > 0; } + void beginAccumulate() { mAccumulate++; } + void endAccumulate() { mAccumulate--; } + }; + public: /** * Constructor.
@@ -90,14 +113,6 @@ namespace hal */ ModuleItem* getItem(const QModelIndex& index) const; - /** - * Returns the index where the specified ModuleItem can be found. - * - * @param item - The ModuleItem to search for in the item model - * @returns the model index of the specified ModuleItem - */ - QModelIndex getIndex(const ModuleItem* const item) const; - /** * Returns the ModuleItem for a specified id and type. * @@ -123,7 +138,7 @@ namespace hal * @param id - The id of the module to add. * @param parent_module - The id of the parent module of the module to add. */ - void addModule(const u32 id, const u32 parent_module); + void addModule(const u32 id, const u32 parentId); /** * Add a gate to the item model. For the specified gate a new ModuleItem is created and stored. @@ -131,7 +146,7 @@ namespace hal * @param id - The id of the gate to add. * @param parent_module - The id of the parent module of the gate to add. */ - void addGate(const u32 id, const u32 parent_module); + void addGate(const u32 id, const u32 parentId); /** * Add a net to the item model. For the specified net a new ModuleItem is created and stored. @@ -139,7 +154,7 @@ namespace hal * @param id - The id of the net to add. * @param parent_module - The id of the parent module of the net to add. */ - void addNet(const u32 id, const u32 parent_module); + void addNet(const u32 id, const u32 parentId); /** * Recursively adds the given module with all of its submodules (and their submodules and so on...) @@ -148,7 +163,7 @@ namespace hal * @param module - The module which should be added to the item model together with all its * submodules, gates and nets. */ - void addRecursively(const Module* module); + void addRecursively(const Module* module, BaseTreeItem* parentItem = nullptr); /** * Removes a module from the item model. The specified module MUST be contained in the item model. @@ -174,9 +189,14 @@ namespace hal /** * Handles the assigment of gates to modules. * If the gate does not yet exist in the item model, a new one is created. - * All nets, that are connected to the gate, will be updated. */ - void handleModuleGateAssinged(const u32 id, const u32 parent_module); + void moduleAssignGate(const u32 moduleId, const u32 gateId); + + /** + * Handles the assigment of nets to modules for nets connected to gates of list. + * If the gate list is empty all nets connected to modules in tree are considered. + */ + void moduleAssignNets(const QList& gateIds = QList()); /** * Updates the position of a net in the ModuleTree. @@ -186,7 +206,7 @@ namespace hal * * @param net The net whose source or destination might have changed. */ - void updateNet(const Net* net, const QHash* parentAssignment = nullptr); + void updateNetParent(const Net* net, const QHash* parentAssignment = nullptr); /** * Reattaches the ModuleItem corresponding to the specified module to a new parent item. @@ -226,8 +246,6 @@ namespace hal */ bool isModifying(); - void debugDump() const; - private Q_SLOTS: void handleModuleNameChanged(Module* mod); @@ -242,7 +260,11 @@ namespace hal * * @param module The module whose parent has changed. */ - void handleModuleParentChanged(const Module* module); + void handleModuleParentChanged(const Module* mod); + + void handleModuleSubmoduleAdded(Module* mod, u32 submodId); + + void handleModuleSubmoduleRemoved(Module* mod, u32 submodId); void handleModuleGateAssigned(Module* mod, u32 gateId); @@ -252,14 +274,18 @@ namespace hal void handleModuleGatesAssignEnd(Module* mod, u32 numberGates); + void handleGateCreated(Gate* gat); + void handleGateNameChanged(Gate* gat); - void handleNetCreated(Net* net); + void handleGateRemoved(Gate* gat); - void handleNetRemoved(Net* net); + void handleNetCreated(Net* net); void handleNetNameChanged(Net* net); + void handleNetRemoved(Net* net); + void handleNetUpdated(Net* net, u32 data); private: /** @@ -269,17 +295,41 @@ namespace hal * @param net The net for which a new parent should be searched. * * @return The new parent module, that contains all sources and destinations of net. If no such parent could be found - * (e.g. net has no sources or destinations), nullptr is returned instead. + * (e.g. global input/output, net has no sources or destinations), nullptr is returned instead. */ - Module* findNetParent(const Net* net); - void updateAllNets(); + Module* findNetParent(const Net* net) const; + + /** + * Recursion to loop over all modules from (sub-)tree and create a hash assign how internal nets are assigned to module + * @param parent - top tree element + * @param parentAssignment - the resulting net module assignment + * @param assignedNets - nets already assigned (no assignment to module higher up in hierarchy) + */ void findNetParentRecursion(BaseTreeItem* parent, QHash& parentAssignment, std::unordered_set& assignedNets) const; - QMap mModuleMap; - QMap mGateMap; - QMap mNetMap; - std::array*, 3> mModuleItemMaps = {&mModuleMap, &mGateMap, &mNetMap};; + /** + * Factory method to append new tree items. Insert signals are sent to view. New items are put into hash table. + * @param id - ID of new tree item + * @param itemType - Whether new tree item is module, gate, or net + * @param parentItem - Parent to new tree item. Will create top-level item if parent is nullptr + * @return Point to new tree item + */ + ModuleItem* createChildItem(u32 id, ModuleItem::TreeItemType itemType, BaseTreeItem* parentItem = nullptr); + + /** + * Method to remove and delete tree items. Remove signals are sent to view. + * Hash table will _NOT_ be updated since caller can do it more efficiently. + * @param itemToRemove - Item to be removed from tree + * @param parentItem - Parent item. Must be present. + */ + void removeChildItem(ModuleItem* itemToRemove, BaseTreeItem* parentItem); + + QMultiMap mModuleMap; + QMultiMap mGateMap; + QMultiMap mNetMap; + QMultiMap* mModuleItemMaps[3] = {&mModuleMap, &mGateMap, &mNetMap};; bool mIsModifying; + TempGateAssignment mTempGateAssignment; }; } // namespace hal diff --git a/plugins/gui/src/module_model/module_item.cpp b/plugins/gui/src/module_model/module_item.cpp index cf5a79bcc56..8291ac52b80 100644 --- a/plugins/gui/src/module_model/module_item.cpp +++ b/plugins/gui/src/module_model/module_item.cpp @@ -11,21 +11,35 @@ namespace hal ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : BaseTreeItem(), mId(id), - mType(type), + mItemType(type), mHighlighted(false) { switch(type) { case TreeItemType::Module: - mName = QString::fromStdString(gNetlist->get_module_by_id(id)->get_name()); + { + const Module* m = gNetlist->get_module_by_id(id); + Q_ASSERT(m); + mName = QString::fromStdString(m->get_name()); + mModuleType = QString::fromStdString(m->get_type()); break; + } case TreeItemType::Gate: - mName = QString::fromStdString(gNetlist->get_gate_by_id(id)->get_name()); + { + const Gate* g = gNetlist->get_gate_by_id(id); + Q_ASSERT(g); + mName = QString::fromStdString(g->get_name()); + mModuleType = QString::fromStdString(g->get_type()->get_name()); break; + } case TreeItemType::Net: - mName = QString::fromStdString(gNetlist->get_net_by_id(id)->get_name()); + { + const Net* n = gNetlist->get_net_by_id(id); + Q_ASSERT(n); + mName = QString::fromStdString(n->get_name()); break; } + } } int ModuleItem::row() const @@ -38,7 +52,7 @@ ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : void ModuleItem::appendExistingChildIfAny(const QMap& moduleMap) { - if(mType != TreeItemType::Module) // only module can have children + if(mItemType != TreeItemType::Module) // only module can have children return; Module* m = gNetlist->get_module_by_id(mId); @@ -55,30 +69,25 @@ ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : } } + void ModuleItem::setModuleType(const QString &moduleType) + { + if (mItemType != TreeItemType::Module) return; + Module* module = gNetlist->get_module_by_id(mId); + if (!module) return; + module->set_type(moduleType.toStdString()); + mModuleType = moduleType; + } + QVariant ModuleItem::getData(int column) const { // DEBUG CODE, USE STYLED DELEGATES OR SOMETHING - if(column == 0) + switch (column) { + case 0: return mName; - else if (column == 1) + case 1: return mId; - else if(column == 2) - { - switch(mType) - { - case TreeItemType::Module: - { - Module* module = gNetlist->get_module_by_id(mId); - if(!module) - return QVariant(); - return QString::fromStdString(module->get_type()); - } - case TreeItemType::Gate: - Gate* gate = gNetlist->get_gate_by_id(mId); - if(!gate) - return QVariant(); - return QString::fromStdString(gate->get_type()->get_name()); - } + case 2: + return mModuleType; } return QVariant(); } @@ -86,42 +95,21 @@ ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : void ModuleItem::setData(QList data) { setName(data[0].toString()); - switch(mType) - { - case TreeItemType::Module: - { - Module* module = gNetlist->get_module_by_id(mId); - if(!module) - return; - module->set_type(data[3].toString().toStdString()); - } - case TreeItemType::Gate: - return; - } + if (mItemType == TreeItemType::Module) + setModuleType(data.at(2).toString()); } void ModuleItem::setDataAtIndex(int index, QVariant &data) { - if(index == 0) { + switch (index) { + case 0: setName(data.toString()); return; - } - else if (index == 1) + case 1: + return; + case 2: + setModuleType(data.toString()); return; - else if(index == 2) - { - switch(mType) - { - case TreeItemType::Module: - { - Module* module = gNetlist->get_module_by_id(mId); - if(!module) - return; - module->set_type(data.toString().toStdString()); - } - case TreeItemType::Gate: - return; - } } } @@ -140,8 +128,14 @@ ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : return mHighlighted; } + bool ModuleItem::isToplevelItem() const + { + if (dynamic_cast(mParent)) return true; + return false; + } + ModuleItem::TreeItemType ModuleItem::getType() const{ - return mType; + return mItemType; } void ModuleItem::setName(const QString& name) @@ -159,5 +153,8 @@ ModuleItem::ModuleItem(const u32 id, const TreeItemType type) : return 3; } - void ModuleItem::appendData(QVariant data) {} + void ModuleItem::appendData(QVariant data) + { + Q_UNUSED(data); + } } diff --git a/plugins/gui/src/module_model/module_model.cpp b/plugins/gui/src/module_model/module_model.cpp index 103c8784dc6..15042327714 100644 --- a/plugins/gui/src/module_model/module_model.cpp +++ b/plugins/gui/src/module_model/module_model.cpp @@ -16,6 +16,8 @@ namespace hal connect(gNetlistRelay, &NetlistRelay::moduleCreated, this, &ModuleModel::handleModuleCreated); connect(gNetlistRelay, &NetlistRelay::moduleNameChanged, this, &ModuleModel::handleModuleNameChanged); connect(gNetlistRelay, &NetlistRelay::moduleParentChanged, this, &ModuleModel::handleModuleParentChanged); + connect(gNetlistRelay, &NetlistRelay::moduleSubmoduleAdded, this, &ModuleModel::handleModuleSubmoduleAdded); + connect(gNetlistRelay, &NetlistRelay::moduleSubmoduleRemoved, this, &ModuleModel::handleModuleSubmoduleRemoved); connect(gNetlistRelay, &NetlistRelay::moduleGateAssigned, this, &ModuleModel::handleModuleGateAssigned); connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignBegin, this, &ModuleModel::handleModuleGatesAssignBegin); connect(gNetlistRelay, &NetlistRelay::moduleGatesAssignEnd, this, &ModuleModel::handleModuleGatesAssignEnd); @@ -91,43 +93,10 @@ namespace hal return nullptr; } - QModelIndex ModuleModel::getIndex(const ModuleItem* const item) const - { - assert(item); - - QVector row_numbers; - const ModuleItem* current_item = item; - - while (current_item != mRootItem->getChild(0)) - { - row_numbers.append(current_item->row()); - current_item = static_cast(current_item->getParent()); - } - - QModelIndex model_index = index(0, 0, QModelIndex()); - - for (QVector::const_reverse_iterator i = row_numbers.crbegin(); i != row_numbers.crend(); ++i) - model_index = index(*i, 0, model_index); - - return model_index; - } - void ModuleModel::init() { - ModuleItem* item = new ModuleItem(1); - mModuleMap.insert(1, item); - - beginInsertRows(index(0, 0, QModelIndex()), 0, 0); - mRootItem->appendChild(item); - endInsertRows(); - - Module* m = gNetlist->get_top_module(); - addRecursively(m); - for(auto net : gNetlist->get_top_module()->get_internal_nets()) - { - addNet(net->get_id(), m->get_id()); - updateNet(net); - } + addRecursively(gNetlist->get_top_module()); + moduleAssignNets(); } void ModuleModel::clear() @@ -138,137 +107,114 @@ namespace hal mModuleMap.clear(); mGateMap.clear(); mNetMap.clear(); - //TODO : clear colors endResetModel(); } - void ModuleModel::addModule(u32 id, u32 parent_module) + void ModuleModel::addModule(u32 id, u32 parentId) { - assert(gNetlist->get_module_by_id(id)); - assert(gNetlist->get_module_by_id(parent_module)); - assert(!mModuleMap.contains(id)); - assert(mModuleMap.contains(parent_module)); - - ModuleItem* item = new ModuleItem(id); - ModuleItem* parent = mModuleMap.value(parent_module); - - item->setParent(parent); - mModuleMap.insert(id, item); - - QModelIndex index = getIndex(parent); + Q_ASSERT(gNetlist->get_module_by_id(id)); + Q_ASSERT(gNetlist->get_module_by_id(parentId)); - int row = parent->getChildCount(); - mIsModifying = true; - beginInsertRows(index, row, row); - parent->appendChild(item); - mIsModifying = false; - endInsertRows(); + for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it) + { + ModuleItem* parentItem = mModuleMap.value(parentId); + createChildItem(id, ModuleItem::TreeItemType::Module, parentItem); + } } - void ModuleModel::addGate(u32 id, u32 parent_module) + void ModuleModel::addGate(u32 id, u32 parentId) { - assert(gNetlist->get_gate_by_id(id)); - assert(gNetlist->get_module_by_id(parent_module)); - assert(!mGateMap.contains(id)); - assert(mModuleMap.contains(parent_module)); + Q_ASSERT(gNetlist->get_gate_by_id(id)); + Q_ASSERT(gNetlist->get_module_by_id(parentId)); - ModuleItem* item = new ModuleItem(id, ModuleItem::TreeItemType::Gate); - ModuleItem* parent = mModuleMap.value(parent_module); - item->setParent(parent); - mGateMap.insert(id, item); - - QModelIndex index = getIndex(parent); - - int row = parent->getChildCount(); - mIsModifying = true; - beginInsertRows(index, row, row); - parent->appendChild(item); - mIsModifying = false; - endInsertRows(); + for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it) + { + createChildItem(id, ModuleItem::TreeItemType::Gate, it.value()); + } } - void ModuleModel::addNet(u32 id, u32 parent_module) + void ModuleModel::addNet(u32 id, u32 parentId) { - assert(gNetlist->get_net_by_id(id)); - assert(gNetlist->get_module_by_id(parent_module)); - assert(!mNetMap.contains(id)); - assert(mModuleMap.contains(parent_module)); - - ModuleItem* item = new ModuleItem(id, ModuleItem::TreeItemType::Net); - ModuleItem* parent = mModuleMap.value(parent_module); + Q_ASSERT(gNetlist->get_net_by_id(id)); + Q_ASSERT(gNetlist->get_module_by_id(parentId)); - item->setParent(parent); - mNetMap.insert(id, item); - - QModelIndex index = getIndex(parent); - - int row = parent->getChildCount(); - mIsModifying = true; - beginInsertRows(index, row, row); - parent->appendChild(item); - mIsModifying = false; - endInsertRows(); + for (auto it = mModuleMap.lowerBound(parentId); it != mModuleMap.upperBound(parentId); ++it) + { + createChildItem(id, ModuleItem::TreeItemType::Net, it.value()); + } } - void ModuleModel::addRecursively(const Module* module) + void ModuleModel::addRecursively(const Module* module, BaseTreeItem *parentItem) { - if(!module->is_top_module()) - addModule(module->get_id(), module->get_parent_module()->get_id()); - for(auto &m : module->get_submodules()) - addRecursively(m); + Q_ASSERT(module); + ModuleItem* moduleItem = createChildItem(module->get_id(), ModuleItem::TreeItemType::Module, parentItem ? parentItem : mRootItem); + Q_ASSERT(moduleItem); + for(const Module* subModule : module->get_submodules()) + addRecursively(subModule, moduleItem); - for(auto &g : module->get_gates()) - addGate(g->get_id(), module->get_id()); + for(const Gate* g : module->get_gates()) + createChildItem(g->get_id(), ModuleItem::TreeItemType::Gate, moduleItem); } void ModuleModel::removeModule(const u32 id) { - assert(id != 1); - // module was most likely already purged from netlist - assert(mModuleMap.contains(id)); + auto it = mModuleMap.lowerBound(id); + while (it != mModuleMap.upperBound(id)) + { + ModuleItem* item = mModuleMap.value(id); + BaseTreeItem* parentItem = item->getParent(); - ModuleItem* item = mModuleMap.value(id); - ModuleItem* parent = static_cast(item->getParent()); - assert(item); - assert(parent); + removeChildItem(item,parentItem); - QModelIndex index = getIndex(parent); + it = mModuleMap.erase(it); + } + } - int row = item->row(); + void ModuleModel::removeGate(const u32 id) + { + auto it = mGateMap.lowerBound(id); + while (it != mGateMap.upperBound(id)) + { + ModuleItem* item = it.value(); + BaseTreeItem* parentItem = item->getParent(); - mIsModifying = true; - beginRemoveRows(index, row, row); - parent->removeChild(item); - mIsModifying = false; - endRemoveRows(); + removeChildItem(item, parentItem); - mModuleMap.remove(id); - delete item; + it = mGateMap.erase(it); + } } - void ModuleModel::removeGate(const u32 id) + void ModuleModel::removeNet(const u32 id) { - //assert(gNetlist->get_gate_by_id(id)); - assert(mGateMap.contains(id)); + auto it = mNetMap.lowerBound(id); + while (it != mNetMap.upperBound(id)) + { + ModuleItem* item = it.value(); + BaseTreeItem* parentItem = item->getParent(); + + removeChildItem(item, parentItem); + + it = mNetMap.erase(it); + } + } - ModuleItem* item = mGateMap.value(id); - ModuleItem* parent = static_cast(item->getParent()); - assert(item); - assert(parent); + void ModuleModel::removeChildItem(ModuleItem *itemToRemove, BaseTreeItem *parentItem) + { + Q_ASSERT(itemToRemove); + Q_ASSERT(parentItem); - QModelIndex index = getIndex(parent); + QModelIndex index = getIndexFromItem(parentItem); - int row = item->row(); + int row = itemToRemove->row(); mIsModifying = true; beginRemoveRows(index, row, row); - parent->removeChild(item); - mIsModifying = false; + parentItem->removeChild(itemToRemove); endRemoveRows(); + mIsModifying = false; - mGateMap.remove(id); - delete item; + delete itemToRemove; } void ModuleModel::handleModuleNameChanged(Module* mod) @@ -289,25 +235,73 @@ namespace hal void ModuleModel::handleModuleGateAssigned(Module* mod, u32 gateId) { - handleModuleGateAssinged(gateId, mod->get_id()); + if (mTempGateAssignment.isAccumulate()) + mTempGateAssignment.assignGateToModule(gateId,mod); + else + { + moduleAssignGate(mod->get_id(), gateId); + moduleAssignNets({gateId}); + } } void ModuleModel::handleModuleGateRemoved(Module* mod, u32 gateId) { - Q_UNUSED(mod); - removeGate(gateId); + if (mTempGateAssignment.isAccumulate()) + mTempGateAssignment.removeGateFromModule(gateId,mod); + else + { + auto it = mGateMap.lowerBound(gateId); + while (it != mGateMap.upperBound(gateId)) + { + ModuleItem* item = it.value(); + if (!item->isToplevelItem()) + { + ModuleItem* parentItem = static_cast(item->getParent()); + if (parentItem->id() == mod->get_id()) + { + removeChildItem(item, parentItem); + it = mGateMap.erase(it); + continue; + } + } + ++it; + } + } } void ModuleModel::handleModuleGatesAssignBegin(Module* mod, u32 numberGates) { Q_UNUSED(mod); Q_UNUSED(numberGates); + mTempGateAssignment.beginAccumulate(); } void ModuleModel::handleModuleGatesAssignEnd(Module* mod, u32 numberGates) { Q_UNUSED(mod); Q_UNUSED(numberGates); + mTempGateAssignment.endAccumulate(); + if (!mTempGateAssignment.isAccumulate()) + { + for (auto it = mTempGateAssignment.mGateAssign.begin(); it != mTempGateAssignment.mGateAssign.end(); ++it) + { + moduleAssignGate(it.value()->get_id(), it.key()); // moduleId, gateId + } + moduleAssignNets(mTempGateAssignment.mGateAssign.keys()); + mTempGateAssignment.mGateAssign.clear(); + mTempGateAssignment.mGateRemove.clear(); + } + } + + void ModuleModel::handleGateRemoved(Gate* gat) + { + removeGate(gat->get_id()); + } + + void ModuleModel::handleGateCreated(Gate* gat) + { + Module* mod = gat->get_module(); + if (mod) moduleAssignGate(mod->get_id(), gat->get_id()); } void ModuleModel::handleGateNameChanged(Gate* gat) @@ -333,41 +327,32 @@ namespace hal void ModuleModel::handleNetUpdated(Net* net, u32 data) { Q_UNUSED(data); - updateNet(net); + updateNetParent(net); } - void ModuleModel::removeNet(const u32 id) + void ModuleModel::handleModuleParentChanged(const Module* mod) { - //assert(gNetlist->get_net_by_id(id)); - if(!mNetMap.contains(id)) // global nets are not contained in the item model - return; - - ModuleItem* item = mNetMap.value(id); - ModuleItem* parent = static_cast(item->getParent()); - assert(item); - assert(parent); - - QModelIndex index = getIndex(parent); + Q_ASSERT(mod); + updateModuleParent(mod); - int row = item->row(); - - mIsModifying = true; - beginRemoveRows(index, row, row); - parent->removeChild(item); - mIsModifying = false; - endRemoveRows(); + QHash parentAssignment; + std::unordered_set assignedNets; + findNetParentRecursion(mRootItem, parentAssignment, assignedNets); - mNetMap.remove(id); - delete item; + for(Net* net : mod->get_nets()) + updateNetParent(net, &parentAssignment); } - void ModuleModel::handleModuleParentChanged(const Module* module) + void ModuleModel::handleModuleSubmoduleAdded(Module* mod, u32 submodId) { - assert(module); - updateModuleParent(module); + Q_UNUSED(mod); + Q_UNUSED(submodId); + } - for(Net* net : module->get_nets()) - updateNet(net); + void ModuleModel::handleModuleSubmoduleRemoved(Module* mod, u32 submodId) + { + Q_UNUSED(mod); + Q_UNUSED(submodId); } void ModuleModel::findNetParentRecursion(BaseTreeItem* parent, QHash &parentAssignment, std::unordered_set& assignedNets) const @@ -379,7 +364,7 @@ namespace hal findNetParentRecursion(item, parentAssignment, assignedNets); Module* m = gNetlist->get_module_by_id(item->id()); Q_ASSERT(m); - std::unordered_set internalNets = m->get_internal_nets(); + std::unordered_set internalNets = m->get_nets(); if (!internalNets.empty()) { for (Net* n : assignedNets) @@ -397,159 +382,254 @@ namespace hal } } - void ModuleModel::debugDump() const + Module* ModuleModel::findNetParent(const Net *net) const { - QHash parentAssignment; - std::unordered_set assignedNets; - findNetParentRecursion(mRootItem, parentAssignment, assignedNets); + QHash modHash; + if (net->is_global_input_net() || net->is_global_output_net()) return nullptr; + int maxDepth = 0; + + for (const Endpoint* ep : net->get_sources()) + { + Module* m = ep->get_gate()->get_module(); + Q_ASSERT(m); + int depth = m->get_submodule_depth(); + if (depth > maxDepth) maxDepth = depth; + modHash.insert(m,depth); + } - QTextStream xout(stdout, QIODevice::WriteOnly); - for (auto it = mModuleMap.begin(); it != mModuleMap.end(); ++it) + for (const Endpoint* ep : net->get_destinations()) { - xout << it.value()->id() << " " << it.value()->name() << " "; + Module* m = ep->get_gate()->get_module(); + Q_ASSERT(m); + int depth = m->get_submodule_depth(); + if (depth > maxDepth) maxDepth = depth; + modHash.insert(m,depth); + } - for (auto jt = parentAssignment.constBegin(); jt != parentAssignment.constEnd(); ++jt) + while (modHash.size() > 1 && maxDepth > 0) + { + auto it = modHash.begin(); + while (it != modHash.end()) { - if (it.value() != jt.value()) continue; - xout << " <" << jt.key()->get_id() << ">"; + if (it.value() == maxDepth) + { + Module* parentMod = it.key()->get_parent_module(); + modHash.erase(it); + if (parentMod) modHash.insert(parentMod,maxDepth-1); + break; + } + ++it; } - xout << "\n"; + if (it == modHash.end()) + --maxDepth; } - xout.flush(); + if (modHash.empty()) return nullptr; + return modHash.begin().key(); } - void ModuleModel::handleModuleGateAssinged(const u32 id, const u32 parent_module) + void ModuleModel::moduleAssignGate(const u32 moduleId, const u32 gateId) { // Don't need new function handleModuleGateRemoved(), because the GateAssinged event always follows GateRemoved // or NetlistInternalManager updates Net connections when a gate is deleted. - if(!mGateMap.contains(id)) - addGate(id, parent_module); + QSet parentsHandled; + Q_ASSERT(gNetlist->get_gate_by_id(gateId)); + + auto itGat = mGateMap.lowerBound(gateId); + while (itGat != mGateMap.upperBound(gateId)) + { + ModuleItem* gatItem = itGat.value(); + if (gatItem->isToplevelItem()) continue; + ModuleItem* oldParentItem = static_cast(gatItem->getParent()); + Q_ASSERT(oldParentItem); + + if (oldParentItem->id() != moduleId) + { + removeChildItem(gatItem,oldParentItem); + itGat = mGateMap.erase(itGat); + } + else + { + parentsHandled.insert(oldParentItem); + ++itGat; + } + + } + + if (!moduleId) return; + for (auto itMod = mModuleMap.lowerBound(moduleId); itMod != mModuleMap.upperBound(moduleId); ++itMod) + { + ModuleItem* parentItem = itMod.value(); + if (parentsHandled.contains(parentItem)) continue; + createChildItem(gateId, ModuleItem::TreeItemType::Gate, parentItem); + } + + } + void ModuleModel::moduleAssignNets(const QList& gateIds) + { QHash parentAssignment; std::unordered_set assignedNets; findNetParentRecursion(mRootItem, parentAssignment, assignedNets); - Gate* gate = gNetlist->get_gate_by_id(id); - for(Net* in_net : gate->get_fan_in_nets()) - updateNet(in_net, &parentAssignment); - for(Net* in_net : gate->get_fan_out_nets()) - updateNet(in_net, &parentAssignment); + QSet netsToAssign; + if (gateIds.isEmpty()) + { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + netsToAssign = QSet(parentAssignment.keys().begin(),parentAssignment.keys().end()); +#else + netsToAssign = parentAssignment.keys().toSet(); +#endif + } + else + { + for (u32 id : gateIds) + { + Gate* gate = gNetlist->get_gate_by_id(id); + for(Net* in_net : gate->get_fan_in_nets()) + netsToAssign.insert(in_net); + for(Net* out_net : gate->get_fan_out_nets()) + netsToAssign.insert(out_net); + } + } + + for (const Net* n: netsToAssign) + updateNetParent(n, &parentAssignment); } - void ModuleModel::updateNet(const Net* net, const QHash *parentAssignment) + void ModuleModel::updateNetParent(const Net* net, const QHash *parentAssignment) { - assert(net); - u32 id = net->get_id(); - - if(!mNetMap.contains(id)) - return; - - ModuleItem* item = mNetMap.value(id); - ModuleItem* oldParentItem = static_cast(item->getParent()); - assert(oldParentItem); + Q_ASSERT(net); + u32 netId = net->get_id(); - ModuleItem* newParentItem = nullptr; + QSet parentsHandled; + u32 newParentId = 0; if (parentAssignment) - newParentItem = parentAssignment->value(net); + { + ModuleItem* modItem = parentAssignment->value(net); + if (modItem) + newParentId = modItem->id(); + } else { Module* newParentModule = findNetParent(net); - if(newParentModule == nullptr) - newParentModule = gNetlist->get_top_module(); - newParentItem = mModuleMap[newParentModule->get_id()]; + if (newParentModule) + newParentId = newParentModule->get_id(); } - if (!newParentItem) + auto itNet = mNetMap.lowerBound(netId); + while (itNet != mNetMap.upperBound(netId)) { - mIsModifying = true; - oldParentItem->removeChild(item); - mIsModifying = false; - return; - } + if (itNet.value()->isToplevelItem()) continue; + + ModuleItem* netItem = itNet.value(); + ModuleItem* oldParentItem = static_cast(netItem->getParent()); + Q_ASSERT(oldParentItem); - if(newParentItem->id() == oldParentItem->id()) - return; - QModelIndex newIndex = getIndex(newParentItem); - QModelIndex oldIndex = getIndex(oldParentItem); - int row = item->row(); + if (newParentId == 0 || newParentId != oldParentItem->id()) + { + removeChildItem(netItem,oldParentItem); + itNet = mNetMap.erase(itNet); + } + else + { + parentsHandled.insert(oldParentItem); + ++itNet; + } + } - mIsModifying = true; - beginMoveRows(oldIndex, row, row, newIndex, newParentItem->getChildCount()); - oldParentItem->removeChild(item); - newParentItem->appendChild(item); - mIsModifying = false; - endMoveRows(); + if (!newParentId) return; + for (auto itMod = mModuleMap.lowerBound(newParentId); itMod != mModuleMap.upperBound(newParentId); ++itMod) + { + ModuleItem* parentItem = itMod.value(); + if (parentsHandled.contains(parentItem)) continue; + createChildItem(net->get_id(), ModuleItem::TreeItemType::Net, parentItem); + } } - void ModuleModel::updateModuleParent(const Module* module){ - assert(module); + void ModuleModel::updateModuleParent(const Module* module) + { + Q_ASSERT(module); u32 id = module->get_id(); - assert(id != 1); - assert(mModuleMap.contains(id)); - ModuleItem* item = mModuleMap.value(id); - ModuleItem* oldParent = static_cast(item->getParent()); - assert(oldParent); + Q_ASSERT(id != 1); - assert(module->get_parent_module()); - if(oldParent->id() == module->get_parent_module()->get_id()) - return; + QSet parentsHandled; + u32 parentId = module->get_parent_module()->get_id(); + Q_ASSERT(parentId > 0); - assert(mModuleMap.contains(module->get_parent_module()->get_id())); - ModuleItem* newParent = mModuleMap.value(module->get_parent_module()->get_id()); + auto itSubm = mModuleMap.lowerBound(id); + while (itSubm != mModuleMap.upperBound(id)) + { + ModuleItem* submItem = itSubm.value(); + if (submItem->isToplevelItem()) continue; + ModuleItem* oldParentItem = static_cast(submItem->getParent()); + Q_ASSERT(oldParentItem); - QModelIndex oldIndex = getIndex(oldParent); - QModelIndex newIndex = getIndex(newParent); - int row = item->row(); + if (oldParentItem->id() != parentId) + { + removeChildItem(submItem,oldParentItem); + itSubm = mModuleMap.erase(itSubm); + } + else + { + parentsHandled.insert(oldParentItem); + ++itSubm; + } + } - mIsModifying = true; - beginMoveRows(oldIndex, row, row, newIndex, newParent->getChildCount()); - oldParent->removeChild(item); - newParent->appendChild(item); - mIsModifying = false; - endMoveRows(); + if (!parentId) return; + for (auto itMod = mModuleMap.lowerBound(parentId); itMod != mModuleMap.upperBound(parentId); ++itMod) + { + ModuleItem* parentItem = itMod.value(); + if (parentsHandled.contains(parentItem)) continue; + addRecursively(module, parentItem); + } } void ModuleModel::updateModuleName(u32 id) { - assert(gNetlist->get_module_by_id(id)); - assert(mModuleMap.contains(id)); + Q_ASSERT(gNetlist->get_module_by_id(id)); - ModuleItem* item = mModuleMap.value(id); - assert(item); + for (auto it = mModuleMap.lowerBound(id); it != mModuleMap.upperBound(id); ++it) + { + ModuleItem* item = it.value(); + Q_ASSERT(item); - item->setName(QString::fromStdString(gNetlist->get_module_by_id(id)->get_name())); // REMOVE & ADD AGAIN + item->setName(QString::fromStdString(gNetlist->get_module_by_id(id)->get_name())); // REMOVE & ADD AGAIN - QModelIndex index = getIndex(item); - Q_EMIT dataChanged(index, index); + QModelIndex index = getIndexFromItem(item); + Q_EMIT dataChanged(index, index); + } } void ModuleModel::updateGateName(u32 id) { - assert(gNetlist->get_gate_by_id(id)); - assert(mGateMap.contains(id)); + Q_ASSERT(gNetlist->get_gate_by_id(id)); - ModuleItem* item = mGateMap.value(id); - assert(item); + for (auto it = mGateMap.lowerBound(id); it != mGateMap.upperBound(id); ++it) + { + ModuleItem* item = it.value(); + Q_ASSERT(item); - item->setName(QString::fromStdString(gNetlist->get_gate_by_id(id)->get_name())); // REMOVE & ADD AGAIN + item->setName(QString::fromStdString(gNetlist->get_gate_by_id(id)->get_name())); // REMOVE & ADD AGAIN - QModelIndex index = getIndex(item); - Q_EMIT dataChanged(index, index); + QModelIndex index = getIndexFromItem(item); + Q_EMIT dataChanged(index, index); + } } void ModuleModel::updateNetName(u32 id) { - assert(gNetlist->get_net_by_id(id)); - assert(mNetMap.contains(id)); + Q_ASSERT(gNetlist->get_net_by_id(id)); + Q_ASSERT(mNetMap.contains(id)); ModuleItem* item = mNetMap.value(id); - assert(item); + Q_ASSERT(item); item->setName(QString::fromStdString(gNetlist->get_net_by_id(id)->get_name())); // REMOVE & ADD AGAIN - QModelIndex index = getIndex(item); + QModelIndex index = getIndexFromItem(item); Q_EMIT dataChanged(index, index); } @@ -558,45 +638,27 @@ namespace hal return mModuleItemMaps[(int)type]->value(id); } - bool ModuleModel::isModifying() + ModuleItem* ModuleModel::createChildItem(u32 id, ModuleItem::TreeItemType itemType, BaseTreeItem *parentItem) { - return mIsModifying; - } - - Module* ModuleModel::findNetParent(const Net* net){ - // cannot use Module::get_internal_nets(), because currently that function is implemented so, - // that a net can be "internal" to multiple modules at the same depth. - // => instead manually search for deepest module, that contains all sources and destinations of net. - assert(net); - if(net->get_num_of_sources() == 0 && net->get_num_of_destinations() == 0) - return nullptr; - - std::vector endpoints = net->get_sources(); + ModuleItem* retval = new ModuleItem(id, itemType); + mModuleItemMaps[(int)itemType]->insertMulti(id,retval); - { - std::vector destinations = net->get_destinations(); - endpoints.insert(endpoints.end(), destinations.begin(), destinations.end()); - } - - Module* parent = endpoints[0]->get_gate()->get_module(); - endpoints.erase(endpoints.begin()); + if (!parentItem) parentItem = mRootItem; + QModelIndex index = getIndexFromItem(parentItem); + int row = parentItem->getChildCount(); + mIsModifying = true; + beginInsertRows(index, row, row); + parentItem->appendChild(retval); + endInsertRows(); + mIsModifying = false; - // might want to split up endpoints, if sources and destinations should be handled differently - while(endpoints.size() > 0) - { - std::vector::iterator it = endpoints.begin(); - while(it != endpoints.end()) - { - if(parent->contains_gate((*it)->get_gate(), true)) - it = endpoints.erase(it); - else - ++it; - } + return retval; + } - if(endpoints.size() > 0) - parent = parent->get_parent_module(); - } - return parent; + bool ModuleModel::isModifying() + { + return mIsModifying; } + } diff --git a/plugins/gui/src/module_widget/module_widget.cpp b/plugins/gui/src/module_widget/module_widget.cpp index aaf294f42bc..0ecaa5212b2 100644 --- a/plugins/gui/src/module_widget/module_widget.cpp +++ b/plugins/gui/src/module_widget/module_widget.cpp @@ -245,10 +245,6 @@ namespace hal QAction delete_action; QAction extractPythonAction; QAction focus_in_view; - QAction debug_dump; - debug_dump.setText("Debug dump"); - debug_dump.setParent(&context_menu); - context_menu.addAction(&debug_dump); switch(type) { @@ -391,9 +387,6 @@ namespace hal } } - if (clicked == &debug_dump) - mModuleModel->debugDump(); - if (clicked == &change_type_action) gNetlistRelay->changeModuleType(getModuleItemFromIndex(index)->id()); @@ -618,7 +611,7 @@ namespace hal for (auto module_id : gSelectionRelay->selectedModulesList()) { - QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndex(mModuleModel->getItem(module_id))); + QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndexFromItem(mModuleModel->getItem(module_id))); module_selection.select(index, index); } From 17d7ddd9707ac928b035af7398ab5ef15f4447c9 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 24 Jan 2024 16:21:49 +0100 Subject: [PATCH 27/40] Overhaul of Module::assign_pin_net() which was too expansive --- include/hal_core/netlist/module.h | 3 +- plugins/gui/src/module_model/module_model.cpp | 72 ++++++++++++++++++- src/netlist/module.cpp | 71 +++++++++--------- src/netlist/netlist.cpp | 9 --- src/python_bindings/bindings/netlist.cpp | 2 +- 5 files changed, 104 insertions(+), 53 deletions(-) diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index c2347d209e1..bd4b833553a 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -734,6 +734,7 @@ namespace hal std::unordered_map*> m_pin_groups_map; std::unordered_map*> m_pin_group_names_map; std::list*> m_pin_groups_ordered; + u32 m_pin_number[4] = { 0, 0, 0, 0 }; /* stores gates sorted by id */ std::unordered_map m_gates_map; @@ -748,7 +749,7 @@ namespace hal NetConnectivity check_net_endpoints(const Net* net) const; Result check_net(Net* net, bool recursive = false); - Result assign_pin_net(const u32 pin_id, Net* net, PinDirection direction, const std::string& name = "", PinType type = PinType::none); + bool assign_pin_net(const u32 pin_id, Net* net, PinDirection direction); bool remove_pin_net(Net* net); Result create_pin_internal(const u32 id, const std::string& name, Net* net, PinDirection direction, PinType type, bool force_name); bool delete_pin_internal(ModulePin* pin); diff --git a/plugins/gui/src/module_model/module_model.cpp b/plugins/gui/src/module_model/module_model.cpp index 15042327714..b671e8e7a9d 100644 --- a/plugins/gui/src/module_model/module_model.cpp +++ b/plugins/gui/src/module_model/module_model.cpp @@ -204,6 +204,21 @@ namespace hal Q_ASSERT(itemToRemove); Q_ASSERT(parentItem); + while (itemToRemove->getChildCount()) + { + ModuleItem* childItem = static_cast(itemToRemove->getChildren().at(0)); + int ityp = static_cast(childItem->getType()); + auto it = mModuleItemMaps[ityp]->lowerBound(childItem->id()); + while (it != mModuleItemMaps[ityp]->upperBound(childItem->id())) + { + if (it.value() == childItem) + it = mModuleItemMaps[ityp]->erase(it); + else + ++it; + } + removeChildItem(childItem,itemToRemove); + } + QModelIndex index = getIndexFromItem(parentItem); int row = itemToRemove->row(); @@ -550,6 +565,9 @@ namespace hal void ModuleModel::updateModuleParent(const Module* module) { + ModuleItem* moduleItemToBeMoved = nullptr; + bool moduleItemReassigned = false; + Q_ASSERT(module); u32 id = module->get_id(); Q_ASSERT(id != 1); @@ -568,8 +586,27 @@ namespace hal if (oldParentItem->id() != parentId) { - removeChildItem(submItem,oldParentItem); - itSubm = mModuleMap.erase(itSubm); + if (moduleItemToBeMoved) + { + // remove tree item recursively + removeChildItem(submItem,oldParentItem); + itSubm = mModuleMap.erase(itSubm); + } + else + { + // save tree item for reassignment + moduleItemToBeMoved = submItem; + QModelIndex index = getIndexFromItem(oldParentItem); + + int row = submItem->row(); + + mIsModifying = true; + beginRemoveRows(index, row, row); + oldParentItem->removeChild(submItem); + endRemoveRows(); + mIsModifying = false; + ++itSubm; + } } else { @@ -583,8 +620,37 @@ namespace hal { ModuleItem* parentItem = itMod.value(); if (parentsHandled.contains(parentItem)) continue; - addRecursively(module, parentItem); + if (moduleItemToBeMoved && !moduleItemReassigned) + { + QModelIndex index = getIndexFromItem(parentItem); + int row = parentItem->getChildCount(); + mIsModifying = true; + beginInsertRows(index, row, row); + parentItem->appendChild(moduleItemToBeMoved); + endInsertRows(); + mIsModifying = false; + moduleItemReassigned = true; + } + else + { + addRecursively(module, parentItem); + } + } + + if (moduleItemToBeMoved && !moduleItemReassigned) + { + // stored item could not be reassigned, delete it + auto it = mModuleMap.lowerBound(id); + while (it != mModuleMap.upperBound(id)) + { + if (it.value() == moduleItemToBeMoved) + it = mModuleMap.erase(it); + else + ++it; + } + delete moduleItemToBeMoved; } + } void ModuleModel::updateModuleName(u32 id) diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 07daa6caddf..74da03ce416 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -671,9 +671,9 @@ namespace hal } else { - if (auto res = assign_pin_net(get_unique_pin_id(), net, PinDirection::inout); res.is_error()) + if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::inout)) { - return ERR(res.get_error()); + return ERR("could not assign inout pin to net ID " + std::to_string(net->get_id())+ ": failed to create pin"); } } } @@ -693,9 +693,9 @@ namespace hal else { m_input_nets.insert(net); - if (auto res = assign_pin_net(get_unique_pin_id(), net, PinDirection::input); res.is_error()) + if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::input)) { - return ERR(res.get_error()); + return ERR("could not assign input pin to net ID " + std::to_string(net->get_id())+ ": failed to create pin"); } } } @@ -715,9 +715,9 @@ namespace hal else { m_output_nets.insert(net); - if (auto res = assign_pin_net(get_unique_pin_id(), net, PinDirection::output); res.is_error()) + if (!assign_pin_net(get_unique_pin_id(), net, PinDirection::output)) { - return ERR(res.get_error()); + return ERR("could not assign output pin to net ID " + std::to_string(net->get_id())+ ": failed to create pin"); } } } @@ -1546,44 +1546,34 @@ namespace hal return true; } - Result Module::assign_pin_net(const u32 pin_id, Net* net, PinDirection direction, const std::string& name, PinType type) + bool Module::assign_pin_net(const u32 pin_id, Net* net, PinDirection direction) { - std::string name_internal; + std::string port_prefix; - if (!name.empty()) + switch (direction) { - name_internal = name; - } - else - { - std::string port_prefix; - u32 ctr = 0; - switch (direction) - { - case PinDirection::input: - port_prefix = "I"; - break; - case PinDirection::inout: - port_prefix = "IO"; - break; - case PinDirection::output: - port_prefix = "O"; - break; - default: - return ERR("could not assign pin '" + name_internal + "' to net: invalid pin direction '" + enum_to_string(direction) + "'"); - } - do - { - name_internal = port_prefix + "(" + std::to_string(ctr) + ")"; - ctr++; - } while (m_pin_names_map.find(name_internal) != m_pin_names_map.end() || m_pin_group_names_map.find(name_internal) != m_pin_group_names_map.end()); + case PinDirection::input: + port_prefix = "I"; + break; + case PinDirection::inout: + port_prefix = "IO"; + break; + case PinDirection::output: + port_prefix = "O"; + break; + default: + log_warning("module", "could not assign pin to net ID {}: invalid pin direction '{}'", net->get_id(), enum_to_string(direction)); + return false; } + std::string name_internal = port_prefix + "(" + std::to_string(m_pin_number[(int)direction]) + ")"; + // create pin ModulePin* pin; - if (auto res = create_pin_internal(pin_id, name_internal, net, direction, type, false); res.is_error()) + if (auto res = create_pin_internal(pin_id, name_internal, net, direction, PinType::none, false); res.is_error()) { - return ERR_APPEND(res.get_error(), "could not assign pin '" + name_internal + "' to net: failed to create pin"); + log_warning("module", "could not assign pin '{}' to net: failed to create pin", name_internal); + return false; } else { @@ -1592,18 +1582,20 @@ namespace hal if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name_internal, pin->get_direction(), pin->get_type(), true, 0, false); group_res.is_error()) { - return ERR_APPEND(group_res.get_error(), "could not assign pin '" + name_internal + "' to net: failed to create pin group"); + log_warning("module", "could not assign pin '{}' to net: failed to create pin group", name_internal); + return false; } else { if (!group_res.get()->assign_pin(pin)) { - return ERR("could not assign pin '" + name_internal + "' to net: failed to assign pin to pin group"); + log_warning("module", "could not assign pin '{}' to net: failed to assign pin to pin group", name_internal); + return false; } } PinChangedEvent(this,PinEvent::GroupCreate,pin->get_group().first->get_id()).send(); - return OK(pin); + return true; } bool Module::remove_pin_net(Net* net) @@ -1690,6 +1682,7 @@ namespace hal m_pins.push_back(std::move(pin_owner)); m_pins_map[id] = pin; m_pin_names_map[name] = pin; + ++m_pin_number[(int)direction]; // mark pin ID as used if (auto free_id_it = m_free_pin_ids.find(id); free_id_it != m_free_pin_ids.end()) diff --git a/src/netlist/netlist.cpp b/src/netlist/netlist.cpp index bc73520dd93..7e233a04f70 100644 --- a/src/netlist/netlist.cpp +++ b/src/netlist/netlist.cpp @@ -567,15 +567,6 @@ namespace hal return create_module(get_unique_module_id(), name, parent, gates); } - Module* Netlist::create_module_python(const std::string &name, Module *parent, const std::vector &gates) - { - CALLGRIND_START_INSTRUMENTATION; - CALLGRIND_TOGGLE_COLLECT; - return create_module(get_unique_module_id(), name, parent, gates); - CALLGRIND_TOGGLE_COLLECT; - CALLGRIND_STOP_INSTRUMENTATION; - } - bool Netlist::delete_module(Module* module) { return m_manager->delete_module(module); diff --git a/src/python_bindings/bindings/netlist.cpp b/src/python_bindings/bindings/netlist.cpp index 1a15960835a..3b30eb2b882 100644 --- a/src/python_bindings/bindings/netlist.cpp +++ b/src/python_bindings/bindings/netlist.cpp @@ -500,7 +500,7 @@ namespace hal )"); py_netlist.def("create_module", - &Netlist::create_module_python, + py::overload_cast&>(&Netlist::create_module), py::arg("name"), py::arg("parent"), py::arg("gates") = std::vector(), From 35bc94becca29e6e5896d07a6b29764ba204d532 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 24 Jan 2024 16:31:11 +0100 Subject: [PATCH 28/40] Remove VALGRIND header and helper function --- include/hal_core/netlist/netlist.h | 1 - src/netlist/netlist.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/include/hal_core/netlist/netlist.h b/include/hal_core/netlist/netlist.h index 4ecadfc8006..415db8badbf 100644 --- a/include/hal_core/netlist/netlist.h +++ b/include/hal_core/netlist/netlist.h @@ -473,7 +473,6 @@ namespace hal * @returns The new module on success, nullptr otherwise. */ Module* create_module(const std::string& name, Module* parent, const std::vector& gates = {}); - Module* create_module_python(const std::string& name, Module* parent, const std::vector& gates = {}); /** * Remove a module from the netlist. diff --git a/src/netlist/netlist.cpp b/src/netlist/netlist.cpp index 7e233a04f70..24a364b8992 100644 --- a/src/netlist/netlist.cpp +++ b/src/netlist/netlist.cpp @@ -7,7 +7,6 @@ #include "hal_core/netlist/net.h" #include "hal_core/netlist/netlist_internal_manager.h" #include "hal_core/utilities/log.h" -#include namespace hal { From d1f4279a5e77d71eacd294caf722cc84abbcd433 Mon Sep 17 00:00:00 2001 From: joern274 Date: Tue, 30 Jan 2024 17:53:20 +0100 Subject: [PATCH 29/40] bugfix: don't iterate over volatile list --- plugins/gui/src/module_model/module_model.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/gui/src/module_model/module_model.cpp b/plugins/gui/src/module_model/module_model.cpp index b671e8e7a9d..48c74c21202 100644 --- a/plugins/gui/src/module_model/module_model.cpp +++ b/plugins/gui/src/module_model/module_model.cpp @@ -491,7 +491,8 @@ namespace hal if (gateIds.isEmpty()) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) - netsToAssign = QSet(parentAssignment.keys().begin(),parentAssignment.keys().end()); + QList tempKeys = parentAssignment.keys(); + netsToAssign = QSet(tempKeys.begin(),tempKeys.end()); #else netsToAssign = parentAssignment.keys().toSet(); #endif From de83430a59cee52998dac7ec506d7ff769be9c88 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 31 Jan 2024 19:46:10 +0100 Subject: [PATCH 30/40] Make sure dock widget gets inserted with correct index --- plugins/gui/include/gui/docking_system/tab_widget.h | 6 ++++++ .../gui/src/content_layout_area/content_layout_area.cpp | 7 +++++++ plugins/gui/src/content_manager/content_manager.cpp | 2 +- plugins/gui/src/docking_system/tab_widget.cpp | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/plugins/gui/include/gui/docking_system/tab_widget.h b/plugins/gui/include/gui/docking_system/tab_widget.h index d5d56f5ea50..4881f0838da 100644 --- a/plugins/gui/include/gui/docking_system/tab_widget.h +++ b/plugins/gui/include/gui/docking_system/tab_widget.h @@ -116,6 +116,12 @@ namespace hal */ void handleNoCurrentWidget(int index); + /** + * Returns the number of widgets / buttons as of mDockBar->count() + * @return - The number of widgets / buttons + */ + int widgetCount() const; + /** * Removes all buttons from the dockbar and therefore the widgets from the area. The corresponding * widgets are not destroyed but hidden. diff --git a/plugins/gui/src/content_layout_area/content_layout_area.cpp b/plugins/gui/src/content_layout_area/content_layout_area.cpp index 8a3ac9b66f2..37f116bb4bb 100644 --- a/plugins/gui/src/content_layout_area/content_layout_area.cpp +++ b/plugins/gui/src/content_layout_area/content_layout_area.cpp @@ -1,5 +1,6 @@ #include "gui/content_layout_area/content_layout_area.h" +#include "hal_core/utilities/log.h" #include "gui/docking_system/dock_bar.h" #include "gui/docking_system/splitter_anchor.h" #include "gui/docking_system/tab_widget.h" @@ -109,6 +110,12 @@ namespace hal void ContentLayoutArea::addContent(ContentWidget* widget, int index, content_anchor anchor) { + if (index > mTabWidget->widgetCount()) + { + log_warning("gui", "Cannot insert widget '{}' at index {}, moved to index {}", widget->name().toStdString(), index, mTabWidget->widgetCount()); + index = mTabWidget->widgetCount(); + } + switch (anchor) { case content_anchor::center: diff --git a/plugins/gui/src/content_manager/content_manager.cpp b/plugins/gui/src/content_manager/content_manager.cpp index 8b2d13a7a0a..79f1e0e65b0 100644 --- a/plugins/gui/src/content_manager/content_manager.cpp +++ b/plugins/gui/src/content_manager/content_manager.cpp @@ -153,7 +153,7 @@ namespace hal mExternalIndex = 6; mGraphTabWidget = new GraphTabWidget(); - mMainWindow->addContent(mGraphTabWidget, 2, content_anchor::center); + mMainWindow->addContent(mGraphTabWidget, 0, content_anchor::center); mModuleWidget = new ModuleWidget(); mMainWindow->addContent(mModuleWidget, 0, content_anchor::left); diff --git a/plugins/gui/src/docking_system/tab_widget.cpp b/plugins/gui/src/docking_system/tab_widget.cpp index 15602f4f18f..42fb55b218d 100644 --- a/plugins/gui/src/docking_system/tab_widget.cpp +++ b/plugins/gui/src/docking_system/tab_widget.cpp @@ -201,4 +201,9 @@ namespace hal if (mDockBar->unused()) hide(); } + + int TabWidget::widgetCount() const + { + return mDockBar->count(); + } } From 7be5957ef354b8516e66aaf1347d88bc432f6f60 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 31 Jan 2024 21:09:52 +0100 Subject: [PATCH 31/40] Make sure dock widget gets inserted with correct index (fixed) --- .../gui/content_anchor/content_anchor.h | 5 ++++ .../gui/docking_system/splitter_anchor.h | 2 +- .../include/gui/docking_system/tab_widget.h | 2 +- .../content_layout_area.cpp | 24 ++++++++++++++++--- .../src/docking_system/splitter_anchor.cpp | 2 +- plugins/gui/src/docking_system/tab_widget.cpp | 2 +- 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/plugins/gui/include/gui/content_anchor/content_anchor.h b/plugins/gui/include/gui/content_anchor/content_anchor.h index eefe744c322..8fb03c1c8dd 100644 --- a/plugins/gui/include/gui/content_anchor/content_anchor.h +++ b/plugins/gui/include/gui/content_anchor/content_anchor.h @@ -84,6 +84,11 @@ namespace hal * Destructor that has to be overriden. */ virtual inline ~ContentAnchor() = 0; + + /** + * Returns the number of widgets / buttons as of mDockBar->count() + */ + virtual int count() const = 0; }; ContentAnchor::~ContentAnchor() diff --git a/plugins/gui/include/gui/docking_system/splitter_anchor.h b/plugins/gui/include/gui/docking_system/splitter_anchor.h index 7678f0c01f6..d7bd083c071 100644 --- a/plugins/gui/include/gui/docking_system/splitter_anchor.h +++ b/plugins/gui/include/gui/docking_system/splitter_anchor.h @@ -113,7 +113,7 @@ namespace hal * * @return The number of widgets. */ - int count(); + int count() const override; /** * Removes all buttons from the dockbar and therefore the widgets from the area. The corresponding diff --git a/plugins/gui/include/gui/docking_system/tab_widget.h b/plugins/gui/include/gui/docking_system/tab_widget.h index 4881f0838da..9692b36c411 100644 --- a/plugins/gui/include/gui/docking_system/tab_widget.h +++ b/plugins/gui/include/gui/docking_system/tab_widget.h @@ -120,7 +120,7 @@ namespace hal * Returns the number of widgets / buttons as of mDockBar->count() * @return - The number of widgets / buttons */ - int widgetCount() const; + int count() const override; /** * Removes all buttons from the dockbar and therefore the widgets from the area. The corresponding diff --git a/plugins/gui/src/content_layout_area/content_layout_area.cpp b/plugins/gui/src/content_layout_area/content_layout_area.cpp index 37f116bb4bb..8dc4d88d102 100644 --- a/plugins/gui/src/content_layout_area/content_layout_area.cpp +++ b/plugins/gui/src/content_layout_area/content_layout_area.cpp @@ -110,12 +110,30 @@ namespace hal void ContentLayoutArea::addContent(ContentWidget* widget, int index, content_anchor anchor) { - if (index > mTabWidget->widgetCount()) + int maxIndex = 0; + switch (anchor) { - log_warning("gui", "Cannot insert widget '{}' at index {}, moved to index {}", widget->name().toStdString(), index, mTabWidget->widgetCount()); - index = mTabWidget->widgetCount(); + case content_anchor::center: + maxIndex = mTabWidget->count(); + break; + case content_anchor::left: + maxIndex = mLeftAnchor->count(); + break; + case content_anchor::right: + maxIndex = mRightAnchor->count(); + break; + case content_anchor::bottom: + maxIndex = mBottomAnchor->count(); + break; + } + + if (index > maxIndex) + { + log_warning("gui", "Cannot insert widget '{}' at index {}, moved to index {}", widget->name().toStdString(), index, maxIndex); + index = maxIndex; } + switch (anchor) { case content_anchor::center: diff --git a/plugins/gui/src/docking_system/splitter_anchor.cpp b/plugins/gui/src/docking_system/splitter_anchor.cpp index 996ef138e21..5500e80a87f 100644 --- a/plugins/gui/src/docking_system/splitter_anchor.cpp +++ b/plugins/gui/src/docking_system/splitter_anchor.cpp @@ -95,7 +95,7 @@ namespace hal mDockBar->uncheckButton(widget); } - int SplitterAnchor::count() + int SplitterAnchor::count() const { return mDockBar->count(); } diff --git a/plugins/gui/src/docking_system/tab_widget.cpp b/plugins/gui/src/docking_system/tab_widget.cpp index 42fb55b218d..1934b53b9ef 100644 --- a/plugins/gui/src/docking_system/tab_widget.cpp +++ b/plugins/gui/src/docking_system/tab_widget.cpp @@ -202,7 +202,7 @@ namespace hal hide(); } - int TabWidget::widgetCount() const + int TabWidget::count() const { return mDockBar->count(); } From 656afa0be54b4ed05d3af762757294eb61a7be01 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 31 Jan 2024 21:20:24 +0100 Subject: [PATCH 32/40] Change wrong context index numbers to eliminate warnings --- plugins/gui/src/content_manager/content_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/gui/src/content_manager/content_manager.cpp b/plugins/gui/src/content_manager/content_manager.cpp index 79f1e0e65b0..09fd59069b2 100644 --- a/plugins/gui/src/content_manager/content_manager.cpp +++ b/plugins/gui/src/content_manager/content_manager.cpp @@ -150,7 +150,7 @@ namespace hal void ContentManager::handleOpenDocument(const QString& fileName) { - mExternalIndex = 6; + mExternalIndex = 1; mGraphTabWidget = new GraphTabWidget(); mMainWindow->addContent(mGraphTabWidget, 0, content_anchor::center); @@ -200,7 +200,7 @@ namespace hal mPythonWidget->open(); mPythonConsoleWidget = new PythonConsoleWidget(); - mMainWindow->addContent(mPythonConsoleWidget, 5, content_anchor::bottom); + mMainWindow->addContent(mPythonConsoleWidget, 2, content_anchor::bottom); mPythonConsoleWidget->open(); mContent.append(mGraphTabWidget); From 16ce2551cadab7c8269492c7ab90329d39da1d70 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 5 Feb 2024 15:45:15 +0100 Subject: [PATCH 33/40] intermediate bugfix --- .../include/gui/user_action/action_pingroup.h | 1 + .../module_ports_tree.cpp | 5 +- .../gui/src/user_action/action_pingroup.cpp | 54 +++++++++++++++++++ plugins/verilog_parser/src/verilog_parser.cpp | 5 ++ 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/plugins/gui/include/gui/user_action/action_pingroup.h b/plugins/gui/include/gui/user_action/action_pingroup.h index e9b31c54f1f..4ab871068f7 100644 --- a/plugins/gui/include/gui/user_action/action_pingroup.h +++ b/plugins/gui/include/gui/user_action/action_pingroup.h @@ -160,6 +160,7 @@ namespace hal static ActionPingroup* addPinsToNewGroup(const Module* m, const QString& name, QList pinIds, int grpRow = -1); static ActionPingroup* addPinToNewGroup(const Module* m, const QString& name, u32 pinId, int grpRow = -1); static ActionPingroup* removePinsFromGroup(const Module* m, QList pinIds); + static ActionPingroup* deletePinGroup(const Module* m, u32 grpId); }; /** diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp index 366b8fb1d09..b38eea359f7 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/module_ports_tree.cpp @@ -161,9 +161,8 @@ namespace hal auto* pinGroup = mod->get_pin_group_by_id(itemId); if (pinGroup != nullptr) { - ActionPingroup* act = new ActionPingroup(PinActionType::GroupDelete,(u32)itemId); - act->setObject(UserActionObject(mod->get_id(), UserActionObjectType::Module)); - act->exec(); + ActionPingroup* act = ActionPingroup::deletePinGroup(mod,itemId); + if (act) act->exec(); } }); diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index ceeaa40ad2a..0c98041eed0 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -482,6 +482,60 @@ namespace hal return addPinsToNewGroup(m,name,pinIds, grpRow); } + ActionPingroup* ActionPingroup::deletePinGroup(const Module *m, u32 grpId) + { + ActionPingroup* retval = nullptr; + + PinGroup* groupToDelete = m->get_pin_group_by_id(grpId); + if (!groupToDelete) return retval; + + QMap existingGroups; + for (PinGroup* pgroup : m->get_pin_groups()) + existingGroups.insert(QString::fromStdString(pgroup->get_name()),pgroup->get_id()); + + bool doNotDelete = false; // if there is a pin with the same name as the + int vid = -1; + + for (ModulePin* pin : groupToDelete->get_pins()) + { + if (pin->get_name() == groupToDelete->get_name()) + doNotDelete = true; + else + { + QString pinName = QString::fromStdString(pin->get_name()); + auto it = existingGroups.find(pinName); + if (it == existingGroups.end()) + { + if (retval) + retval->mPinActions.append(AtomicAction(PinActionType::GroupCreate,vid,pinName)); + else + retval = new ActionPingroup(PinActionType::GroupCreate,vid,pinName); + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignToGroup,pin->get_id(),"",vid)); + --vid; + } + else + { + if (retval) + retval->mPinActions.append(AtomicAction(PinActionType::PinAsignToGroup,pin->get_id(),"",it.value())); + else + retval = new ActionPingroup(PinActionType::PinAsignToGroup,pin->get_id(),"",it.value()); + } + } + + } + + if (!doNotDelete) + { + if (retval) + retval->mPinActions.append(AtomicAction(PinActionType::GroupDelete,groupToDelete->get_id())); + else + retval = new ActionPingroup(PinActionType::GroupDelete,groupToDelete->get_id()); + } + + retval->setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); + return retval; + } + ActionPingroup* ActionPingroup::removePinsFromGroup(const Module* m, QList pinIds) { ActionPingroup* retval = nullptr; diff --git a/plugins/verilog_parser/src/verilog_parser.cpp b/plugins/verilog_parser/src/verilog_parser.cpp index 985326f2d40..1771503cdba 100644 --- a/plugins/verilog_parser/src/verilog_parser.cpp +++ b/plugins/verilog_parser/src/verilog_parser.cpp @@ -1947,6 +1947,11 @@ namespace hal return {(u32)std::stoi(stream.consume().string)}; } + if (stream.peek(0).string=="35" && stream.peek(2).string=="32") + { + std::cerr << "parser <" << stream.peek(-1).string << ">" << std::endl; + } + // MSB to LSB const int end = std::stoi(stream.consume().string); stream.consume(":", true); From 84ec39bcc8088e76144869a2c315331b84c99442 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 8 Feb 2024 16:58:15 +0100 Subject: [PATCH 34/40] Restore verilog parser after abusing branch for parser test --- plugins/verilog_parser/src/verilog_parser.cpp | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/plugins/verilog_parser/src/verilog_parser.cpp b/plugins/verilog_parser/src/verilog_parser.cpp index 1771503cdba..216250f66e4 100644 --- a/plugins/verilog_parser/src/verilog_parser.cpp +++ b/plugins/verilog_parser/src/verilog_parser.cpp @@ -1236,6 +1236,7 @@ namespace hal for (const auto& expanded_port_identifier : port->m_expanded_identifiers) { const auto signal_name = get_unique_alias("", expanded_port_identifier + "__GLOBAL_IO__", m_net_name_occurences); + m_net_name_occurences[signal_name]++; Net* global_port_net = m_netlist->create_net(signal_name); if (global_port_net == nullptr) @@ -1590,7 +1591,10 @@ namespace hal { for (const auto& expanded_name : signal->m_expanded_names) { - signal_alias[expanded_name] = get_unique_alias(module->get_name(), expanded_name, m_net_name_occurences); + std::string unique_net_name = get_unique_alias(module->get_name(), expanded_name, m_net_name_occurences); + if (unique_net_name != expanded_name) + m_net_name_occurences[unique_net_name]++; + signal_alias[expanded_name] = unique_net_name; // create new net for the signal Net* signal_net = m_netlist->create_net(signal_alias.at(expanded_name)); @@ -1730,7 +1734,6 @@ namespace hal { // create the new gate instance_alias[instance->m_name] = get_unique_alias(module->get_name(), instance->m_name, m_instance_name_occurences); - Gate* new_gate = m_netlist->create_gate(gate_type_it->second, instance_alias.at(instance->m_name)); if (new_gate == nullptr) { @@ -1931,9 +1934,22 @@ namespace hal if (!parent_name.empty()) { // if there is no other instance with that name, we omit the name prefix - if (const auto instance_name_it = name_occurences.find(name); instance_name_it != name_occurences.end() && instance_name_it->second > 1) + + auto instance_name_it = name_occurences.find(name); + + int cnt = 0; + + // it is OK if base name (first loop cnt=0) is already in name_occurences once + // unique_alias (cnt > 0) must not be in name_occurences + while (instance_name_it != name_occurences.end() && (cnt || instance_name_it->second > 1) ) { - unique_alias = parent_name + instance_name_seperator + unique_alias; + std::string extension; + if (cnt++) + { + extension = "_u" + std::to_string(cnt); + } + unique_alias = parent_name + instance_name_seperator + unique_alias + extension; + instance_name_it = name_occurences.find(unique_alias); } } @@ -1947,11 +1963,6 @@ namespace hal return {(u32)std::stoi(stream.consume().string)}; } - if (stream.peek(0).string=="35" && stream.peek(2).string=="32") - { - std::cerr << "parser <" << stream.peek(-1).string << ">" << std::endl; - } - // MSB to LSB const int end = std::stoi(stream.consume().string); stream.consume(":", true); From d192f8817cf04289a3a48a81db479f7a93a10243 Mon Sep 17 00:00:00 2001 From: HerrKermet Date: Thu, 8 Feb 2024 19:45:13 +0100 Subject: [PATCH 35/40] added nullptr checks --- plugins/gui/src/module_widget/module_widget.cpp | 8 ++++++-- .../selection_details_widget.cpp | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/gui/src/module_widget/module_widget.cpp b/plugins/gui/src/module_widget/module_widget.cpp index 0ecaa5212b2..4ec4b21c8b9 100644 --- a/plugins/gui/src/module_widget/module_widget.cpp +++ b/plugins/gui/src/module_widget/module_widget.cpp @@ -611,8 +611,12 @@ namespace hal for (auto module_id : gSelectionRelay->selectedModulesList()) { - QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndexFromItem(mModuleModel->getItem(module_id))); - module_selection.select(index, index); + ModuleItem* item = mModuleModel->getItem(module_id); + if(item) + { + QModelIndex index = mModuleProxyModel->mapFromSource(mModuleModel->getIndexFromItem(item)); + module_selection.select(index, index); + } } mTreeView->selectionModel()->select(module_selection, QItemSelectionModel::SelectionFlag::ClearAndSelect); diff --git a/plugins/gui/src/selection_details_widget/selection_details_widget.cpp b/plugins/gui/src/selection_details_widget/selection_details_widget.cpp index 9e9f47f552a..f872c443965 100644 --- a/plugins/gui/src/selection_details_widget/selection_details_widget.cpp +++ b/plugins/gui/src/selection_details_widget/selection_details_widget.cpp @@ -451,10 +451,14 @@ namespace hal // set_name("Selection Details"); break; case SelectionTreeItem::ModuleItem: - mModuleDetailsTabs->setModule(gNetlist->get_module_by_id(sti->id())); - mStackedWidget->setCurrentWidget(mModuleDetailsTabs); -// if (mNumberSelectedItems==1) set_name("Module Details"); + if (Module* m = gNetlist->get_module_by_id(sti->id()); m) + { + mModuleDetailsTabs->setModule(m); + mStackedWidget->setCurrentWidget(mModuleDetailsTabs); + } + // if (mNumberSelectedItems==1) set_name("Module Details"); break; + case SelectionTreeItem::GateItem: if(mStackedWidget->currentWidget() == mModuleDetailsTabs) mModuleDetailsTabs->clear(); From 15d2420922304745cc87821532288edafc7ff4f9 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 15 Feb 2024 17:17:49 +0100 Subject: [PATCH 36/40] Several fixes to pin event handling --- include/hal_core/netlist/module.h | 1 - .../include/gui/netlist_relay/netlist_relay.h | 1 + plugins/gui/src/netlist_relay/netlist_relay.cpp | 9 +++++++++ .../module_details_widget/port_tree_model.cpp | 10 ++++++++++ plugins/gui/src/user_action/action_pingroup.cpp | 2 ++ src/netlist/event_system/event_log.cpp | 5 ++++- src/netlist/module.cpp | 17 +++++++++++++---- 7 files changed, 39 insertions(+), 6 deletions(-) diff --git a/include/hal_core/netlist/module.h b/include/hal_core/netlist/module.h index bd4b833553a..0cccca0441e 100644 --- a/include/hal_core/netlist/module.h +++ b/include/hal_core/netlist/module.h @@ -734,7 +734,6 @@ namespace hal std::unordered_map*> m_pin_groups_map; std::unordered_map*> m_pin_group_names_map; std::list*> m_pin_groups_ordered; - u32 m_pin_number[4] = { 0, 0, 0, 0 }; /* stores gates sorted by id */ std::unordered_map m_gates_map; diff --git a/plugins/gui/include/gui/netlist_relay/netlist_relay.h b/plugins/gui/include/gui/netlist_relay/netlist_relay.h index e8cc5c3275e..7e0630d1243 100644 --- a/plugins/gui/include/gui/netlist_relay/netlist_relay.h +++ b/plugins/gui/include/gui/netlist_relay/netlist_relay.h @@ -607,6 +607,7 @@ namespace hal void relayGateEvent(GateEvent::event ev, Gate* gat, u32 associated_data); void relayNetEvent(NetEvent::event ev, Net* net, u32 associated_data); void relayGroupingEvent(GroupingEvent::event ev, Grouping* grp, u32 associated_data); + static void dumpModuleRecursion(Module* m); void handleNetlistModified(); bool mNotified; diff --git a/plugins/gui/src/netlist_relay/netlist_relay.cpp b/plugins/gui/src/netlist_relay/netlist_relay.cpp index 541d46e2655..51c154a50d7 100644 --- a/plugins/gui/src/netlist_relay/netlist_relay.cpp +++ b/plugins/gui/src/netlist_relay/netlist_relay.cpp @@ -661,6 +661,15 @@ namespace hal } } + void NetlistRelay::dumpModuleRecursion(Module *m) + { + for (int i=0; iget_submodule_depth(); i++) + std::cerr << " "; + std::cerr << "Mod " << m->get_id() << " <" << m->get_name() << ">\n"; + for (Module* sm : m->get_submodules()) + dumpModuleRecursion(sm); + } + void NetlistRelay::debugHandleFileOpened() { for (Module* m : gNetlist->get_modules()) diff --git a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp index 204f9191f53..f38d4ad5819 100644 --- a/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp +++ b/plugins/gui/src/selection_details_widget/module_details_widget/port_tree_model.cpp @@ -529,6 +529,11 @@ namespace hal { // group event ptiGroup = mIdToGroupItem.value(pgid); + if (pev != PinEvent::GroupCreate && !ptiGroup) + { + log_warning("gui", "Cannot handle event for pin group ID={}, tree item does not exist.", pgid); + return; + } if (pev != PinEvent::GroupDelete) { pgroup = m->get_pin_group_by_id(pgid); @@ -543,6 +548,11 @@ namespace hal { // pin event ptiPin = mIdToPinItem.value(pgid); + if (pev != PinEvent::PinCreate && !ptiPin) + { + log_warning("gui", "Cannot handle event for pin ID={}, tree item does not exist.", pgid); + return; + } if (pev != PinEvent::PinDelete) { pin = m->get_pin_by_id(pgid); diff --git a/plugins/gui/src/user_action/action_pingroup.cpp b/plugins/gui/src/user_action/action_pingroup.cpp index 0c98041eed0..73de9f426aa 100644 --- a/plugins/gui/src/user_action/action_pingroup.cpp +++ b/plugins/gui/src/user_action/action_pingroup.cpp @@ -3,6 +3,7 @@ #include "hal_core/netlist/grouping.h" #include "gui/grouping/grouping_manager_widget.h" #include "gui/graph_widget/contexts/graph_context.h" +#include "gui/graph_widget/layout_locker.h" #include namespace hal @@ -291,6 +292,7 @@ namespace hal return false; prepareUndoAction(); // create pingroups in case we are going to delete some while assigning + LayoutLocker llock; for (const AtomicAction& aa : mPinActions) { diff --git a/src/netlist/event_system/event_log.cpp b/src/netlist/event_system/event_log.cpp index 1f1973a2603..3dd2eb41a6b 100644 --- a/src/netlist/event_system/event_log.cpp +++ b/src/netlist/event_system/event_log.cpp @@ -287,7 +287,10 @@ namespace hal } else if (event == ModuleEvent::event::pin_changed) { - log_info("event", "changed port of module '{}' (id {:08x})", module->get_name(), module->get_id()); + PinEvent pev = (PinEvent) (associated_data&0xF); + u32 id = (associated_data >> 4); + + log_info("event", "module '{}' (id {:08x}) port event '{}' id={}", module->get_name(), module->get_id(), enum_to_string(pev), id); } else { diff --git a/src/netlist/module.cpp b/src/netlist/module.cpp index 74da03ce416..612db982c25 100644 --- a/src/netlist/module.cpp +++ b/src/netlist/module.cpp @@ -1548,8 +1548,9 @@ namespace hal bool Module::assign_pin_net(const u32 pin_id, Net* net, PinDirection direction) { + PinChangedEventScope scope(this); std::string port_prefix; - + u32 ctr = 0; switch (direction) { case PinDirection::input: @@ -1566,7 +1567,12 @@ namespace hal return false; } - std::string name_internal = port_prefix + "(" + std::to_string(m_pin_number[(int)direction]) + ")"; + std::string name_internal; + do + { + name_internal = port_prefix + "(" + std::to_string(ctr) + ")"; + ctr++; + } while (m_pin_names_map.find(name_internal) != m_pin_names_map.end() || m_pin_group_names_map.find(name_internal) != m_pin_group_names_map.end()); // create pin ModulePin* pin; @@ -1578,6 +1584,7 @@ namespace hal else { pin = res.get(); + PinChangedEvent(this,PinEvent::PinCreate,pin->get_id()).send(); } if (const auto group_res = create_pin_group_internal(get_unique_pin_group_id(), name_internal, pin->get_direction(), pin->get_type(), true, 0, false); group_res.is_error()) @@ -1587,14 +1594,17 @@ namespace hal } else { + PinChangedEvent(this,PinEvent::GroupCreate,group_res.get()->get_id()).send(); if (!group_res.get()->assign_pin(pin)) { log_warning("module", "could not assign pin '{}' to net: failed to assign pin to pin group", name_internal); return false; } + else + PinChangedEvent(this,PinEvent::PinAssignToGroup,pin->get_id()).send(); } - PinChangedEvent(this,PinEvent::GroupCreate,pin->get_group().first->get_id()).send(); + scope.send_events(); return true; } @@ -1682,7 +1692,6 @@ namespace hal m_pins.push_back(std::move(pin_owner)); m_pins_map[id] = pin; m_pin_names_map[name] = pin; - ++m_pin_number[(int)direction]; // mark pin ID as used if (auto free_id_it = m_free_pin_ids.find(id); free_id_it != m_free_pin_ids.end()) From 54dacd6ca67fe504b9d3097bf76f56bf7ded7c64 Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 19 Feb 2024 09:02:58 +0100 Subject: [PATCH 37/40] Remember module ID upon 'undo module delete' --- plugins/gui/src/user_action/action_create_object.cpp | 9 ++++++++- plugins/gui/src/user_action/action_delete_object.cpp | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/gui/src/user_action/action_create_object.cpp b/plugins/gui/src/user_action/action_create_object.cpp index 8a501f44b13..236cf48c73e 100644 --- a/plugins/gui/src/user_action/action_create_object.cpp +++ b/plugins/gui/src/user_action/action_create_object.cpp @@ -86,8 +86,15 @@ namespace hal Module* parentModule = gNetlist->get_module_by_id(mParentId); if (parentModule) { - Module* m = gNetlist->create_module(gNetlist->get_unique_module_id(), + u32 modId = mObject.id() ? mObject.id() : gNetlist->get_unique_module_id(); + Module* m = gNetlist->create_module(modId, mObjectName.toStdString(), parentModule); + if (!m) + { + log_warning("gui", "Failed to create module '{}' with ID={} under parent ID={}.", + mObjectName.toStdString(), modId, mParentId); + return false; + } setObject(UserActionObject(m->get_id(),UserActionObjectType::Module)); standardUndo = true; } diff --git a/plugins/gui/src/user_action/action_delete_object.cpp b/plugins/gui/src/user_action/action_delete_object.cpp index 23db22c4cd8..ad1a5c5266e 100644 --- a/plugins/gui/src/user_action/action_delete_object.cpp +++ b/plugins/gui/src/user_action/action_delete_object.cpp @@ -74,6 +74,7 @@ namespace hal UserActionCompound* act = new UserActionCompound; act->setUseCreatedObject(); ActionCreateObject* actCreate = new ActionCreateObject(UserActionObjectType::Module, QString::fromStdString(mod->get_name())); + actCreate->setObject(mObject); actCreate->setParentId(mod->get_parent_module()->get_id()); act->addAction(actCreate); act->addAction(new ActionSetObjectType(QString::fromStdString(mod->get_type()))); From 088ea00b0cfb323037e2de8e78970f309116c4c4 Mon Sep 17 00:00:00 2001 From: joern274 Date: Wed, 21 Feb 2024 16:58:32 +0100 Subject: [PATCH 38/40] Bugfix: lock view layout redraw by ID (not by pointer) --- .../gui/include/gui/graph_widget/layout_locker.h | 3 ++- plugins/gui/src/graph_widget/layout_locker.cpp | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/plugins/gui/include/gui/graph_widget/layout_locker.h b/plugins/gui/include/gui/graph_widget/layout_locker.h index ebc6472a05c..34af29617d5 100644 --- a/plugins/gui/include/gui/graph_widget/layout_locker.h +++ b/plugins/gui/include/gui/graph_widget/layout_locker.h @@ -26,6 +26,7 @@ #pragma once #include +#include "hal_core/defines.h" namespace hal { @@ -37,7 +38,7 @@ namespace hal LayoutLockerManager(); int mLockCount; - QSet mWaitingRoom; + QSet mWaitingRoom; public: static LayoutLockerManager* instance(); diff --git a/plugins/gui/src/graph_widget/layout_locker.cpp b/plugins/gui/src/graph_widget/layout_locker.cpp index 70082902bdb..e2bf1f46bb2 100644 --- a/plugins/gui/src/graph_widget/layout_locker.cpp +++ b/plugins/gui/src/graph_widget/layout_locker.cpp @@ -1,4 +1,5 @@ #include "gui/graph_widget/layout_locker.h" +#include "gui/gui_globals.h" #include "gui/graph_widget/contexts/graph_context.h" namespace hal { @@ -22,24 +23,29 @@ namespace hal { void LayoutLockerManager::removeLock() { --mLockCount; + if (mLockCount <= 0 && !mWaitingRoom.isEmpty()) { - for (GraphContext* ctx : mWaitingRoom) - ctx->startSceneUpdate(); + for (u32 ctxId : mWaitingRoom) + { + GraphContext* ctx = gGraphContextManager->getContextById(ctxId); + if (ctx) ctx->startSceneUpdate(); + } mWaitingRoom.clear(); } } bool LayoutLockerManager::canUpdate(GraphContext* ctx) { + if (!ctx) return false; if (mLockCount <= 0) return true; - mWaitingRoom.insert(ctx); + mWaitingRoom.insert(ctx->id()); return false; } void LayoutLockerManager::removeWaitingContext(GraphContext* ctx) { - auto it = mWaitingRoom.find(ctx); + auto it = mWaitingRoom.find(ctx->id()); if (it != mWaitingRoom.end()) mWaitingRoom.erase(it); } From 62b5f7cfd52502bf8eafa7f9cf4bbf67a9062338 Mon Sep 17 00:00:00 2001 From: joern274 Date: Thu, 29 Feb 2024 13:26:27 +0100 Subject: [PATCH 39/40] Added INIT field declaration to FF-gate-types in example library --- CHANGELOG.md | 1 + .../definitions/example_library.hgl | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad3ccb7183b..ac0e1def95b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. * removed layouter code used prior to version 3.1.0 - thus removing the setting option to use that code * added setting option to dump junction layout input data for experts to debug in case of layout errors * miscellaneous + * added INIT field declaration to FF-gate-types in example library * added drag'n drop feature allowing to move several nodes in graph view at same time * added functions to Python GUI API to create, modifiy and delete views * added GUI PluginParameter type `ComboBox` for parameters that can be requested from plugin diff --git a/plugins/gate_libraries/definitions/example_library.hgl b/plugins/gate_libraries/definitions/example_library.hgl index b42016e1c2c..ed1af26c8af 100644 --- a/plugins/gate_libraries/definitions/example_library.hgl +++ b/plugins/gate_libraries/definitions/example_library.hgl @@ -2055,7 +2055,9 @@ "state": "IQ", "neg_state": "IQN", "next_state": "(D & CE)", - "clocked_on": "C" + "clocked_on": "C", + "data_category": "generic", + "data_identifier": "INIT" }, "pin_groups": [ { @@ -2128,7 +2130,9 @@ "neg_state": "IQN", "next_state": "(D & CE)", "clocked_on": "C", - "preset_on": "S" + "preset_on": "S", + "data_category": "generic", + "data_identifier": "INIT" }, "pin_groups": [ { @@ -2215,7 +2219,9 @@ "neg_state": "IQN", "next_state": "(D & CE)", "clocked_on": "C", - "clear_on": "R" + "clear_on": "R", + "data_category": "generic", + "data_identifier": "INIT" }, "pin_groups": [ { @@ -2305,7 +2311,9 @@ "clear_on": "R", "preset_on": "S", "state_clear_preset": "L", - "neg_state_clear_preset": "H" + "neg_state_clear_preset": "H", + "data_category": "generic", + "data_identifier": "INIT" }, "pin_groups": [ { @@ -2444,4 +2452,4 @@ ] } ] -} \ No newline at end of file +} From 95b424a36a1735d022026a2dc77937877c224c8c Mon Sep 17 00:00:00 2001 From: joern274 Date: Mon, 11 Mar 2024 21:43:16 +0100 Subject: [PATCH 40/40] Uncomment unneeded ASSERT --- plugins/gui/src/graph_widget/layouters/graph_layouter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/gui/src/graph_widget/layouters/graph_layouter.cpp b/plugins/gui/src/graph_widget/layouters/graph_layouter.cpp index ae6eee941ee..d3493a7fc83 100644 --- a/plugins/gui/src/graph_widget/layouters/graph_layouter.cpp +++ b/plugins/gui/src/graph_widget/layouters/graph_layouter.cpp @@ -778,7 +778,7 @@ namespace hal { iy0 = ityLast.key(); int iy1 = itNext.key(); - Q_ASSERT(iy1 == iy0 + 1); +// Q_ASSERT(iy1 == iy0 + 1); if (iy0 % 2 != 0) { // netjunction -> endpoint