#include "variants.hpp" #include #include #include #include #include #include "scavenge.hpp" void Variants::earlyInit(QObject* old) { auto* oldv = qobject_cast(old); if (oldv != nullptr) { this->scavengeableInstances = std::move(oldv->instances); } } QObject* Variants::scavengeTargetFor(QObject* /* child */) { if (this->activeScavengeVariant != nullptr) { auto* r = this->scavengeableInstances.get(*this->activeScavengeVariant); if (r != nullptr) return *r; } return nullptr; } void Variants::setVariants(QVariantList variants) { this->mVariants = std::move(variants); this->updateVariants(); } void Variants::componentComplete() { Scavenger::componentComplete(); this->updateVariants(); } void Variants::updateVariants() { if (this->mComponent == nullptr) { qWarning() << "Variants instance does not have a component specified"; return; } // clean up removed entries for (auto iter = this->instances.values.begin(); iter < this->instances.values.end();) { if (this->mVariants.contains(iter->first)) { iter++; } else { iter->second->deleteLater(); iter = this->instances.values.erase(iter); } } for (auto iter = this->mVariants.begin(); iter < this->mVariants.end(); iter++) { auto& variantObj = *iter; if (!variantObj.canConvert()) { qWarning() << "value passed to Variants is not an object and will be ignored:" << variantObj; } else { auto variant = variantObj.value(); for (auto iter2 = this->mVariants.begin(); iter2 < iter; iter2++) { if (*iter2 == variantObj) { qWarning() << "same value specified twice in Variants, duplicates will be ignored:" << variantObj; goto outer; } } if (this->instances.contains(variant)) { continue; // we dont need to recreate this one } this->activeScavengeVariant = &variant; auto* instance = createComponentScavengeable(*this, *this->mComponent, variant); if (instance == nullptr) { qWarning() << "failed to create variant with object" << variant; continue; } this->instances.insert(variant, instance); } outer:; } } template bool AwfulMap::contains(const K& key) const { return std::ranges::any_of(this->values, [&](const QPair& pair) { return pair.first == key; }); } template V* AwfulMap::get(const K& key) { for (auto& [k, v]: this->values) { if (key == k) { return &v; } } return nullptr; } template void AwfulMap::insert(K key, V value) { this->values.push_back(QPair(key, value)); } template bool AwfulMap::remove(const K& key) { for (auto iter = this->values.begin(); iter < this->values.end(); iter++) { if (iter->first == key) { this->values.erase(iter); return true; } } return false; }