+
+bool SMUX::UpdateTables()
+{
+Sensors newSensors;
+bool done = true;
+auto it = tables.begin();
+while (it != tables.end())
+ {
+ try
+ {
+ it->second->UpdateSensors(newSensors);
+ }
+ catch (const std::runtime_error & ex)
+ {
+ printfd(__FILE__,
+ "SMUX::UpdateTables - failed to update table '%s': '%s'\n",
+ it->first.c_str(), ex.what());
+ done = false;
+ break;
+ }
+ ++it;
+ }
+if (!done)
+ {
+ auto sit = newSensors.begin();
+ while (sit != newSensors.end())
+ {
+ delete sit->second;
+ ++sit;
+ }
+ return false;
+ }
+
+it = tables.begin();
+while (it != tables.end())
+ {
+ auto res = std::equal_range(sensors.begin(),
+ sensors.end(),
+ std::pair<OID, Sensor *>(OID(it->first), nullptr),
+ SPrefixLess);
+ auto sit = res.first;
+ while (sit != res.second)
+ {
+ delete sit->second;
+ ++sit;
+ }
+ sensors.erase(res.first, res.second);
+ ++it;
+ }
+
+sensors.insert(newSensors.begin(), newSensors.end());
+
+return true;
+}
+
+void SMUX::SetNotifier(UserPtr userPtr)
+{
+ m_conns.emplace_back(
+ userPtr->GetID(),
+ userPtr->GetProperties().tariffName.afterChange([this](const auto&, const auto&){ UpdateTables(); })
+ );
+}
+
+void SMUX::UnsetNotifier(UserPtr userPtr)
+{
+ m_conns.erase(std::remove_if(m_conns.begin(), m_conns.end(),
+ [userPtr](const auto& c){ return std::get<0>(c) == userPtr->GetID(); }),
+ m_conns.end());
+}
+
+void SMUX::SetNotifiers()
+{
+int h = users->OpenSearch();
+assert(h && "USERS::OpenSearch is always correct");
+
+UserPtr u;
+while (users->SearchNext(h, &u) == 0)
+ SetNotifier(u);
+
+users->CloseSearch(h);
+
+m_onAddUserConn = users->onAdd([this](auto user){
+ SetNotifier(user);
+ UpdateTables();
+});
+m_onDelUserConn = users->onDel([this](auto user){
+ UnsetNotifier(user);
+ UpdateTables();
+});
+
+auto updateTables = [this](const TariffData&){ UpdateTables(); };
+m_onAddTariffConn = tariffs->onAdd(updateTables);
+m_onDelTariffConn = tariffs->onDel(updateTables);
+}
+
+void SMUX::ResetNotifiers()
+{
+m_onAddTariffConn.disconnect();
+m_onDelTariffConn.disconnect();
+
+m_onAddUserConn.disconnect();
+m_onDelUserConn.disconnect();
+
+m_conns.clear();
+}