Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple fixes for stability #49

Merged
merged 6 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
###### 3.3.3
* More strict checks for proxy validity in all Async Blueprint nodes.
* Prevent from starting any action from a non game thread.
* Ensure the Run Async And Wait object is still valid after exiting another thread.

###### 3.3.2
* Further fixes to prepare the plugin to be compiled for a marketplace. Tests against UE5.4.

Expand Down
36 changes: 22 additions & 14 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFCustomTimelineBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFCustomTimelineBP* UECFCustomTimelineBP::ECFCustomTimeline(const UObject* WorldContextObject, UCurveFloat* CurveFloat, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFCustomTimelineBP* Proxy = NewObject<UECFCustomTimelineBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::AddCustomTimeline(WorldContextObject, CurveFloat,
[Proxy](float Value, float Time)
{
Proxy->OnTick.Broadcast(Value, Time, false);
},
[Proxy](float Value, float Time, bool bStopped)
{
Proxy->OnFinished.Broadcast(Value, Time, bStopped);
Proxy->ClearAsyncBPAction();
},
Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::AddCustomTimeline(WorldContextObject, CurveFloat,
[Proxy](float Value, float Time)
{
if (IsProxyValid(Proxy))
{
Proxy->OnTick.Broadcast(Value, Time, false);
}
},
[Proxy](float Value, float Time, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnFinished.Broadcast(Value, Time, bStopped);
Proxy->ClearAsyncBPAction();
}
},
Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
19 changes: 12 additions & 7 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFDelayBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFDelayBP* UECFDelayBP::ECFDelay(const UObject* WorldContextObject, float DelayTime, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFDelayBP* Proxy = NewObject<UECFDelayBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::Delay(WorldContextObject, DelayTime, [Proxy](bool bStopped)
if (Proxy)
{
Proxy->OnComplete.Broadcast(bStopped);
Proxy->ClearAsyncBPAction();
}, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::Delay(WorldContextObject, DelayTime, [Proxy](bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnComplete.Broadcast(bStopped);
Proxy->ClearAsyncBPAction();
}
}, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
19 changes: 12 additions & 7 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFDelayTicksBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFDelayTicksBP* UECFDelayTicksBP::ECFDelayTicks(const UObject* WorldContextObject, int32 DelayTicks, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFDelayTicksBP* Proxy = NewObject<UECFDelayTicksBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::DelayTicks(WorldContextObject, DelayTicks, [Proxy](bool bStopped)
if (Proxy)
{
Proxy->OnComplete.Broadcast(bStopped);
Proxy->ClearAsyncBPAction();
}, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::DelayTicks(WorldContextObject, DelayTicks, [Proxy](bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnComplete.Broadcast(bStopped);
Proxy->ClearAsyncBPAction();
}
}, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,35 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFDoNoMoreThanXTimeBP* UECFDoNoMoreThanXTimeBP::ECFDoNoMoreThanXTime(const UObject* WorldContextObject, float Time, FECFHandleBP& Handle, FECFInstanceIdBP& InstanceId, FECFActionSettings Settings, int32 MaxExecsEnqueued /*= 1*/)
{
UECFDoNoMoreThanXTimeBP* Proxy = NewObject<UECFDoNoMoreThanXTimeBP>();
Proxy->Init(WorldContextObject, Settings);

if (InstanceId.InstanceId.IsValid() == false)
if (Proxy)
{
UECFBPLibrary::ECFGetNewInstanceId(InstanceId);
}
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::DoNoMoreThanXTime(WorldContextObject, [Proxy]()
{
// Because the action will be executed on first call, check if the async action has been activated.
// Not activated actions don't have bindings to delegates!
// Enqueue the OnExecute broadcast for the activation.
if (Proxy->bActivated)
if (InstanceId.InstanceId.IsValid() == false)
{
Proxy->OnExecute.Broadcast();
Proxy->ClearAsyncBPAction();
UECFBPLibrary::ECFGetNewInstanceId(InstanceId);
}
else

Proxy->Proxy_Handle = FFlow::DoNoMoreThanXTime(WorldContextObject, [Proxy]()
{
Proxy->bExecuteOnActivation = true;
}
}, Time, MaxExecsEnqueued, InstanceId.InstanceId, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
// Because the action will be executed on first call, check if the async action has been activated.
// Not activated actions don't have bindings to delegates!
// Enqueue the OnExecute broadcast for the activation.
if (IsProxyValid(Proxy))
{
if (Proxy->bActivated)
{
Proxy->OnExecute.Broadcast();
Proxy->ClearAsyncBPAction();
}
else
{
Proxy->bExecuteOnActivation = true;
}
}
}, Time, MaxExecsEnqueued, InstanceId.InstanceId, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
36 changes: 22 additions & 14 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFRunAsyncThenBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFRunAsyncThenBP* UECFRunAsyncThenBP::ECFRunAsyncThen(const UObject* WorldContextObject, float InTimeOut, EECFAsyncPrio Priority, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFRunAsyncThenBP* Proxy = NewObject<UECFRunAsyncThenBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::RunAsyncThen(WorldContextObject,
[Proxy]()
{
Proxy->AsyncTask.Broadcast(false, false);
},
[Proxy](bool bTimedOut, bool bStopped)
{
Proxy->OnExecute.Broadcast(bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
},
InTimeOut, Priority, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::RunAsyncThen(WorldContextObject,
[Proxy]()
{
if (IsProxyValid(Proxy))
{
Proxy->AsyncTask.Broadcast(false, false);
}
},
[Proxy](bool bTimedOut, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnExecute.Broadcast(bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
}
},
InTimeOut, Priority, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
36 changes: 22 additions & 14 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFTickerBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFTickerBP* UECFTickerBP::ECFTicker(const UObject* WorldContextObject, float TickingTime, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFTickerBP* Proxy = NewObject<UECFTickerBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::AddTicker(WorldContextObject, TickingTime,
[Proxy](float DeltaTime)
{
Proxy->OnTick.Broadcast(DeltaTime, false);
},
[Proxy](bool bStopped)
{
Proxy->OnComplete.Broadcast(0.f, bStopped);
Proxy->ClearAsyncBPAction();
},
Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::AddTicker(WorldContextObject, TickingTime,
[Proxy](float DeltaTime)
{
if (IsProxyValid(Proxy))
{
Proxy->OnTick.Broadcast(DeltaTime, false);
}
},
[Proxy](bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnComplete.Broadcast(0.f, bStopped);
Proxy->ClearAsyncBPAction();
}
},
Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
38 changes: 23 additions & 15 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFTimelineBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,29 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFTimelineBP* UECFTimelineBP::ECFTimeline(const UObject* WorldContextObject, float StartValue, float StopValue, float Time, FECFActionSettings Settings, FECFHandleBP& Handle, EECFBlendFunc BlendFunc /*= EECFBlendFunc::ECFBlend_Linear*/, float BlendExp /*= 1.f*/)
{
UECFTimelineBP* Proxy = NewObject<UECFTimelineBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_Handle = FFlow::AddTimeline(WorldContextObject,
StartValue, StopValue, Time,
[Proxy](float Value, float Time)
{
Proxy->OnTick.Broadcast(Value, Time, false);
},
[Proxy](float Value, float Time, bool bStopped)
{
Proxy->OnFinished.Broadcast(Value, Time, false);
Proxy->ClearAsyncBPAction();
},
BlendFunc, BlendExp, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::AddTimeline(WorldContextObject,
StartValue, StopValue, Time,
[Proxy](float Value, float Time)
{
if (IsProxyValid(Proxy))
{
Proxy->OnTick.Broadcast(Value, Time, false);
}
},
[Proxy](float Value, float Time, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnFinished.Broadcast(Value, Time, false);
Proxy->ClearAsyncBPAction();
}
},
BlendFunc, BlendExp, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
42 changes: 25 additions & 17 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFWaitAndExecuteBP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,31 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFWaitAndExecuteBP* UECFWaitAndExecuteBP::ECFWaitAndExecute(const UObject* WorldContextObject, float InTimeOut, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFWaitAndExecuteBP* Proxy = NewObject<UECFWaitAndExecuteBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_HasFinished = false;

Proxy->Proxy_Handle = FFlow::WaitAndExecute(WorldContextObject,
[Proxy](float DeltaTime)
{
Proxy->OnWait.Broadcast(Proxy, DeltaTime, false, false);
return Proxy->Proxy_HasFinished;
},
[Proxy](bool bTimedOut, bool bStopped)
{
Proxy->OnExecute.Broadcast(Proxy, 0.f, bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
},
InTimeOut, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_HasFinished = false;
Proxy->Proxy_Handle = FFlow::WaitAndExecute(WorldContextObject,
[Proxy](float DeltaTime)
{
if (IsProxyValid(Proxy))
{
Proxy->OnWait.Broadcast(Proxy, DeltaTime, false, false);
return Proxy->Proxy_HasFinished;
}
return true;
},
[Proxy](bool bTimedOut, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnExecute.Broadcast(Proxy, 0.f, bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
}
},
InTimeOut, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,38 @@ ECF_PRAGMA_DISABLE_OPTIMIZATION
UECFWhileTrueExecuteBP* UECFWhileTrueExecuteBP::ECFWhileTrueExecute(const UObject* WorldContextObject, float TimeOut, FECFActionSettings Settings, FECFHandleBP& Handle)
{
UECFWhileTrueExecuteBP* Proxy = NewObject<UECFWhileTrueExecuteBP>();
Proxy->Init(WorldContextObject, Settings);

Proxy->Proxy_IsTrue = true;

Proxy->Proxy_Handle = FFlow::WhileTrueExecute(WorldContextObject,
[Proxy]()
{
Proxy->OnWhile.Broadcast(Proxy, 0.f, false, false);
return Proxy->Proxy_IsTrue;
},
[Proxy](float DeltaTime)
{
Proxy->OnExecute.Broadcast(Proxy, DeltaTime, false, false);
},
[Proxy](bool bTimedOut, bool bStopped)
{
Proxy->OnComplete.Broadcast(Proxy, 0.f, bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
},
TimeOut, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_IsTrue = true;
Proxy->Proxy_Handle = FFlow::WhileTrueExecute(WorldContextObject,
[Proxy]()
{
if (IsProxyValid(Proxy))
{
Proxy->OnWhile.Broadcast(Proxy, 0.f, false, false);
return Proxy->Proxy_IsTrue;
}
return false;
},
[Proxy](float DeltaTime)
{
if (IsProxyValid(Proxy))
{
Proxy->OnExecute.Broadcast(Proxy, DeltaTime, false, false);
}
},
[Proxy](bool bTimedOut, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnComplete.Broadcast(Proxy, 0.f, bTimedOut, bStopped);
Proxy->ClearAsyncBPAction();
}
},
TimeOut, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}
Expand Down
Loading