Skip to content
Snippets Groups Projects
Commit 15752a70 authored by Jonathan Ehret's avatar Jonathan Ehret
Browse files

improvements for cluster mode and minor code style changes

parent 7017fabf
No related branches found
No related tags found
No related merge requests found
...@@ -58,16 +58,17 @@ void USFGlobalFadeGameViewportClient::DrawScreenFade(UCanvas* Canvas) ...@@ -58,16 +58,17 @@ void USFGlobalFadeGameViewportClient::DrawScreenFade(UCanvas* Canvas)
{ {
if (bFading) if (bFading)
{ {
float Alpha = 1.0f; float Progress = 1.0f; //goes from 0.0 to 1.0 over a fade
if (FadeDuration > 0.0f) if (FadeDuration > 0.0f)
{ {
Alpha = FadeTimeRemaining() / FadeDuration; Progress = 1.0f - (FadeTimeRemaining() / FadeDuration);
} }
if (Alpha < 1.0f) Progress = FMath::Clamp(Progress, 0.0f, 1.0f);
{
FLinearColor FadeColorTmp = FadeColor; FLinearColor FadeColorTmp = FadeColor;
FadeColorTmp.A = bToBlack ? 1 - Alpha : Alpha; //in case we are
FadeColorTmp.A *= bToBlack ? Progress : 1.0f - Progress;
ASFMasterHUD* MasterHUD = nullptr; ASFMasterHUD* MasterHUD = nullptr;
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
...@@ -90,6 +91,11 @@ void USFGlobalFadeGameViewportClient::DrawScreenFade(UCanvas* Canvas) ...@@ -90,6 +91,11 @@ void USFGlobalFadeGameViewportClient::DrawScreenFade(UCanvas* Canvas)
Canvas->DefaultTexture->GetSizeX(), Canvas->DefaultTexture->GetSizeY()); Canvas->DefaultTexture->GetSizeX(), Canvas->DefaultTexture->GetSizeY());
Canvas->DrawColor = OldColor; Canvas->DrawColor = OldColor;
} }
if (Progress >= 1.0f && !bToBlack) {
ClearFade(); //fading is done
//only "stop fading" when we are fading in, otherwise we stay faded out!
} }
} }
} }
...@@ -226,9 +226,12 @@ void USFGameInstance::PrepareWithStudySetup(ASFStudySetup* Setup) ...@@ -226,9 +226,12 @@ void USFGameInstance::PrepareWithStudySetup(ASFStudySetup* Setup)
int ParticipantSequenceNumber = USFParticipant::GetLastParticipantSequenceNumber(); int ParticipantSequenceNumber = USFParticipant::GetLastParticipantSequenceNumber();
FString LastParticipantID = USFParticipant::GetLastParticipantID(); FString LastParticipantID = USFParticipant::GetLastParticipantID();
bool bRecoverParticipantData = false;
if (USFParticipant::GetLastParticipantFinished()) if (USFParticipant::GetLastParticipantFinished())
{ {
PrepareForStartMode("Last Participant Finished"); ParticipantSequenceNumber++;
PrepareWithStudySetupAllNodes(ParticipantSequenceNumber, FString::FromInt(ParticipantSequenceNumber), false);
} }
else if (FSFUtils::IsPrimary()) else if (FSFUtils::IsPrimary())
{ {
...@@ -248,66 +251,28 @@ void USFGameInstance::PrepareWithStudySetup(ASFStudySetup* Setup) ...@@ -248,66 +251,28 @@ void USFGameInstance::PrepareWithStudySetup(ASFStudySetup* Setup)
int Answer = FSFUtils::OpenCustomDialog(MessageTitle, MessageText, Buttons); int Answer = FSFUtils::OpenCustomDialog(MessageTitle, MessageText, Buttons);
const FString ModeSelection = Buttons[Answer]; const FString ModeSelection = Buttons[Answer];
// Primary Node in cluster mode: Continue preparation by event for synchronization purposes
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
{
IDisplayClusterClusterManager* const Manager = IDisplayCluster::Get().GetClusterMgr();
FDisplayClusterClusterEventJson Event;
TMap<FString, FString> Params;
Params.Add("Selection", ModeSelection);
Event.Type = "SFGameInstanceEvent";
Event.Name = "SelectStudyStartMode";
Event.Parameters = Params;
Manager->EmitClusterEventJson(Event, true);
}
// Not in cluster mode: Directly call prep
else
{
PrepareForStartMode(ModeSelection);
}
}
}
//Continue / Next Participant / Restart Study switch (Answer)
void USFGameInstance::PrepareForStartMode(FString StartMode)
{
int ParticipantSequenceNumber = USFParticipant::GetLastParticipantSequenceNumber();
FString LastParticipantID = USFParticipant::GetLastParticipantID();
TArray<USFCondition*> Conditions;
bool bRecoverParticipantData = false;
if (StartMode == "Last Participant Finished")
{
ParticipantSequenceNumber++;
Conditions = StudySetup->GetAllConditionsForRun(ParticipantSequenceNumber);
}
else if (StartMode == "Restart Study")
{ {
case 2:
FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Restart entire study"); FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Restart entire study");
ParticipantSequenceNumber = 0; ParticipantSequenceNumber = 0;
Conditions = StudySetup->GetAllConditionsForRun(ParticipantSequenceNumber); //clear data (but only on primary to avoid data races)
//clear data
USFParticipant::ClearLogData(); USFParticipant::ClearLogData();
} break;
else if (StartMode == "Continue Participant") case 0:
{
FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Continue last participant"); FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Continue last participant");
Conditions = USFParticipant::GetLastParticipantsConditions();
StartCondition = Conditions[USFParticipant::GetLastParticipantLastConditionStarted()];
bRecoverParticipantData = true; bRecoverParticipantData = true;
} break;
else if (StartMode == "Next Participant") { case 1:
FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Continue with the next participant"); FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Continue with the next participant");
ParticipantSequenceNumber++; ParticipantSequenceNumber++;
Conditions = StudySetup->GetAllConditionsForRun(ParticipantSequenceNumber); break;
} default:
FSFLoggingUtils::Log("[USFGameInstance::PrepareWithStudySetup]: Unknown UnfinishedRunDetectedDialog answer: " + FString::FromInt(Answer), true);
if (StudySetup->bPreloadAllMapsOnStart) break;
{
PreloadAllMaps(Conditions);
} }
// Participant // Participant
FString ParticipantID = ""; FString ParticipantID = "";
if (StudySetup->bUseCustomParticipantIDs) if (StudySetup->bUseCustomParticipantIDs)
...@@ -340,9 +305,57 @@ void USFGameInstance::PrepareForStartMode(FString StartMode) ...@@ -340,9 +305,57 @@ void USFGameInstance::PrepareForStartMode(FString StartMode)
ParticipantID = FString::FromInt(ParticipantSequenceNumber); ParticipantID = FString::FromInt(ParticipantSequenceNumber);
} }
Participant = NewObject<USFParticipant>(this, FName(TEXT("Participant_") + ParticipantID));
Participant->Initialize(ParticipantSequenceNumber, ParticipantID);
if (bRecoverParticipantData) { // Primary Node in cluster mode: Continue preparation by event so it is done on all nodes
if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
{
IDisplayClusterClusterManager* const Manager = IDisplayCluster::Get().GetClusterMgr();
FDisplayClusterClusterEventJson Event;
TMap<FString, FString> Params;
Params.Add("ParticipantSequenceNumber", FString::FromInt(ParticipantSequenceNumber));
Params.Add("ParticipantID", ParticipantID);
Params.Add("bRecoverParticipantData", bRecoverParticipantData ? "true" : "false");
Event.Type = "SFGameInstanceEvent";
Event.Name = "PrepareWithStudySetupAllNodes";
Event.Parameters = Params;
Manager->EmitClusterEventJson(Event, true);
}
// Not in cluster mode: Directly call prep
else
{
PrepareWithStudySetupAllNodes(ParticipantSequenceNumber, ParticipantID, bRecoverParticipantData);
}
}
}
//Continue / Next Participant / Restart Study
void USFGameInstance::PrepareWithStudySetupAllNodes(int NewParticipantSequenceNumber, FString NewParticipantID, bool bRestoreLast)
{
FSFLoggingUtils::Log(FString("[USFGameInstance::PrepareWithStudySetupAllNodes]:") +
" Participant#: " + FString::FromInt(NewParticipantSequenceNumber) +
" ParticipantID: " + NewParticipantID +
" RecoverLast: " + (bRestoreLast ? "true" : "false"));
TArray<USFCondition*> Conditions;
if (bRestoreLast) {
Conditions = USFParticipant::GetLastParticipantsConditions();
StartCondition = Conditions[USFParticipant::GetLastParticipantLastConditionStarted()];
}
else {
Conditions = StudySetup->GetAllConditionsForRun(NewParticipantSequenceNumber);
}
if (StudySetup->bPreloadAllMapsOnStart)
{
PreloadAllMaps(Conditions);
}
Participant = NewObject<USFParticipant>(this, FName(TEXT("Participant_") + NewParticipantID));
Participant->Initialize(NewParticipantSequenceNumber, NewParticipantID);
if (bRestoreLast) {
Participant->LoadLastParticipantsIndependentVariables(); Participant->LoadLastParticipantsIndependentVariables();
} }
else { else {
...@@ -351,10 +364,11 @@ void USFGameInstance::PrepareForStartMode(FString StartMode) ...@@ -351,10 +364,11 @@ void USFGameInstance::PrepareForStartMode(FString StartMode)
} }
Participant->SetStudyConditions(Conditions); Participant->SetStudyConditions(Conditions);
if (bRecoverParticipantData) if (bRestoreLast)
{ {
Participant->RecoverStudyResultsOfFinishedConditions(); Participant->RecoverStudyResultsOfFinishedConditions();
//also delete any data of the condition that is now restarted (StartCondition) if (FSFUtils::IsPrimary()) {
//also delete any data of the condition that is now restarted (StartCondition), only on primary to avoid data races
Participant->DeleteStoredDataForConditionFromLongTable(StartCondition); Participant->DeleteStoredDataForConditionFromLongTable(StartCondition);
for (USFDependentVariable* DV : StartCondition->DependentVariables) for (USFDependentVariable* DV : StartCondition->DependentVariables)
{ {
...@@ -363,6 +377,7 @@ void USFGameInstance::PrepareForStartMode(FString StartMode) ...@@ -363,6 +377,7 @@ void USFGameInstance::PrepareForStartMode(FString StartMode)
Participant->DeleteStoredTrialDataForCondition(StartCondition, MTDV); Participant->DeleteStoredTrialDataForCondition(StartCondition, MTDV);
} }
} }
}
} }
...@@ -531,11 +546,15 @@ void USFGameInstance::GoToConditionSynced(FString ConditionName, bool bForced, E ...@@ -531,11 +546,15 @@ void USFGameInstance::GoToConditionSynced(FString ConditionName, bool bForced, E
} }
} }
void USFGameInstance::HandleClusterEvent(const FDisplayClusterClusterEventJson& Event) { void USFGameInstance::HandleClusterEvent(const FDisplayClusterClusterEventJson& Event) {
if (Event.Type == "SFGameInstanceEvent") { if (Event.Type == "SFGameInstanceEvent") {
if(Event.Name == "SelectStudyStartMode") if (Event.Name == "PrepareWithStudySetupAllNodes")
{ {
PrepareForStartMode(Event.Parameters["Selection"]); int NewParticipantSequenceNumber = FCString::Atoi(*Event.Parameters["ParticipantSequenceNumber"]);
FString NewParticipantID = Event.Parameters["ParticipantID"];
bool bRecoverParticipantData = Event.Parameters["bRecoverParticipantData"] == "true";
PrepareWithStudySetupAllNodes(NewParticipantSequenceNumber, NewParticipantID, bRecoverParticipantData);
} }
//now we actually react on all cluster nodes: //now we actually react on all cluster nodes:
if (Event.Name == "GoToConditionSynced") if (Event.Name == "GoToConditionSynced")
......
...@@ -615,7 +615,7 @@ void USFParticipant::SetIndependentVariablesFromStudySetup(ASFStudySetup* Setup) ...@@ -615,7 +615,7 @@ void USFParticipant::SetIndependentVariablesFromStudySetup(ASFStudySetup* Setup)
IndependentVariablesValues.Empty(); IndependentVariablesValues.Empty();
for (auto Var : Setup->IndependentVariables) { for (auto Var : Setup->IndependentVariables) {
IndependentVariablesValues.Add(DuplicateObject(Var, this), ""); IndependentVariablesValues.Add(DuplicateObject(Var, this), "");
// nodes do nothing, values will be added from cluster event // secondary nodes do nothing, values will be added from cluster event
if (!FSFUtils::IsPrimary()) if (!FSFUtils::IsPrimary())
{ {
continue; continue;
......
...@@ -30,7 +30,9 @@ public: ...@@ -30,7 +30,9 @@ public:
/** Clear fading state */ /** Clear fading state */
virtual void ClearFade(); virtual void ClearFade();
/** Used for Fade to and from black */ /** Used for Fade to and from black
* Call with Duration = 0.0f if you want it e.g. to stay faded out (default starting state)
*/
virtual void Fade(const float Duration, const bool bToBlackN, const FLinearColor FadeColorN = FLinearColor::Black); virtual void Fade(const float Duration, const bool bToBlackN, const FLinearColor FadeColorN = FLinearColor::Black);
/** Get how many seconds are left */ /** Get how many seconds are left */
...@@ -42,8 +44,9 @@ public: ...@@ -42,8 +44,9 @@ public:
private: private:
// Values used by our screen fading // Values used by our screen fading
// these default values result in a faded out start on intialization of a viewport
bool bFading = true; bool bFading = true;
bool bToBlack = true; // Fading to black will be applied even if alpha is 1 bool bToBlack = true;
double FadeStartTime = 0.0; double FadeStartTime = 0.0;
float FadeDuration = 0.0f; float FadeDuration = 0.0f;
FLinearColor FadeColor = FLinearColor::Black; FLinearColor FadeColor = FLinearColor::Black;
......
...@@ -201,7 +201,7 @@ protected: ...@@ -201,7 +201,7 @@ protected:
void InitFadeHandler(FFadeConfig FadeConfig); void InitFadeHandler(FFadeConfig FadeConfig);
void PrepareWithStudySetup(ASFStudySetup* Setup); void PrepareWithStudySetup(ASFStudySetup* Setup);
void PrepareForStartMode(FString StartMode); void PrepareWithStudySetupAllNodes(int NewParticipantSequenceNumber, FString NewParticipantID, bool bRestoreLast);
void PreloadAllMaps(const TArray<USFCondition*>& Conditions); void PreloadAllMaps(const TArray<USFCondition*>& Conditions);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment