refactor(selection): made selection shared_ptr rather than weak_ptr

This commit is contained in:
maelstrom 2025-05-30 01:20:08 +02:00
parent f6d5ebd7c7
commit 215fa141b6
8 changed files with 31 additions and 29 deletions

View file

@ -14,11 +14,11 @@ std::optional<HierarchyPostUpdateHandler> hierarchyPostUpdateHandler;
Handles editorToolHandles; Handles editorToolHandles;
std::vector<InstanceRefWeak> currentSelection; std::vector<std::shared_ptr<Instance>> currentSelection;
std::vector<SelectionUpdateHandler> selectionUpdateListeners; std::vector<SelectionUpdateHandler> selectionUpdateListeners;
std::vector<PropertyUpdateHandler> propertyUpdatelisteners; std::vector<PropertyUpdateHandler> propertyUpdatelisteners;
void setSelection(std::vector<InstanceRefWeak> newSelection, bool fromExplorer) { void setSelection(std::vector<std::shared_ptr<Instance>> newSelection, bool fromExplorer) {
for (SelectionUpdateHandler handler : selectionUpdateListeners) { for (SelectionUpdateHandler handler : selectionUpdateListeners) {
handler(currentSelection, newSelection, fromExplorer); handler(currentSelection, newSelection, fromExplorer);
} }
@ -26,7 +26,7 @@ void setSelection(std::vector<InstanceRefWeak> newSelection, bool fromExplorer)
currentSelection = newSelection; currentSelection = newSelection;
} }
const std::vector<InstanceRefWeak> getSelection() { const std::vector<std::shared_ptr<Instance>> getSelection() {
return currentSelection; return currentSelection;
} }

View file

@ -11,7 +11,7 @@ class Instance;
// typedef std::function<void(std::shared_ptr<Instance> element, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyUpdateHandler; // typedef std::function<void(std::shared_ptr<Instance> element, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyUpdateHandler;
typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPreUpdateHandler; typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPreUpdateHandler;
typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPostUpdateHandler; typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPostUpdateHandler;
typedef std::function<void(std::vector<InstanceRefWeak> oldSelection, std::vector<InstanceRefWeak> newSelection, bool fromExplorer)> SelectionUpdateHandler; typedef std::function<void(std::vector<std::shared_ptr<Instance>> oldSelection, std::vector<std::shared_ptr<Instance>> newSelection, bool fromExplorer)> SelectionUpdateHandler;
typedef std::function<void(InstanceRef instance, std::string property, Data::Variant newValue)> PropertyUpdateHandler; typedef std::function<void(InstanceRef instance, std::string property, Data::Variant newValue)> PropertyUpdateHandler;
// TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS // TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS
@ -24,8 +24,8 @@ extern std::optional<HierarchyPreUpdateHandler> hierarchyPreUpdateHandler;
extern std::optional<HierarchyPostUpdateHandler> hierarchyPostUpdateHandler; extern std::optional<HierarchyPostUpdateHandler> hierarchyPostUpdateHandler;
extern Handles editorToolHandles; extern Handles editorToolHandles;
void setSelection(std::vector<InstanceRefWeak> newSelection, bool fromExplorer = false); void setSelection(std::vector<std::shared_ptr<Instance>> newSelection, bool fromExplorer = false);
const std::vector<InstanceRefWeak> getSelection(); const std::vector<std::shared_ptr<Instance>> getSelection();
void addSelectionListener(SelectionUpdateHandler handler); void addSelectionListener(SelectionUpdateHandler handler);
void sendPropertyUpdatedSignal(InstanceRef instance, std::string property, Data::Variant newValue); void sendPropertyUpdatedSignal(InstanceRef instance, std::string property, Data::Variant newValue);

View file

@ -32,7 +32,7 @@ PartAssembly::PartAssembly(std::vector<std::shared_ptr<Part>> parts, bool worldM
_bounds = size; _bounds = size;
} }
PartAssembly PartAssembly::FromSelection(std::vector<std::weak_ptr<Instance>> newSelection) { PartAssembly PartAssembly::FromSelection(std::vector<std::shared_ptr<Instance>> newSelection) {
std::vector<std::shared_ptr<Part>> selection; std::vector<std::shared_ptr<Part>> selection;
for (std::weak_ptr<Instance> obj : newSelection) { for (std::weak_ptr<Instance> obj : newSelection) {

View file

@ -7,7 +7,7 @@
class Part; class Part;
class Instance; class Instance;
const std::vector<std::weak_ptr<Instance>> getSelection(); const std::vector<std::shared_ptr<Instance>> getSelection();
class PartAssembly { class PartAssembly {
CFrame _assemblyOrigin; CFrame _assemblyOrigin;
@ -17,7 +17,7 @@ class PartAssembly {
public: public:
PartAssembly(std::vector<std::shared_ptr<Part>>, bool worldMode = false); PartAssembly(std::vector<std::shared_ptr<Part>>, bool worldMode = false);
static PartAssembly FromSelection(std::vector<std::weak_ptr<Instance>> selection = getSelection()); static PartAssembly FromSelection(std::vector<std::shared_ptr<Instance>> selection = getSelection());
inline CFrame assemblyOrigin() { return _assemblyOrigin; }; inline CFrame assemblyOrigin() { return _assemblyOrigin; };
inline Vector3 bounds() { return _bounds; }; inline Vector3 bounds() { return _bounds; };

View file

@ -556,7 +556,9 @@ void renderRotationArcs() {
// Pass in the camera position // Pass in the camera position
handleShader->set("viewPos", camera.cameraPos); handleShader->set("viewPos", camera.cameraPos);
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(getSelection()[0].lock()); // TODO: This won't do... Doesn't support rotating multiple objects, and expects the first selected item to be a part,
// which isn't always the case
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(getSelection()[0]);
for (HandleFace face : HandleFace::Faces) { for (HandleFace face : HandleFace::Faces) {
if (glm::any(glm::lessThan(face.normal, glm::vec3(0)))) continue; if (glm::any(glm::lessThan(face.normal, glm::vec3(0)))) continue;

View file

@ -417,10 +417,10 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
isMouseDragging = true; isMouseDragging = true;
draggingObject = part; draggingObject = part;
if (evt->modifiers() & Qt::ControlModifier) { if (evt->modifiers() & Qt::ControlModifier) {
std::vector<InstanceRefWeak> currentSelection = getSelection(); std::vector<std::shared_ptr<Instance>> currentSelection = getSelection();
for (int i = 0; i < currentSelection.size(); i++) { for (int i = 0; i < currentSelection.size(); i++) {
InstanceRefWeak inst = currentSelection[i]; std::shared_ptr<Instance> inst = currentSelection[i];
if (!inst.expired() && inst.lock() == part) { if (inst == part) {
currentSelection.erase(currentSelection.begin() + i); currentSelection.erase(currentSelection.begin() + i);
goto skipAddPart; goto skipAddPart;
} }
@ -429,7 +429,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
skipAddPart: skipAddPart:
setSelection(currentSelection); setSelection(currentSelection);
} else } else
setSelection(std::vector<InstanceRefWeak> { part }); setSelection({ part });
// Disable bit so that we can ignore the part while raycasting // Disable bit so that we can ignore the part while raycasting
// part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b10); // part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b10);
@ -488,11 +488,11 @@ void MainGLWidget::keyPressEvent(QKeyEvent* evt) {
if (evt->key() == Qt::Key_O) if (evt->key() == Qt::Key_O)
Logger::error("error message"); Logger::error("error message");
if (evt->key() == Qt::Key_C && getSelection().size() > 0 && !getSelection()[0].expired()) if (evt->key() == Qt::Key_C && getSelection().size() > 0)
getSelection()[0].lock()->Clone().value()->SetParent(gWorkspace()); getSelection()[0]->Clone().value()->SetParent(gWorkspace());
if (evt->key() == Qt::Key_H && getSelection().size() > 0 && !getSelection()[0].expired()) if (evt->key() == Qt::Key_H && getSelection().size() > 0)
Logger::infof("Object at: 0x%x\n", getSelection()[0].lock().get()); Logger::infof("Object at: 0x%x\n", getSelection()[0].get());
} }
void MainGLWidget::keyReleaseEvent(QKeyEvent* evt) { void MainGLWidget::keyReleaseEvent(QKeyEvent* evt) {

View file

@ -90,7 +90,7 @@ MainWindow::MainWindow(QWidget *parent)
if (newSelection.size() == 0) return; if (newSelection.size() == 0) return;
if (newSelection.size() > 1) if (newSelection.size() > 1)
ui->propertiesView->setSelected(std::nullopt); ui->propertiesView->setSelected(std::nullopt);
ui->propertiesView->setSelected(newSelection[0].lock()); ui->propertiesView->setSelected(newSelection[0]);
}); });
addSelectionListener([&](auto oldSelection, auto newSelection, bool __) { addSelectionListener([&](auto oldSelection, auto newSelection, bool __) {
@ -295,7 +295,7 @@ void MainWindow::connectActionHandlers() {
if (inst.expired()) continue; if (inst.expired()) continue;
inst.lock()->SetParent(std::nullopt); inst.lock()->SetParent(std::nullopt);
} }
setSelection(std::vector<InstanceRefWeak> {}); setSelection({});
}); });
connect(ui->actionCopy, &QAction::triggered, this, [&]() { connect(ui->actionCopy, &QAction::triggered, this, [&]() {
@ -345,9 +345,9 @@ void MainWindow::connectActionHandlers() {
}); });
connect(ui->actionPasteInto, &QAction::triggered, this, [&]() { connect(ui->actionPasteInto, &QAction::triggered, this, [&]() {
if (getSelection().size() != 1 || getSelection()[0].expired()) return; if (getSelection().size() != 1) return;
InstanceRef selectedParent = getSelection()[0].lock(); InstanceRef selectedParent = getSelection()[0];
const QMimeData* mimeData = QApplication::clipboard()->mimeData(); const QMimeData* mimeData = QApplication::clipboard()->mimeData();
if (!mimeData || !mimeData->hasFormat("application/xml")) return; if (!mimeData || !mimeData->hasFormat("application/xml")) return;
@ -382,8 +382,8 @@ void MainWindow::connectActionHandlers() {
}); });
connect(ui->actionInsertModel, &QAction::triggered, this, [&]() { connect(ui->actionInsertModel, &QAction::triggered, this, [&]() {
if (getSelection().size() != 1 || getSelection()[0].expired()) return; if (getSelection().size() != 1) return;
InstanceRef selectedParent = getSelection()[0].lock(); InstanceRef selectedParent = getSelection()[0];
std::optional<std::string> path = openFileDialog("Openblocks Model (*.obm)", ".obm", QFileDialog::AcceptOpen); std::optional<std::string> path = openFileDialog("Openblocks Model (*.obm)", ".obm", QFileDialog::AcceptOpen);
if (!path) return; if (!path) return;

View file

@ -38,11 +38,11 @@ ExplorerView::ExplorerView(QWidget* parent):
}); });
connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, [&](const QItemSelection &selected, const QItemSelection &deselected) { connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, [&](const QItemSelection &selected, const QItemSelection &deselected) {
std::vector<InstanceRefWeak> selectedInstances; std::vector<std::shared_ptr<Instance>> selectedInstances;
selectedInstances.reserve(selectedIndexes().count()); // This doesn't reserve everything, but should enhance things anyway selectedInstances.reserve(selectedIndexes().count()); // This doesn't reserve everything, but should enhance things anyway
for (auto index : selectedIndexes()) { for (auto index : selectedIndexes()) {
selectedInstances.push_back(reinterpret_cast<Instance*>(index.internalPointer())->weak_from_this()); selectedInstances.push_back(reinterpret_cast<Instance*>(index.internalPointer())->shared_from_this());
} }
::setSelection(selectedInstances, true); ::setSelection(selectedInstances, true);
@ -104,8 +104,8 @@ void ExplorerView::buildContextMenu() {
QAction* instAction = new QAction(model.iconOf(type), QString::fromStdString(type->className)); QAction* instAction = new QAction(model.iconOf(type), QString::fromStdString(type->className));
insertObjectMenu->addAction(instAction); insertObjectMenu->addAction(instAction);
connect(instAction, &QAction::triggered, this, [&]() { connect(instAction, &QAction::triggered, this, [&]() {
if (getSelection().size() == 0 || getSelection()[0].expired()) return; if (getSelection().size() == 0) return;
std::shared_ptr<Instance> instParent = getSelection()[0].lock(); std::shared_ptr<Instance> instParent = getSelection()[0];
std::shared_ptr<Instance> newInst = type->constructor(); std::shared_ptr<Instance> newInst = type->constructor();
newInst->SetParent(instParent); newInst->SetParent(instParent);
}); });