diff --git a/ZEDLiveLink/Source/ZEDLiveLink/Private/ZEDLiveLinkSource.cpp b/ZEDLiveLink/Source/ZEDLiveLink/Private/ZEDLiveLinkSource.cpp index 1016047..7d7d61f 100644 --- a/ZEDLiveLink/Source/ZEDLiveLink/Private/ZEDLiveLinkSource.cpp +++ b/ZEDLiveLink/Source/ZEDLiveLink/Private/ZEDLiveLinkSource.cpp @@ -26,7 +26,7 @@ FZEDLiveLinkSource::FZEDLiveLinkSource(const FZEDLiveLinkSettings& InSettings) : Socket(nullptr) -, Stopping(false) +, bIsRunning(false) , Thread(nullptr) , WaitTime(FTimespan::FromMilliseconds(500)) { @@ -101,7 +101,7 @@ void FZEDLiveLinkSource::ReceiveClient(ILiveLinkClient* InClient, FGuid InSource bool FZEDLiveLinkSource::IsSourceStillValid() const { // Source is valid if we have a valid thread and socket - bool bIsSourceValid = !Stopping && Thread != nullptr && Socket != nullptr; + bool bIsSourceValid = bIsRunning && Thread != nullptr && Socket != nullptr; return bIsSourceValid; } @@ -117,6 +117,8 @@ bool FZEDLiveLinkSource::RequestSourceShutdown() void FZEDLiveLinkSource::Start() { + bIsRunning = true; + ThreadName = "ZED UDP Receiver "; ThreadName.AppendInt(FAsyncThreadIndex::GetNext()); @@ -125,13 +127,13 @@ void FZEDLiveLinkSource::Start() void FZEDLiveLinkSource::Stop() { - Stopping = true; + bIsRunning = false; } uint32 FZEDLiveLinkSource::Run() { TSharedRef Sender = SocketSubsystem->CreateInternetAddr(); - while (!Stopping) + while (bIsRunning) { if (Socket->Wait(ESocketWaitConditions::WaitForRead, WaitTime)) { @@ -148,7 +150,7 @@ uint32 FZEDLiveLinkSource::Run() { if (Read > 0) { - TSharedPtr> ReceivedData = MakeShareable(new TArray()); + TSharedPtr, ESPMode::ThreadSafe> ReceivedData = MakeShareable(new TArray()); ReceivedData->SetNumUninitialized(Read); memcpy(ReceivedData->GetData(), RecvBuffer.GetData(), Read); AsyncTask(ENamedThreads::GameThread, [this, ReceivedData]() { ProcessReceivedData(ReceivedData); }); @@ -185,7 +187,7 @@ void FZEDLiveLinkSource::ProcessReceivedData(TSharedPtr> ReceivedD FLiveLinkFrameDataStruct FrameData; FLiveLinkSubjectKey Key = FLiveLinkSubjectKey(SourceGuid, SubjectName); - if (Client) + if (Client && bIsRunning) { if (frameData.bIsValid) { @@ -200,27 +202,36 @@ void FZEDLiveLinkSource::ProcessReceivedData(TSharedPtr> ReceivedD } else { - if (!Subjects.Contains(SubjectName) && !Client->GetSubjects(true, false).Contains(Key)) + TArray SubjectsKey; + FScopeLock Lock(&SubjectsCriticalSection); { - FLiveLinkSubjectPreset Preset; - Preset.Key = Key; - Preset.Role = frameData.SubjectRole; - //Preset.bEnabled = true; + SubjectsKey = Client->GetSubjects(true, false); + } - if (Client->GetSources().Num() > 0) + if (!SubjectsKey.Contains(Key)) + { + if (!Subjects.Contains(SubjectName)) { - Client->CreateSubject(Preset); - Client->SetSubjectEnabled(Key, true); + FLiveLinkSubjectPreset Preset; + Preset.Key = Key; + Preset.Role = frameData.SubjectRole; + //Preset.bEnabled = true; - Subjects.Push(SubjectName); - - if (frameData.SubjectRole == ULiveLinkCameraRole::StaticClass()) - { - UpdateCameraStaticData(SubjectName, frameData.CameraTransform); - } - else if (frameData.SubjectRole == ULiveLinkAnimationRole::StaticClass()) + if (Client->GetSources().Num() > 0) { - UpdateAnimationStaticData(SubjectName, frameData.ParentsIdx, frameData.TargetBones); + Client->CreateSubject(Preset); + Client->SetSubjectEnabled(Key, true); + + Subjects.Push(SubjectName); + + if (frameData.SubjectRole == ULiveLinkCameraRole::StaticClass()) + { + UpdateCameraStaticData(SubjectName, frameData.CameraTransform); + } + else if (frameData.SubjectRole == ULiveLinkAnimationRole::StaticClass()) + { + UpdateAnimationStaticData(SubjectName, frameData.ParentsIdx, frameData.TargetBones); + } } } } diff --git a/ZEDLiveLink/Source/ZEDLiveLink/Public/ZEDLiveLinkSource.h b/ZEDLiveLink/Source/ZEDLiveLink/Public/ZEDLiveLinkSource.h index ba32173..cb51da8 100644 --- a/ZEDLiveLink/Source/ZEDLiveLink/Public/ZEDLiveLinkSource.h +++ b/ZEDLiveLink/Source/ZEDLiveLink/Public/ZEDLiveLinkSource.h @@ -70,7 +70,7 @@ class ZEDLIVELINK_API FZEDLiveLinkSource : public ILiveLinkSource, public FRunna ISocketSubsystem* SocketSubsystem; // Threadsafe Bool for terminating the main thread loop - FThreadSafeBool Stopping; + FThreadSafeBool bIsRunning; // Thread to run socket operations on FRunnableThread* Thread; @@ -87,6 +87,7 @@ class ZEDLIVELINK_API FZEDLiveLinkSource : public ILiveLinkSource, public FRunna // Buffer to receive socket data into TArray RecvBuffer; + mutable FCriticalSection SubjectsCriticalSection; bool FirstConnection = true; // Check if static data is setup