Enhance DaliGatewayCache: add support for multiple status update callbacks
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -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_;
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user