184 lines
7.0 KiB
C++
184 lines
7.0 KiB
C++
#include "MetaCoreRuntimeData/MetaCoreRuntimeDataDispatcher.h"
|
|
|
|
#include "MetaCoreScene/MetaCoreComponents.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace MetaCore {
|
|
|
|
MetaCoreRuntimeDataDispatcher::MetaCoreRuntimeDataDispatcher(MetaCoreScene& scene)
|
|
: Scene_(scene) {
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::SetDataPointDefinitions(std::vector<MetaCoreDataPointDefinition> dataPointDefinitions) {
|
|
DataPointDefinitions_ = std::move(dataPointDefinitions);
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::SetBindingDefinitions(std::vector<MetaCoreSceneBindingDefinition> bindingDefinitions) {
|
|
BindingDefinitions_ = std::move(bindingDefinitions);
|
|
RebuildBindingStatuses();
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::ApplyUpdates(const std::vector<MetaCoreRuntimeDataUpdate>& updates) {
|
|
for (const MetaCoreRuntimeDataUpdate& update : updates) {
|
|
const MetaCoreDataPointDefinition* dataPointDefinition = FindDataPointDefinition(update.DataPointId);
|
|
if (dataPointDefinition == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
for (const MetaCoreSceneBindingDefinition& bindingDefinition : BindingDefinitions_) {
|
|
if (bindingDefinition.DataPointId != update.DataPointId) {
|
|
continue;
|
|
}
|
|
|
|
MetaCoreGameObject* gameObject = Scene_.FindGameObject(bindingDefinition.TargetObjectId);
|
|
if (gameObject == nullptr) {
|
|
MarkBindingFault(bindingDefinition.BindingId, "Target object missing");
|
|
continue;
|
|
}
|
|
|
|
bool applied = false;
|
|
switch (bindingDefinition.Target) {
|
|
case MetaCoreRuntimeBindingTarget::TransformPosition:
|
|
if (update.Value.Type == MetaCoreRuntimeValueType::Vec3) {
|
|
gameObject->Transform.Position = update.Value.Vec3Value;
|
|
applied = true;
|
|
}
|
|
break;
|
|
case MetaCoreRuntimeBindingTarget::MeshRendererVisible:
|
|
if (update.Value.Type == MetaCoreRuntimeValueType::Bool && gameObject->MeshRenderer.has_value()) {
|
|
gameObject->MeshRenderer->Visible = update.Value.BoolValue;
|
|
applied = true;
|
|
}
|
|
break;
|
|
case MetaCoreRuntimeBindingTarget::MeshRendererBaseColor:
|
|
if (update.Value.Type == MetaCoreRuntimeValueType::Vec3 && gameObject->MeshRenderer.has_value()) {
|
|
gameObject->MeshRenderer->BaseColor = update.Value.Vec3Value;
|
|
applied = true;
|
|
}
|
|
break;
|
|
case MetaCoreRuntimeBindingTarget::LightIntensity:
|
|
if (update.Value.Type == MetaCoreRuntimeValueType::Double && gameObject->Light.has_value()) {
|
|
gameObject->Light->Intensity = static_cast<float>(update.Value.DoubleValue);
|
|
applied = true;
|
|
}
|
|
break;
|
|
case MetaCoreRuntimeBindingTarget::LightColor:
|
|
if (update.Value.Type == MetaCoreRuntimeValueType::Vec3 && gameObject->Light.has_value()) {
|
|
gameObject->Light->Color = update.Value.Vec3Value;
|
|
applied = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!applied) {
|
|
MarkBindingFault(bindingDefinition.BindingId, "Update type incompatible with binding target");
|
|
continue;
|
|
}
|
|
|
|
MarkBindingHealthy(bindingDefinition.BindingId, update.Value.SourceTimestamp);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::TickStaleness(std::uint64_t currentTimestamp) {
|
|
for (MetaCoreRuntimeBindingStatus& bindingStatus : BindingStatuses_) {
|
|
if (bindingStatus.LastAppliedAt == 0) {
|
|
bindingStatus.Stale = true;
|
|
continue;
|
|
}
|
|
|
|
bindingStatus.Stale =
|
|
currentTimestamp > bindingStatus.LastAppliedAt &&
|
|
(currentTimestamp - bindingStatus.LastAppliedAt) > bindingStatus.StaleAfterMs;
|
|
}
|
|
}
|
|
|
|
const std::vector<MetaCoreRuntimeBindingStatus>& MetaCoreRuntimeDataDispatcher::GetBindingStatuses() const {
|
|
return BindingStatuses_;
|
|
}
|
|
|
|
bool MetaCoreRuntimeDataDispatcher::HasBindingFaults() const {
|
|
return std::any_of(
|
|
BindingStatuses_.begin(),
|
|
BindingStatuses_.end(),
|
|
[](const MetaCoreRuntimeBindingStatus& bindingStatus) {
|
|
return !bindingStatus.Healthy || bindingStatus.Stale;
|
|
}
|
|
);
|
|
}
|
|
|
|
MetaCoreRuntimeDiagnosticsSnapshot MetaCoreRuntimeDataDispatcher::BuildDiagnosticsSnapshot(
|
|
const std::vector<MetaCoreRuntimeDataSourceStatus>& sourceStatuses
|
|
) const {
|
|
MetaCoreRuntimeDiagnosticsSnapshot snapshot;
|
|
snapshot.SourceStatuses = sourceStatuses;
|
|
snapshot.BindingStatuses = BindingStatuses_;
|
|
snapshot.HasFaults = HasBindingFaults();
|
|
snapshot.HasFaults = snapshot.HasFaults || std::any_of(
|
|
snapshot.SourceStatuses.begin(),
|
|
snapshot.SourceStatuses.end(),
|
|
[](const MetaCoreRuntimeDataSourceStatus& sourceStatus) {
|
|
return sourceStatus.State == MetaCoreRuntimeDataSourceState::Degraded ||
|
|
sourceStatus.State == MetaCoreRuntimeDataSourceState::Faulted;
|
|
}
|
|
);
|
|
return snapshot;
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::RebuildBindingStatuses() {
|
|
BindingStatuses_.clear();
|
|
BindingStatusIndexById_.clear();
|
|
BindingStatuses_.reserve(BindingDefinitions_.size());
|
|
|
|
for (const MetaCoreSceneBindingDefinition& bindingDefinition : BindingDefinitions_) {
|
|
BindingStatusIndexById_[bindingDefinition.BindingId] = BindingStatuses_.size();
|
|
BindingStatuses_.push_back(MetaCoreRuntimeBindingStatus{
|
|
bindingDefinition.BindingId,
|
|
true,
|
|
false,
|
|
0,
|
|
1000,
|
|
{}
|
|
});
|
|
}
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::MarkBindingFault(const std::string& bindingId, const std::string& error) {
|
|
const auto iterator = BindingStatusIndexById_.find(bindingId);
|
|
if (iterator == BindingStatusIndexById_.end()) {
|
|
return;
|
|
}
|
|
|
|
MetaCoreRuntimeBindingStatus& status = BindingStatuses_[iterator->second];
|
|
status.Healthy = false;
|
|
status.Stale = false;
|
|
status.LastError = error;
|
|
}
|
|
|
|
void MetaCoreRuntimeDataDispatcher::MarkBindingHealthy(const std::string& bindingId, std::uint64_t appliedAt) {
|
|
const auto iterator = BindingStatusIndexById_.find(bindingId);
|
|
if (iterator == BindingStatusIndexById_.end()) {
|
|
return;
|
|
}
|
|
|
|
MetaCoreRuntimeBindingStatus& status = BindingStatuses_[iterator->second];
|
|
status.Healthy = true;
|
|
status.Stale = false;
|
|
status.LastAppliedAt = appliedAt;
|
|
status.LastError.clear();
|
|
}
|
|
|
|
const MetaCoreDataPointDefinition* MetaCoreRuntimeDataDispatcher::FindDataPointDefinition(const std::string& dataPointId) const {
|
|
const auto iterator = std::find_if(
|
|
DataPointDefinitions_.begin(),
|
|
DataPointDefinitions_.end(),
|
|
[&](const MetaCoreDataPointDefinition& definition) {
|
|
return definition.Id == dataPointId;
|
|
}
|
|
);
|
|
return iterator == DataPointDefinitions_.end() ? nullptr : &(*iterator);
|
|
}
|
|
|
|
} // namespace MetaCore
|