Skip to content
Snippets Groups Projects
Select Git revision
  • 78f8c2fb99aba1ba5cb2ae45b4a28d1ae31f5a1a
  • main default protected
  • Version-0.5.4
  • Version-0.5.3
  • Version-0.5.2
  • Version-0.5.1
  • Version-0.3.1
  • Version-0.2.2
  • Version-0.2.1
  • Version-0.2.0
  • Version-0.1.1
  • Version-0.1.0
  • Version0.0.1
13 results

shared.py

Blame
  • UniversalLogging.cpp 6.29 KiB
    #include "UniversalLogging.h"
    
    #include "LogStream.h"
    #include "GameFramework/PlayerController.h"
    #include "GameFramework/HUD.h"
    #if PLATFORM_WINDOWS || PLATFORM_LINUX
    #include "IDisplayCluster.h"
    #include "Cluster/IDisplayClusterClusterManager.h"
    #endif
    #if WITH_EDITOR
    #include "Editor.h"
    #endif
    #include "Misc/CommandLine.h"
    
    LogFileManager UniversalLoggingImpl::Log_File_Manager{};
    
    void UniversalLoggingImpl::StartupModule()
    {
      Streams.Add("", MakeUnique<LogStreamImpl>());
    
      FWorldDelegates::OnPostWorldInitialization.AddRaw(this, &UniversalLoggingImpl::OnWorldStart);
      FWorldDelegates::OnWorldPostActorTick.AddRaw(this, &UniversalLoggingImpl::OnPostActorTick);
      FWorldDelegates::OnWorldCleanup.AddRaw(this, &UniversalLoggingImpl::OnWorldEnd);
    
    #if WITH_EDITOR
      FEditorDelegates::BeginPIE.AddRaw(this, &UniversalLoggingImpl::OnSessionStart);
      FEditorDelegates::EndPIE.AddRaw(this, &UniversalLoggingImpl::OnSessionEnd);
    #endif
    
      Session_ID = "";
    }
    
    void UniversalLoggingImpl::ShutdownModule()
    {
    }
    
    void UniversalLoggingImpl::OnWorldStart(UWorld* World, const UWorld::InitializationValues)
    {
      if (!World->IsGameWorld())
        return;
    
      On_Screen_Log_Actor = dynamic_cast<AOnScreenLog*>(World->SpawnActor(AOnScreenLog::StaticClass()));
    
    	//only set Session_ID on the first world of this session
      if(Session_ID != "")
        return;
    
      if (World->IsPlayInEditor())
        ResetSessionId("PlayInEditor");
      else if (World->IsPlayInPreview())
        ResetSessionId("PlayInPreview");
      else
        ResetSessionId("Play");
    }
    
    void UniversalLoggingImpl::OnWorldEnd(UWorld*, bool bSessionEnded, bool bCleanupResources)
    {
      On_Screen_Log_Actor = nullptr;
    }
    
    void UniversalLoggingImpl::OnSessionStart(const bool)
    {
      Session_ID = "";
    }
    
    void UniversalLoggingImpl::OnSessionEnd(const bool)
    {
      ResetSessionId("Stopped");
    
      for (auto& Elem : Streams)
      {
        Elem.Value->Close();
      }
    
      Streams.Empty();
    }
    
    void UniversalLoggingImpl::OnPostActorTick(UWorld* World, ELevelTick LevelTick, float WhateverThisIsDeltaTimeMaybe)
    {
      const auto PlayerController = World->GetFirstPlayerController();
      if (!PlayerController) 
        return;
      auto HUD = PlayerController->GetHUD();
      if (HUD)
      {
        HUD->AddPostRenderedActor(On_Screen_Log_Actor); // Doing this every tick seems excessive (AddPostRenderActor checks for duplicates, though)
        HUD->bShowOverlays = true; // Yuck, but necessary as otherwise the Actor's PostRenderFor method is not called.  
      }
    }
    
    ILogStream* UniversalLoggingImpl::NewLogStream(const FString StreamName)
    {
      return NewLogStream(StreamName, "Saved/Logs", "UniversalLogging_" + StreamName + ".log");
    }
    
    ILogStream* UniversalLoggingImpl::NewLogStream(const FString StreamName, const FString Filepath, const FString Filename,
                                                   bool bPer_Session /* = false*/, bool bLogOnMaster/* = true*/,
                                                   const bool bLogOnSlaves/* = false*/)
    {
      FString NewFilepath = Filepath;
      FString NewFilename = Filename;
      if(bLogOnSlaves && !IsClusterMaster())
      {
        NewFilepath = Filepath + "/slavelogs";
        NewFilename = GetNodeName() + "_" + Filename;
      }
      Streams.Add(StreamName, MakeUnique<LogStreamImpl>(NewFilepath, NewFilename, bPer_Session, bLogOnMaster, bLogOnSlaves));
      return Streams[StreamName].Get();
    }
    
    void UniversalLoggingImpl::CloseLogStream(const FString StreamName)
    {
      if(Streams.Contains(StreamName))
      {
        Streams[StreamName]->Close();
        Streams.Remove(StreamName);
      }
    }
    
    ILogStream * UniversalLoggingImpl::GetLogStream(const FString StreamName)
    {
      if (Streams.Contains(StreamName))
        return Streams[StreamName].Get();
      else 
        return nullptr;
    }
    
    ILogStream * UniversalLoggingImpl::GetDefaultLogStream()
    {
      return GetLogStream("");
    }
    
    FString UniversalLoggingImpl::GetSessionIdentifier()
    {
      return Session_ID;
    }
    
    void UniversalLoggingImpl::Log(const FString Text, const FString Stream /*= ""*/, const bool bOmit_Newline /*= false*/)
    {
      if (!Streams.Contains(Stream))
        NewLogStream(Stream);
      LogStreamImpl* Stream_OBJ = Streams[Stream].Get();
    
      FString Full_Text = Text;
      if (!bOmit_Newline)
        Full_Text += "\n";
    
      if ((Stream_OBJ->GetLogOnMaster() && IsClusterMaster()) || (Stream_OBJ->GetLogOnSlaves() && !IsClusterMaster()))
      {
        Stream_OBJ->Write(Full_Text);
      }
    
      if(Stream_OBJ->GetOnScreen() && On_Screen_Log_Actor)
      {
        if ((Stream_OBJ->GetLogOnScreenOnMaster() && IsClusterMaster()) || (Stream_OBJ->GetLogOnScreenOnSlaves() && !IsClusterMaster()))
        On_Screen_Log_Actor->EnqueueMessage(Full_Text, Stream_OBJ->GetOnScreenColor(),
                                            Stream_OBJ->GetOnScreenBackgroundColor(), Stream_OBJ->GetOnScreenSize(),
                                            Stream_OBJ->GetOnScreenDuration());
      }
    
      if(Stream_OBJ->GetLogToDefaultLog())
      {
        UE_LOG(LogUni, Log, TEXT("[%s] %s"), *Stream, *Full_Text);
      }
    }
    
    void UniversalLoggingImpl::ResetSessionId(FString Prefix)
    {
      TArray<FString> Tokens;
      TArray<FString> Switches;
      FCommandLine::Parse(FCommandLine::Get(), Tokens, Switches);
      for (auto Token : Tokens)
      {
        if (Token.StartsWith("SessionID"))
        {
          Token.RemoveFromStart("SessionID=");
          Session_ID = Token;
          return;
        }
      }
    
      FString timestamp = FGenericPlatformTime::StrTimestamp();
      timestamp = timestamp.Replace(TEXT("/"), TEXT("-"));
      timestamp = timestamp.Replace(TEXT(" "), TEXT("_"));
      timestamp = timestamp.Replace(TEXT(":"), TEXT("-"));
      Session_ID = FString::Printf(TEXT("%s_%s"), *Prefix, *timestamp);
    }
    
    bool UniversalLoggingImpl::IsClusterMaster()
    {
    #if PLATFORM_WINDOWS || PLATFORM_LINUX
      if (!IDisplayCluster::IsAvailable()) 
      {
         return true;
      }
      IDisplayClusterClusterManager* Manager = IDisplayCluster::Get().GetClusterMgr();
      if (Manager == nullptr)
      {
        return true; // if we are not in cluster mode, we are always the master
      }
      return Manager->IsPrimary() || !Manager->IsSecondary();
    #else
      return true;
    #endif
    }
    
    FString UniversalLoggingImpl::GetNodeName()
    {
    #if PLATFORM_WINDOWS || PLATFORM_LINUX
      if (IDisplayCluster::Get().GetOperationMode() == EDisplayClusterOperationMode::Cluster)
        return IDisplayCluster::Get().GetClusterMgr()->GetNodeId();
      else 
        return FString(TEXT("Localhost"));
    #else
    	return FString(TEXT("Localhost"));
    #endif
    }
    
    LogFileManager* UniversalLoggingImpl::GetLogFileManager()
    {
      return &Log_File_Manager;
    }
    
    IMPLEMENT_MODULE(UniversalLoggingImpl, UniversalLogging)