Enhance DaliGatewayCache: add support for multiple status update callbacks

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-08-02 02:11:17 +08:00
parent c5a079e779
commit 491b2ede4f
5 changed files with 41 additions and 6 deletions
+6
View File
@@ -126,6 +126,10 @@ class DaliGatewayCache {
DaliGatewayCachePriorityMode priorityMode() const;
void setPriorityMode(DaliGatewayCachePriorityMode mode);
void setStatusUpdateCallback(StatusUpdateCallback callback);
// Register an additional semantic status observer without replacing the
// protocol bridge callback installed through setStatusUpdateCallback().
// Adapters registered here must outlive the cache.
void addStatusUpdateCallback(StatusUpdateCallback callback);
void setPersistenceCallbacks(DaliGatewayCachePersistenceCallbacks callbacks);
static std::optional<DaliGatewayTarget> decodeTarget(uint8_t rawAddress);
@@ -203,10 +207,12 @@ class DaliGatewayCache {
static std::optional<std::string> encodeAddressState(
const DaliGatewayAddressState& state);
static std::optional<DaliGatewayAddressState> decodeAddressState(std::string_view payload);
StatusUpdateCallback statusUpdateCallbackLocked() const;
mutable std::recursive_mutex mutex_;
DaliGatewayCacheConfig config_;
StatusUpdateCallback statusUpdateCallback_;
std::vector<StatusUpdateCallback> statusUpdateCallbacks_;
DaliGatewayCachePersistenceCallbacks persistence_;
std::map<uint8_t, AddressStates> states_;
std::map<uint8_t, PresenceStates> presence_;
+19
View File
@@ -118,6 +118,25 @@ void DaliGatewayCache::setStatusUpdateCallback(StatusUpdateCallback callback) {
statusUpdateCallback_ = std::move(callback);
}
void DaliGatewayCache::addStatusUpdateCallback(StatusUpdateCallback callback) {
if (!callback) return;
std::lock_guard<std::recursive_mutex> guard(mutex_);
statusUpdateCallbacks_.push_back(std::move(callback));
}
DaliGatewayCache::StatusUpdateCallback DaliGatewayCache::statusUpdateCallbackLocked() const {
std::vector<StatusUpdateCallback> callbacks;
callbacks.reserve(statusUpdateCallbacks_.size() + (statusUpdateCallback_ ? 1U : 0U));
if (statusUpdateCallback_) callbacks.push_back(statusUpdateCallback_);
callbacks.insert(callbacks.end(), statusUpdateCallbacks_.begin(), statusUpdateCallbacks_.end());
if (callbacks.empty()) return {};
return [callbacks = std::move(callbacks)](const DaliGatewayStatusUpdate& update) {
for (const auto& callback : callbacks) {
if (callback) callback(update);
}
};
}
void DaliGatewayCache::setPersistenceCallbacks(
DaliGatewayCachePersistenceCallbacks callbacks) {
std::lock_guard<std::recursive_mutex> guard(mutex_);
+5 -5
View File
@@ -140,7 +140,7 @@ bool DaliGatewayCache::setGroupMask(uint8_t channel, uint8_t shortAddress,
markDirty(channel);
update = statusUpdate(
channel, DaliGatewayTarget{DaliGatewayTargetKind::shortAddress, shortAddress});
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return true;
@@ -162,7 +162,7 @@ bool DaliGatewayCache::setSceneLevel(uint8_t channel, uint8_t shortAddress, uint
markDirty(channel);
update = statusUpdate(
channel, DaliGatewayTarget{DaliGatewayTargetKind::shortAddress, shortAddress});
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return true;
@@ -181,7 +181,7 @@ bool DaliGatewayCache::setSettings(uint8_t channel, uint8_t shortAddress,
markDirty(channel);
update = statusUpdate(
channel, DaliGatewayTarget{DaliGatewayTargetKind::shortAddress, shortAddress});
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return true;
@@ -203,7 +203,7 @@ bool DaliGatewayCache::setActualLevel(uint8_t channel, uint8_t shortAddress,
markDirty(channel);
update = statusUpdate(
channel, DaliGatewayTarget{DaliGatewayTargetKind::shortAddress, shortAddress});
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return true;
@@ -394,7 +394,7 @@ bool DaliGatewayCache::mirrorForwardFrame(uint8_t channel, uint8_t rawAddress,
{
std::lock_guard<std::recursive_mutex> guard(mutex_);
changed = mirrorForwardFrameLocked(channel, rawAddress, command, &update);
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return changed;
+1 -1
View File
@@ -80,7 +80,7 @@ bool DaliGatewayCache::observeForwardFrame(uint8_t channel, uint8_t rawAddress,
flags.needUpdateSettings = flags.needUpdateSettings || mutation.needUpdateSettings;
flagged = true;
}
callback = statusUpdateCallback_;
callback = statusUpdateCallbackLocked();
}
if (callback && update.has_value()) callback(*update);
return flagged;
+10
View File
@@ -30,15 +30,19 @@ int main() {
});
int status_updates = 0;
int observer_updates = 0;
DaliGatewayStatusUpdate last_update;
cache.setStatusUpdateCallback([&](const DaliGatewayStatusUpdate& update) {
++status_updates;
last_update = update;
});
cache.addStatusUpdateCallback(
[&](const DaliGatewayStatusUpdate&) { ++observer_updates; });
assert(cache.setGroupMask(7, 4, 0x0001));
assert(cache.mirrorForwardFrame(7, 0x80, 42));
assert(status_updates == 1);
assert(observer_updates == status_updates);
assert(last_update.channel == 7);
assert(last_update.target.kind == DaliGatewayTargetKind::group);
assert(last_update.target.value == 0);
@@ -47,6 +51,12 @@ int main() {
assert(cache.groupStatus(7, 0).actualLevel == 42);
assert(cache.addressState(7, 4).status.actualLevel == 42);
// Replacing the owning callback must not remove additive adapter observers.
cache.setStatusUpdateCallback({});
assert(cache.setActualLevel(7, 4, 43));
assert(status_updates == 1);
assert(observer_updates == 2);
// The command-state cache tracks DTR-dependent settings and applies a
// broadcast command to every state known by the adapter.
cache.mirrorForwardFrame(7, 0xA3, 12);