diff options
-rw-r--r-- | include/libcamera/controls.h | 2 | ||||
-rw-r--r-- | src/libcamera/controls.cpp | 30 |
2 files changed, 32 insertions, 0 deletions
diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 1a5690a5..1c9b37e6 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -363,7 +363,9 @@ public: bool empty() const { return controls_.empty(); } std::size_t size() const { return controls_.size(); } + void clear() { controls_.clear(); } + void merge(const ControlList &source); bool contains(const ControlId &id) const; bool contains(unsigned int id) const; diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index c58ed394..b763148d 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -875,6 +875,36 @@ ControlList::ControlList(const ControlInfoMap &infoMap, ControlValidator *valida */ /** + * \brief Merge the \a source into the ControlList + * \param[in] source The ControlList to merge into this object + * + * Merging two control lists copies elements from the \a source and inserts + * them in *this. If the \a source contains elements whose key is already + * present in *this, then those elements are not overwritten. + * + * Only control lists created from the same ControlIdMap or ControlInfoMap may + * be merged. Attempting to do otherwise results in undefined behaviour. + * + * \todo Reimplement or implement an overloaded version which internally uses + * std::unordered_map::merge() and accepts a non-const argument. + */ +void ControlList::merge(const ControlList &source) +{ + ASSERT(idmap_ == source.idmap_); + + for (const auto &ctrl : source) { + if (contains(ctrl.first)) { + const ControlId *id = idmap_->at(ctrl.first); + LOG(Controls, Warning) + << "Control " << id->name() << " not overwritten"; + continue; + } + + set(ctrl.first, ctrl.second); + } +} + +/** * \brief Check if the list contains a control with the specified \a id * \param[in] id The control ID * |