refactor(misc): removed InstanceRef and InstanceRefWeak type aliases due to confusion with Data::InstanceRef

Possible alternative names: Object and ObjectWeak
This commit is contained in:
maelstrom 2025-05-30 01:27:22 +02:00
parent 215fa141b6
commit 497a3f783c
18 changed files with 71 additions and 118 deletions

View file

@ -53,7 +53,7 @@ static std::string castToVariant(std::string valueStr, std::string fieldType) {
return "Data::Int((int)" + valueStr + ")"; return "Data::Int((int)" + valueStr + ")";
} }
// InstanceRef // std::shared_ptr<Instance>
std::string subtype = parseWeakPtr(fieldType); std::string subtype = parseWeakPtr(fieldType);
if (!subtype.empty()) { if (!subtype.empty()) {
return "Data::Variant(" + valueStr + ".expired() ? Data::InstanceRef() : Data::InstanceRef(std::dynamic_pointer_cast<Instance>(" + valueStr + ".lock())))"; return "Data::Variant(" + valueStr + ".expired() ? Data::InstanceRef() : Data::InstanceRef(std::dynamic_pointer_cast<Instance>(" + valueStr + ".lock())))";
@ -73,7 +73,7 @@ static void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) {
bool first = true; bool first = true;
for (auto& prop : state.properties) { for (auto& prop : state.properties) {
out << (first ? "" : " else ") << "if (name == \"" << prop.name << "\") {"; out << (first ? "" : " else ") << "if (name == \"" << prop.name << "\") {";
// InstanceRef // std::shared_ptr<Instance>
std::string subtype = parseWeakPtr(prop.backingFieldType); std::string subtype = parseWeakPtr(prop.backingFieldType);
if (prop.flags & PropertyFlag_Readonly) { if (prop.flags & PropertyFlag_Readonly) {

View file

@ -52,7 +52,7 @@ int main() {
.color = glm::vec3(0.639216f, 0.635294f, 0.647059f), .color = glm::vec3(0.639216f, 0.635294f, 0.647059f),
})); }));
for (InstanceRef inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
gWorkspace()->SyncPartPhysics(part); gWorkspace()->SyncPartPhysics(part);

View file

@ -34,7 +34,7 @@ void addSelectionListener(SelectionUpdateHandler handler) {
selectionUpdateListeners.push_back(handler); selectionUpdateListeners.push_back(handler);
} }
void sendPropertyUpdatedSignal(InstanceRef instance, std::string property, Data::Variant newValue) { void sendPropertyUpdatedSignal(std::shared_ptr<Instance> instance, std::string property, Data::Variant newValue) {
for (PropertyUpdateHandler handler : propertyUpdatelisteners) { for (PropertyUpdateHandler handler : propertyUpdatelisteners) {
handler(instance, property, newValue); handler(instance, property, newValue);
} }

View file

@ -9,10 +9,10 @@
class Instance; 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(std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyPreUpdateHandler;
typedef std::function<void(InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent)> HierarchyPostUpdateHandler; typedef std::function<void(std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyPostUpdateHandler;
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(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(std::shared_ptr<Instance> instance, std::string property, Data::Variant newValue)> PropertyUpdateHandler;
// TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS // TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS
@ -28,5 +28,5 @@ void setSelection(std::vector<std::shared_ptr<Instance>> newSelection, bool from
const std::vector<std::shared_ptr<Instance>> 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(std::shared_ptr<Instance> instance, std::string property, Data::Variant newValue);
void addPropertyUpdateListener(PropertyUpdateHandler handler); void addPropertyUpdateListener(PropertyUpdateHandler handler);

View file

@ -109,7 +109,7 @@ void Instance::updateAncestry(std::optional<std::shared_ptr<Instance>> updatedCh
} }
// Update ancestry in descendants // Update ancestry in descendants
for (InstanceRef child : children) { for (std::shared_ptr<Instance> child : children) {
child->updateAncestry(updatedChild, newParent); child->updateAncestry(updatedChild, newParent);
} }
} }
@ -272,7 +272,7 @@ void Instance::Serialize(pugi::xml_node parent, RefStateSerialize state) {
pugi::xml_node propertyNode = propertiesNode.append_child(meta.type->name); pugi::xml_node propertyNode = propertiesNode.append_child(meta.type->name);
propertyNode.append_attribute("name").set_value(name); propertyNode.append_attribute("name").set_value(name);
// Update InstanceRef properties using map above // Update std::shared_ptr<Instance> properties using map above
if (meta.type == &Data::InstanceRef::TYPE) { if (meta.type == &Data::InstanceRef::TYPE) {
std::weak_ptr<Instance> refWeak = GetPropertyValue(name).expect("Declared property is missing").get<Data::InstanceRef>(); std::weak_ptr<Instance> refWeak = GetPropertyValue(name).expect("Declared property is missing").get<Data::InstanceRef>();
if (refWeak.expired()) continue; if (refWeak.expired()) continue;
@ -306,18 +306,18 @@ void Instance::Serialize(pugi::xml_node parent, RefStateSerialize state) {
state->refsAwaitingRemap[shared_from_this()].clear(); state->refsAwaitingRemap[shared_from_this()].clear();
// Add children // Add children
for (InstanceRef child : this->children) { for (std::shared_ptr<Instance> child : this->children) {
child->Serialize(node, state); child->Serialize(node, state);
} }
} }
result<InstanceRef, NoSuchInstance> Instance::Deserialize(pugi::xml_node node, RefStateDeserialize state) { result<std::shared_ptr<Instance>, NoSuchInstance> Instance::Deserialize(pugi::xml_node node, RefStateDeserialize state) {
std::string className = node.attribute("class").value(); std::string className = node.attribute("class").value();
if (INSTANCE_MAP.count(className) == 0) { if (INSTANCE_MAP.count(className) == 0) {
return NoSuchInstance(className); return NoSuchInstance(className);
} }
// This will error if an abstract instance is used in the file. Oh well, not my prob rn. // This will error if an abstract instance is used in the file. Oh well, not my prob rn.
InstanceRef object = INSTANCE_MAP[className]->constructor(); std::shared_ptr<Instance> object = INSTANCE_MAP[className]->constructor();
object->GetChildren(); object->GetChildren();
// const InstanceType* type = INSTANCE_MAP.at(className); // const InstanceType* type = INSTANCE_MAP.at(className);
@ -332,7 +332,7 @@ result<InstanceRef, NoSuchInstance> Instance::Deserialize(pugi::xml_node node, R
continue; continue;
} }
// Update InstanceRef properties using map above // Update std::shared_ptr<Instance> properties using map above
if (meta_.expect().type == &Data::InstanceRef::TYPE) { if (meta_.expect().type == &Data::InstanceRef::TYPE) {
if (propertyNode.text().empty()) if (propertyNode.text().empty())
continue; continue;
@ -369,7 +369,7 @@ result<InstanceRef, NoSuchInstance> Instance::Deserialize(pugi::xml_node node, R
// Read children // Read children
for (pugi::xml_node childNode : node.children("Item")) { for (pugi::xml_node childNode : node.children("Item")) {
result<InstanceRef, NoSuchInstance> child = Instance::Deserialize(childNode, state); result<std::shared_ptr<Instance>, NoSuchInstance> child = Instance::Deserialize(childNode, state);
if (child.isError()) { if (child.isError()) {
std::get<NoSuchInstance>(child.error().value()).logMessage(); std::get<NoSuchInstance>(child.error().value()).logMessage();
continue; continue;
@ -434,7 +434,7 @@ std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
if (meta.flags & (PROP_READONLY | PROP_NOSAVE)) continue; if (meta.flags & (PROP_READONLY | PROP_NOSAVE)) continue;
// Update InstanceRef properties using map above // Update std::shared_ptr<Instance> properties using map above
if (meta.type == &Data::InstanceRef::TYPE) { if (meta.type == &Data::InstanceRef::TYPE) {
std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<Data::InstanceRef>(); std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<Data::InstanceRef>();
if (refWeak.expired()) continue; if (refWeak.expired()) continue;

View file

@ -138,9 +138,6 @@ public:
std::optional<std::shared_ptr<Instance>> Clone(RefStateClone state = std::make_shared<__RefStateClone>()); std::optional<std::shared_ptr<Instance>> Clone(RefStateClone state = std::make_shared<__RefStateClone>());
}; };
typedef std::shared_ptr<Instance> InstanceRef;
typedef std::weak_ptr<Instance> InstanceRefWeak;
// https://gist.github.com/jeetsukumaran/307264 // https://gist.github.com/jeetsukumaran/307264
class DescendantsIterator { class DescendantsIterator {
public: public:

View file

@ -49,7 +49,7 @@ void DataModel::SaveToFile(std::optional<std::string> path) {
pugi::xml_document doc; pugi::xml_document doc;
pugi::xml_node root = doc.append_child("openblocks"); pugi::xml_node root = doc.append_child("openblocks");
for (InstanceRef child : this->GetChildren()) { for (std::shared_ptr<Instance> child : this->GetChildren()) {
child->Serialize(root); child->Serialize(root);
} }
@ -59,50 +59,6 @@ void DataModel::SaveToFile(std::optional<std::string> path) {
Logger::info("Place saved successfully"); Logger::info("Place saved successfully");
} }
// void DataModel::DeserializeService(pugi::xml_node node, RefStateDeserialize state) {
// std::string className = node.attribute("class").value();
// if (INSTANCE_MAP.count(className) == 0) {
// Logger::fatalErrorf("Unknown service: '%s'", className.c_str());
// return;
// }
// if (services.count(className) != 0) {
// Logger::fatalErrorf("Service %s defined multiple times in file", className.c_str());
// return;
// }
// // This will error if an abstract instance is used in the file. Oh well, not my prob rn.
// InstanceRef object = INSTANCE_MAP[className]->constructor();
// AddChild(object);
// // Read properties
// pugi::xml_node propertiesNode = node.child("Properties");
// for (pugi::xml_node propertyNode : propertiesNode) {
// std::string propertyName = propertyNode.attribute("name").value();
// auto meta_ = object->GetPropertyMeta(propertyName);
// if (!meta_) {
// Logger::fatalErrorf("Attempt to set unknown property '%s' of %s", propertyName.c_str(), object->GetClass()->className.c_str());
// continue;
// }
// Data::Variant value = Data::Variant::Deserialize(propertyNode, state);
// object->SetPropertyValue(propertyName, value).expect();
// }
// // Add children
// for (pugi::xml_node childNode : node.children("Item")) {
// result<InstanceRef, NoSuchInstance> child = Instance::Deserialize(childNode, state);
// if (child.isError()) {
// std::get<NoSuchInstance>(child.error().value()).logMessage();
// continue;
// }
// object->AddChild(child.expect());
// }
// // We add the service to the list
// // All services get init'd at once in InitServices
// this->services[className] = std::dynamic_pointer_cast<Service>(object);
// }
std::shared_ptr<DataModel> DataModel::LoadFromFile(std::string path) { std::shared_ptr<DataModel> DataModel::LoadFromFile(std::string path) {
std::ifstream inStream(path); std::ifstream inStream(path);
pugi::xml_document doc; pugi::xml_document doc;
@ -174,7 +130,7 @@ std::shared_ptr<DataModel> DataModel::CloneModel() {
if (meta.flags & (PROP_READONLY | PROP_NOSAVE)) continue; if (meta.flags & (PROP_READONLY | PROP_NOSAVE)) continue;
// Update InstanceRef properties using map above // Update std::shared_ptr<Instance> properties using map above
if (meta.type == &Data::InstanceRef::TYPE) { if (meta.type == &Data::InstanceRef::TYPE) {
std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<Data::InstanceRef>(); std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<Data::InstanceRef>();
if (refWeak.expired()) continue; if (refWeak.expired()) continue;

View file

@ -224,7 +224,7 @@ void Part::MakeJoints() {
// TEMPORARY // TEMPORARY
// TODO: Use more efficient algorithm to *actually* find nearby parts) // TODO: Use more efficient algorithm to *actually* find nearby parts)
for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) { for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) {
InstanceRef obj = *it; std::shared_ptr<Instance> obj = *it;
if (obj == shared_from_this()) continue; // Skip ourselves if (obj == shared_from_this()) continue; // Skip ourselves
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly
std::shared_ptr<Part> otherPart = obj->CastTo<Part>().expect(); std::shared_ptr<Part> otherPart = obj->CastTo<Part>().expect();

View file

@ -107,7 +107,7 @@ public:
static inline std::shared_ptr<Part> New() { return std::make_shared<Part>(); }; static inline std::shared_ptr<Part> New() { return std::make_shared<Part>(); };
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); }; static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
static inline InstanceRef Create() { return std::make_shared<Part>(); }; static inline std::shared_ptr<Instance> Create() { return std::make_shared<Part>(); };
inline Vector3 position() { return cframe.Position(); } inline Vector3 position() { return cframe.Position(); }

View file

@ -59,7 +59,7 @@ void Workspace::InitService() {
// Sync all parts // Sync all parts
for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) {
InstanceRef obj = *it; std::shared_ptr<Instance> obj = *it;
if (!obj->IsA<Part>()) continue; if (!obj->IsA<Part>()) continue;
std::shared_ptr<Part> part = obj->CastTo<Part>().expect(); std::shared_ptr<Part> part = obj->CastTo<Part>().expect();
this->SyncPartPhysics(part); this->SyncPartPhysics(part);
@ -68,7 +68,7 @@ void Workspace::InitService() {
// Activate all joints // Activate all joints
for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) {
InstanceRef obj = *it; std::shared_ptr<Instance> obj = *it;
if (!obj->IsA<JointInstance>()) continue; if (!obj->IsA<JointInstance>()) continue;
std::shared_ptr<JointInstance> joint = obj->CastTo<JointInstance>().expect(); std::shared_ptr<JointInstance> joint = obj->CastTo<JointInstance>().expect();
joint->UpdateProperty("Part0"); joint->UpdateProperty("Part0");
@ -130,7 +130,7 @@ void Workspace::PhysicsStep(float deltaTime) {
// Naive implementation. Parts are only considered so if they are just under Workspace // Naive implementation. Parts are only considered so if they are just under Workspace
// TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance // TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance
for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) {
InstanceRef obj = *it; std::shared_ptr<Instance> obj = *it;
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(obj); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(obj);
const rp::Transform& transform = part->rigidBody->getTransform(); const rp::Transform& transform = part->rigidBody->getTransform();

View file

@ -133,7 +133,7 @@ void renderParts() {
// Sort by nearest // Sort by nearest
std::map<float, std::shared_ptr<Part>> sorted; std::map<float, std::shared_ptr<Part>> sorted;
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
InstanceRef inst = *it; std::shared_ptr<Instance> inst = *it;
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
if (part->transparency > 0.00001) { if (part->transparency > 0.00001) {
@ -227,7 +227,7 @@ void renderSurfaceExtras() {
ghostShader->set("viewPos", camera.cameraPos); ghostShader->set("viewPos", camera.cameraPos);
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
InstanceRef inst = *it; std::shared_ptr<Instance> inst = *it;
if (!inst->IsA("Part")) continue; if (!inst->IsA("Part")) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
@ -367,7 +367,7 @@ void renderAABB() {
ghostShader->set("color", glm::vec3(1.f, 0.f, 0.f)); ghostShader->set("color", glm::vec3(1.f, 0.f, 0.f));
// Sort by nearest // Sort by nearest
for (InstanceRef inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
glm::mat4 model = CFrame::IDENTITY + part->cframe.Position(); glm::mat4 model = CFrame::IDENTITY + part->cframe.Position();
@ -407,7 +407,7 @@ void renderWireframe() {
wireframeShader->set("color", glm::vec3(1.f, 0.f, 0.f)); wireframeShader->set("color", glm::vec3(1.f, 0.f, 0.f));
// Sort by nearest // Sort by nearest
for (InstanceRef inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
glm::mat4 model = part->cframe; glm::mat4 model = part->cframe;
@ -451,7 +451,7 @@ void renderOutlines() {
int count = 0; int count = 0;
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
InstanceRef inst = *it; std::shared_ptr<Instance> inst = *it;
if (inst->GetClass() != &Part::TYPE) continue; if (inst->GetClass() != &Part::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
if (!part->selected) continue; if (!part->selected) continue;

View file

@ -94,13 +94,13 @@ MainWindow::MainWindow(QWidget *parent)
}); });
addSelectionListener([&](auto oldSelection, auto newSelection, bool __) { addSelectionListener([&](auto oldSelection, auto newSelection, bool __) {
for (InstanceRefWeak inst : oldSelection) { for (std::weak_ptr<Instance> inst : oldSelection) {
if (inst.expired() || inst.lock()->GetClass() != &Part::TYPE) continue; if (inst.expired() || inst.lock()->GetClass() != &Part::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst.lock()); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst.lock());
part->selected = false; part->selected = false;
} }
for (InstanceRefWeak inst : newSelection) { for (std::weak_ptr<Instance> inst : newSelection) {
if (inst.expired() || inst.lock()->GetClass() != &Part::TYPE) continue; if (inst.expired() || inst.lock()->GetClass() != &Part::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst.lock()); std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst.lock());
part->selected = true; part->selected = true;
@ -291,7 +291,7 @@ void MainWindow::connectActionHandlers() {
}); });
connect(ui->actionDelete, &QAction::triggered, this, [&]() { connect(ui->actionDelete, &QAction::triggered, this, [&]() {
for (InstanceRefWeak inst : getSelection()) { for (std::weak_ptr<Instance> inst : getSelection()) {
if (inst.expired()) continue; if (inst.expired()) continue;
inst.lock()->SetParent(std::nullopt); inst.lock()->SetParent(std::nullopt);
} }
@ -300,7 +300,7 @@ void MainWindow::connectActionHandlers() {
connect(ui->actionCopy, &QAction::triggered, this, [&]() { connect(ui->actionCopy, &QAction::triggered, this, [&]() {
pugi::xml_document rootDoc; pugi::xml_document rootDoc;
for (InstanceRefWeak inst : getSelection()) { for (std::weak_ptr<Instance> inst : getSelection()) {
if (inst.expired()) continue; if (inst.expired()) continue;
inst.lock()->Serialize(rootDoc); inst.lock()->Serialize(rootDoc);
} }
@ -314,7 +314,7 @@ void MainWindow::connectActionHandlers() {
}); });
connect(ui->actionCut, &QAction::triggered, this, [&]() { connect(ui->actionCut, &QAction::triggered, this, [&]() {
pugi::xml_document rootDoc; pugi::xml_document rootDoc;
for (InstanceRefWeak inst : getSelection()) { for (std::weak_ptr<Instance> inst : getSelection()) {
if (inst.expired()) continue; if (inst.expired()) continue;
inst.lock()->Serialize(rootDoc); inst.lock()->Serialize(rootDoc);
inst.lock()->SetParent(std::nullopt); inst.lock()->SetParent(std::nullopt);
@ -338,7 +338,7 @@ void MainWindow::connectActionHandlers() {
rootDoc.load_string(encoded.c_str()); rootDoc.load_string(encoded.c_str());
for (pugi::xml_node instNode : rootDoc.children()) { for (pugi::xml_node instNode : rootDoc.children()) {
result<InstanceRef, NoSuchInstance> inst = Instance::Deserialize(instNode); result<std::shared_ptr<Instance>, NoSuchInstance> inst = Instance::Deserialize(instNode);
if (!inst) { inst.logError(); continue; } if (!inst) { inst.logError(); continue; }
gWorkspace()->AddChild(inst.expect()); gWorkspace()->AddChild(inst.expect());
} }
@ -347,7 +347,7 @@ void MainWindow::connectActionHandlers() {
connect(ui->actionPasteInto, &QAction::triggered, this, [&]() { connect(ui->actionPasteInto, &QAction::triggered, this, [&]() {
if (getSelection().size() != 1) return; if (getSelection().size() != 1) return;
InstanceRef selectedParent = getSelection()[0]; std::shared_ptr<Instance> 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;
@ -358,7 +358,7 @@ void MainWindow::connectActionHandlers() {
rootDoc.load_string(encoded.c_str()); rootDoc.load_string(encoded.c_str());
for (pugi::xml_node instNode : rootDoc.children()) { for (pugi::xml_node instNode : rootDoc.children()) {
result<InstanceRef, NoSuchInstance> inst = Instance::Deserialize(instNode); result<std::shared_ptr<Instance>, NoSuchInstance> inst = Instance::Deserialize(instNode);
if (!inst) { inst.logError(); continue; } if (!inst) { inst.logError(); continue; }
selectedParent->AddChild(inst.expect()); selectedParent->AddChild(inst.expect());
} }
@ -373,7 +373,7 @@ void MainWindow::connectActionHandlers() {
pugi::xml_document modelDoc; pugi::xml_document modelDoc;
pugi::xml_node modelRoot = modelDoc.append_child("openblocks"); pugi::xml_node modelRoot = modelDoc.append_child("openblocks");
for (InstanceRefWeak inst : getSelection()) { for (std::weak_ptr<Instance> inst : getSelection()) {
if (inst.expired()) continue; if (inst.expired()) continue;
inst.lock()->Serialize(modelRoot); inst.lock()->Serialize(modelRoot);
} }
@ -383,7 +383,7 @@ void MainWindow::connectActionHandlers() {
connect(ui->actionInsertModel, &QAction::triggered, this, [&]() { connect(ui->actionInsertModel, &QAction::triggered, this, [&]() {
if (getSelection().size() != 1) return; if (getSelection().size() != 1) return;
InstanceRef selectedParent = getSelection()[0]; std::shared_ptr<Instance> 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;
@ -393,7 +393,7 @@ void MainWindow::connectActionHandlers() {
modelDoc.load(inStream); modelDoc.load(inStream);
for (pugi::xml_node instNode : modelDoc.child("openblocks").children("Item")) { for (pugi::xml_node instNode : modelDoc.child("openblocks").children("Item")) {
result<InstanceRef, NoSuchInstance> inst = Instance::Deserialize(instNode); result<std::shared_ptr<Instance>, NoSuchInstance> inst = Instance::Deserialize(instNode);
if (!inst) { inst.logError(); continue; } if (!inst) { inst.logError(); continue; }
selectedParent->AddChild(inst.expect()); selectedParent->AddChild(inst.expect());
} }

View file

@ -10,11 +10,11 @@
std::map<std::string, QIcon> instanceIconCache; std::map<std::string, QIcon> instanceIconCache;
ExplorerModel::ExplorerModel(InstanceRef dataRoot, QWidget *parent) ExplorerModel::ExplorerModel(std::shared_ptr<Instance> dataRoot, QWidget *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
, rootItem(dataRoot) { , rootItem(dataRoot) {
// TODO: Don't use lambdas and handlers like that // TODO: Don't use lambdas and handlers like that
hierarchyPreUpdateHandler = [&](InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent) { hierarchyPreUpdateHandler = [&](std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
if (oldParent.has_value()) { if (oldParent.has_value()) {
auto children = oldParent.value()->GetChildren(); auto children = oldParent.value()->GetChildren();
size_t idx = std::find(children.begin(), children.end(), object) - children.begin(); size_t idx = std::find(children.begin(), children.end(), object) - children.begin();
@ -29,7 +29,7 @@ ExplorerModel::ExplorerModel(InstanceRef dataRoot, QWidget *parent)
} }
}; };
hierarchyPostUpdateHandler = [&](InstanceRef object, std::optional<InstanceRef> oldParent, std::optional<InstanceRef> newParent) { hierarchyPostUpdateHandler = [&](std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
if (newParent.has_value()) endInsertRows(); if (newParent.has_value()) endInsertRows();
if (oldParent.has_value()) endRemoveRows(); if (oldParent.has_value()) endRemoveRows();
}; };
@ -50,11 +50,11 @@ QModelIndex ExplorerModel::index(int row, int column, const QModelIndex &parent)
return {}; return {};
} }
QModelIndex ExplorerModel::toIndex(InstanceRef item) { QModelIndex ExplorerModel::toIndex(std::shared_ptr<Instance> item) {
if (item == rootItem || !item->GetParent().has_value()) if (item == rootItem || !item->GetParent().has_value())
return {}; return {};
InstanceRef parentItem = item->GetParent().value(); std::shared_ptr<Instance> parentItem = item->GetParent().value();
// Check above ensures this item is not root, so value() must be valid // Check above ensures this item is not root, so value() must be valid
for (int i = 0; i < parentItem->GetChildren().size(); i++) for (int i = 0; i < parentItem->GetChildren().size(); i++)
if (parentItem->GetChildren()[i] == item) if (parentItem->GetChildren()[i] == item)
@ -62,7 +62,7 @@ QModelIndex ExplorerModel::toIndex(InstanceRef item) {
return QModelIndex{}; return QModelIndex{};
} }
QModelIndex ExplorerModel::ObjectToIndex(InstanceRef item) { QModelIndex ExplorerModel::ObjectToIndex(std::shared_ptr<Instance> item) {
return toIndex(item); return toIndex(item);
} }
@ -72,13 +72,13 @@ QModelIndex ExplorerModel::parent(const QModelIndex &index) const {
Instance* childItem = static_cast<Instance*>(index.internalPointer()); Instance* childItem = static_cast<Instance*>(index.internalPointer());
// NORISK: The parent must exist if the child was obtained from it during this frame // NORISK: The parent must exist if the child was obtained from it during this frame
InstanceRef parentItem = childItem->GetParent().value(); std::shared_ptr<Instance> parentItem = childItem->GetParent().value();
if (parentItem == rootItem) if (parentItem == rootItem)
return {}; return {};
// Check above ensures this item is not root, so value() must be valid // Check above ensures this item is not root, so value() must be valid
InstanceRef parentParent = parentItem->GetParent().value(); std::shared_ptr<Instance> parentParent = parentItem->GetParent().value();
for (int i = 0; i < parentParent->GetChildren().size(); i++) for (int i = 0; i < parentParent->GetChildren().size(); i++)
if (parentParent->GetChildren()[i] == parentItem) if (parentParent->GetChildren()[i] == parentItem)
return createIndex(i, 0, parentItem.get()); return createIndex(i, 0, parentItem.get());
@ -196,13 +196,13 @@ Qt::DropActions ExplorerModel::supportedDropActions() const {
} }
InstanceRef ExplorerModel::fromIndex(const QModelIndex index) const { std::shared_ptr<Instance> ExplorerModel::fromIndex(const QModelIndex index) const {
if (!index.isValid()) return rootItem; if (!index.isValid()) return rootItem;
return static_cast<Instance*>(index.internalPointer())->shared_from_this(); return static_cast<Instance*>(index.internalPointer())->shared_from_this();
} }
struct DragDropSlot { struct DragDropSlot {
std::vector<InstanceRef> instances; std::vector<std::shared_ptr<Instance>> instances;
}; };
bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) {
@ -216,8 +216,8 @@ bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
return true; return true;
} }
InstanceRef parentInst = fromIndex(parent); std::shared_ptr<Instance> parentInst = fromIndex(parent);
for (InstanceRef instance : slot->instances) { for (std::shared_ptr<Instance> instance : slot->instances) {
instance->SetParent(parentInst); instance->SetParent(parentInst);
} }
@ -225,7 +225,7 @@ bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
return true; return true;
} }
void ExplorerModel::updateRoot(InstanceRef newRoot) { void ExplorerModel::updateRoot(std::shared_ptr<Instance> newRoot) {
beginResetModel(); beginResetModel();
rootItem = newRoot; rootItem = newRoot;
endResetModel(); endResetModel();

View file

@ -8,7 +8,7 @@ class ExplorerModel : public QAbstractItemModel {
public: public:
Q_DISABLE_COPY_MOVE(ExplorerModel) Q_DISABLE_COPY_MOVE(ExplorerModel)
explicit ExplorerModel(InstanceRef dataRoot, QWidget *parent = nullptr); explicit ExplorerModel(std::shared_ptr<Instance> dataRoot, QWidget *parent = nullptr);
~ExplorerModel() override; ~ExplorerModel() override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
@ -29,15 +29,15 @@ public:
QStringList mimeTypes() const override; QStringList mimeTypes() const override;
Qt::DropActions supportedDragActions() const override; Qt::DropActions supportedDragActions() const override;
Qt::DropActions supportedDropActions() const override; Qt::DropActions supportedDropActions() const override;
InstanceRef fromIndex(const QModelIndex index) const; std::shared_ptr<Instance> fromIndex(const QModelIndex index) const;
QModelIndex ObjectToIndex(InstanceRef item); QModelIndex ObjectToIndex(std::shared_ptr<Instance> item);
QIcon iconOf(const InstanceType* type) const; QIcon iconOf(const InstanceType* type) const;
void updateRoot(InstanceRef newRoot); void updateRoot(std::shared_ptr<Instance> newRoot);
private: private:
InstanceRef rootItem; std::shared_ptr<Instance> rootItem;
QModelIndex toIndex(InstanceRef item); QModelIndex toIndex(std::shared_ptr<Instance> item);
}; };
// #endif // #endif

View file

@ -53,7 +53,7 @@ ExplorerView::ExplorerView(QWidget* parent):
if (fromExplorer) return; if (fromExplorer) return;
this->clearSelection(); this->clearSelection();
for (InstanceRefWeak inst : newSelection) { for (std::weak_ptr<Instance> inst : newSelection) {
if (inst.expired()) continue; if (inst.expired()) continue;
QModelIndex index = this->model.ObjectToIndex(inst.lock()); QModelIndex index = this->model.ObjectToIndex(inst.lock());
this->selectionModel()->select(index, QItemSelectionModel::SelectionFlag::Select); this->selectionModel()->select(index, QItemSelectionModel::SelectionFlag::Select);
@ -112,6 +112,6 @@ void ExplorerView::buildContextMenu() {
} }
} }
void ExplorerView::updateRoot(InstanceRef newRoot) { void ExplorerView::updateRoot(std::shared_ptr<Instance> newRoot) {
model.updateRoot(newRoot); model.updateRoot(newRoot);
} }

View file

@ -16,7 +16,7 @@ public:
// void dropEvent(QDropEvent*) override; // void dropEvent(QDropEvent*) override;
void buildContextMenu(); void buildContextMenu();
void updateRoot(InstanceRef newRoot); void updateRoot(std::shared_ptr<Instance> newRoot);
private: private:
ExplorerModel model; ExplorerModel model;
QMenu contextMenu; QMenu contextMenu;

View file

@ -38,7 +38,7 @@ public:
if (index.column() == 0) return nullptr; if (index.column() == 0) return nullptr;
if (!index.parent().isValid() || view->currentInstance.expired()) return nullptr; if (!index.parent().isValid() || view->currentInstance.expired()) return nullptr;
InstanceRef inst = view->currentInstance.lock(); std::shared_ptr<Instance> inst = view->currentInstance.lock();
// If the property is deeper than 1 layer, then it is considered composite // If the property is deeper than 1 layer, then it is considered composite
// Handle specially // Handle specially
@ -107,7 +107,7 @@ public:
if (index.column() == 0) return; if (index.column() == 0) return;
if (!index.parent().isValid() || view->currentInstance.expired()) return; if (!index.parent().isValid() || view->currentInstance.expired()) return;
InstanceRef inst = view->currentInstance.lock(); std::shared_ptr<Instance> inst = view->currentInstance.lock();
bool isComposite = index.parent().parent().isValid(); bool isComposite = index.parent().parent().isValid();
std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : ""; std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : "";
@ -159,7 +159,7 @@ public:
if (index.column() == 0) return; if (index.column() == 0) return;
if (!index.parent().isValid() || view->currentInstance.expired()) return; if (!index.parent().isValid() || view->currentInstance.expired()) return;
InstanceRef inst = view->currentInstance.lock(); std::shared_ptr<Instance> inst = view->currentInstance.lock();
bool isComposite = index.parent().parent().isValid(); bool isComposite = index.parent().parent().isValid();
std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : ""; std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : "";
@ -268,11 +268,11 @@ void PropertiesView::drawBranches(QPainter *painter, const QRect &rect, const QM
QTreeWidget::drawBranches(painter, rect, index); QTreeWidget::drawBranches(painter, rect, index);
} }
void PropertiesView::setSelected(std::optional<InstanceRef> instance) { void PropertiesView::setSelected(std::optional<std::shared_ptr<Instance>> instance) {
clear(); clear();
currentInstance = {}; currentInstance = {};
if (!instance) return; if (!instance) return;
InstanceRef inst = instance.value(); std::shared_ptr<Instance> inst = instance.value();
currentInstance = inst; currentInstance = inst;
std::map<PropertyCategory, QTreeWidgetItem*> propertyCategories; std::map<PropertyCategory, QTreeWidgetItem*> propertyCategories;
@ -347,7 +347,7 @@ void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) {
// Necessary because otherwise this will catch setCheckState from onPropertyUpdated // Necessary because otherwise this will catch setCheckState from onPropertyUpdated
if (ignorePropertyUpdates) return; if (ignorePropertyUpdates) return;
if (!item->parent() || (item->parent() && item->parent()->parent()) || currentInstance.expired()) return; if (!item->parent() || (item->parent() && item->parent()->parent()) || currentInstance.expired()) return;
InstanceRef inst = currentInstance.lock(); std::shared_ptr<Instance> inst = currentInstance.lock();
std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString(); std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString();
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect(); PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
@ -384,7 +384,7 @@ void PropertiesView::rebuildCompositeProperty(QTreeWidgetItem *item, const Data:
} }
// static auto lastUpdateTime = std::chrono::steady_clock::now(); // static auto lastUpdateTime = std::chrono::steady_clock::now();
void PropertiesView::onPropertyUpdated(InstanceRef inst, std::string property, Data::Variant newValue) { void PropertiesView::onPropertyUpdated(std::shared_ptr<Instance> inst, std::string property, Data::Variant newValue) {
// if (!currentInstance || currentInstance->expired() || instance != currentInstance->lock()) return; // if (!currentInstance || currentInstance->expired() || instance != currentInstance->lock()) return;
// if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - lastUpdateTime).count() < 1000) return; // if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - lastUpdateTime).count() < 1000) return;
// lastUpdateTime = std::chrono::steady_clock::now(); // lastUpdateTime = std::chrono::steady_clock::now();

View file

@ -12,11 +12,11 @@ class PropertiesView : public QTreeWidget {
Q_DECLARE_PRIVATE(QTreeView) Q_DECLARE_PRIVATE(QTreeView)
bool ignorePropertyUpdates = false; bool ignorePropertyUpdates = false;
InstanceRefWeak currentInstance; std::weak_ptr<Instance> currentInstance;
void propertyChanged(QTreeWidgetItem *item, int column); void propertyChanged(QTreeWidgetItem *item, int column);
void activateProperty(QTreeWidgetItem *item, int column); void activateProperty(QTreeWidgetItem *item, int column);
void rebuildCompositeProperty(QTreeWidgetItem *item, const Data::TypeInfo*, Data::Variant); void rebuildCompositeProperty(QTreeWidgetItem *item, const Data::TypeInfo*, Data::Variant);
void onPropertyUpdated(InstanceRef instance, std::string property, Data::Variant newValue); void onPropertyUpdated(std::shared_ptr<Instance> instance, std::string property, Data::Variant newValue);
friend PropertiesItemDelegate; friend PropertiesItemDelegate;
protected: protected:
@ -26,5 +26,5 @@ public:
PropertiesView(QWidget* parent = nullptr); PropertiesView(QWidget* parent = nullptr);
~PropertiesView() override; ~PropertiesView() override;
void setSelected(std::optional<InstanceRef> instance); void setSelected(std::optional<std::shared_ptr<Instance>> instance);
}; };