summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/controls.h2
-rw-r--r--src/libcamera/controls.cpp30
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
*