Add Async to anim events (false by default) to delay events execution into main thread and prevent multi-threading issues by default

#2033
This commit is contained in:
Wojtek Figat
2023-12-07 15:21:03 +01:00
parent 7db0ae59bb
commit 526edb83de
5 changed files with 103 additions and 37 deletions

View File

@@ -100,48 +100,50 @@ void AnimGraphExecutor::ProcessAnimEvents(AnimGraphNode* node, bool loop, float
if (!k.Value.Instance)
continue;
const float duration = k.Value.Duration > 1 ? k.Value.Duration : 0.0f;
#define ADD_OUTGOING_EVENT(type) context.Data->OutgoingEvents.Add({ k.Value.Instance, (AnimatedModel*)context.Data->Object, anim, eventTime, eventDeltaTime, AnimGraphInstanceData::OutgoingEvent::type })
if (k.Time <= eventTimeMax && eventTimeMin <= k.Time + duration)
{
int32 stateIndex = -1;
if (duration > 1)
{
// Begin for continuous event
for (stateIndex = 0; stateIndex < context.Data->Events.Count(); stateIndex++)
for (stateIndex = 0; stateIndex < context.Data->ActiveEvents.Count(); stateIndex++)
{
const auto& e = context.Data->Events[stateIndex];
const auto& e = context.Data->ActiveEvents[stateIndex];
if (e.Instance == k.Value.Instance && e.Node == node)
break;
}
if (stateIndex == context.Data->Events.Count())
if (stateIndex == context.Data->ActiveEvents.Count())
{
auto& e = context.Data->Events.AddOne();
e.Instance = k.Value.Instance;
ASSERT(k.Value.Instance->Is<AnimContinuousEvent>());
auto& e = context.Data->ActiveEvents.AddOne();
e.Instance = (AnimContinuousEvent*)k.Value.Instance;
e.Anim = anim;
e.Node = node;
ASSERT(k.Value.Instance->Is<AnimContinuousEvent>());
((AnimContinuousEvent*)k.Value.Instance)->OnBegin((AnimatedModel*)context.Data->Object, anim, eventTime, eventDeltaTime);
ADD_OUTGOING_EVENT(OnBegin);
}
}
// Event
k.Value.Instance->OnEvent((AnimatedModel*)context.Data->Object, anim, eventTime, eventDeltaTime);
ADD_OUTGOING_EVENT(OnEvent);
if (stateIndex != -1)
context.Data->Events[stateIndex].Hit = true;
context.Data->ActiveEvents[stateIndex].Hit = true;
}
else if (duration > 1)
{
// End for continuous event
for (int32 i = 0; i < context.Data->Events.Count(); i++)
for (int32 i = 0; i < context.Data->ActiveEvents.Count(); i++)
{
const auto& e = context.Data->Events[i];
const auto& e = context.Data->ActiveEvents[i];
if (e.Instance == k.Value.Instance && e.Node == node)
{
((AnimContinuousEvent*)k.Value.Instance)->OnEnd((AnimatedModel*)context.Data->Object, anim, eventTime, eventDeltaTime);
context.Data->Events.RemoveAt(i);
ADD_OUTGOING_EVENT(OnEnd);
context.Data->ActiveEvents.RemoveAt(i);
break;
}
}
}
#undef ADD_OUTGOING_EVENT
}
}
}