22#include " UObject/UObjectThreadContext.h"
33
44/* * This class is to capture all log output even if the log window is closed */
5- class FJavascriptOutputDevice : public FOutputDevice
5+ class FJavascriptOutputDevice : public FOutputDevice , public FTickableGameObject
66{
77public:
88 UJavascriptOutputDevice* OutputDevice;
@@ -23,20 +23,74 @@ class FJavascriptOutputDevice : public FOutputDevice
2323 GLog->RemoveOutputDevice (this );
2424 }
2525 }
26+
27+ virtual void Tick (float DeltaTime) override
28+ {
29+ SubmitPendingMessages ();
30+ }
31+
32+ virtual TStatId GetStatId () const override
33+ {
34+ RETURN_QUICK_DECLARE_CYCLE_STAT (FJavascriptOutputDevice, STATGROUP_Tickables);
35+ }
2636
2737protected:
38+ struct FLogMessage
39+ {
40+ TSharedRef<FString> Message;
41+ ELogVerbosity::Type Verbosity;
42+ FName Category;
43+
44+ FLogMessage (const TSharedRef<FString>& NewMessage, ELogVerbosity::Type NewVerbosity, FName NewCategory)
45+ : Message(NewMessage)
46+ , Verbosity(NewVerbosity)
47+ , Category(NewCategory)
48+ {
49+ }
50+ };
2851
2952 virtual void Serialize (const TCHAR* V, ELogVerbosity::Type Verbosity, const class FName & Category) override
3053 {
54+ FScopeLock PendingMessagesAccess (&PendingMessagesCriticalSection);
55+ PendingMessages.Add (MakeShared<FLogMessage>(MakeShared<FString>(V), Verbosity, Category));
56+ }
57+
58+ void SubmitPendingMessages ()
59+ {
60+ TArray<TSharedPtr<FLogMessage>> Messages;
61+
62+ if (PendingMessagesCriticalSection.TryLock ())
63+ {
64+ Messages = MoveTemp (PendingMessages);
65+ PendingMessages.Reset ();
66+ PendingMessagesCriticalSection.Unlock ();
67+ }
68+ else
69+ {
70+ return ;
71+ }
72+
73+ for (const auto & Message : Messages)
74+ {
75+ SubmitPendingMessage (Message->Message , Message->Verbosity , Message->Category );
76+ }
77+ }
78+
79+ void SubmitPendingMessage (TSharedPtr<FString> Message, ELogVerbosity::Type Verbosity, const class FName & Category)
80+ {
3181 static bool bIsReentrant = false ;
3282 if (bIsReentrant) return ;
3383
3484 TGuardValue<bool > ReentrantGuard (bIsReentrant, true );
3585 if (!OutputDevice->IsUnreachable () && !FUObjectThreadContext::Get ().IsRoutingPostLoad )
3686 {
37- OutputDevice->OnMessage (V , (ELogVerbosity_JS)Verbosity, Category);
38- }
87+ OutputDevice->OnMessage (*Message , (ELogVerbosity_JS)Verbosity, Category);
88+ }
3989 }
90+
91+ private:
92+ TArray<TSharedPtr<FLogMessage>> PendingMessages;
93+ FCriticalSection PendingMessagesCriticalSection;
4094};
4195
4296UJavascriptOutputDevice::UJavascriptOutputDevice (const FObjectInitializer& ObjectInitializer)
0 commit comments