// Copyright Epic Games, Inc. All Rights Reserved. #include "DatasmithExporterManager.h" #include "CoreMinimal.h" #include "UObject/UObjectBase.h" #include "Async/TaskGraphInterfaces.h" #include "Modules/ModuleManager.h" #if IS_PROGRAM #include "RequiredProgramMainCPPInclude.h" #ifndef UE_BUILD_DEVELOPMENT_WITH_DEBUGGAME #define UE_BUILD_DEVELOPMENT_WITH_DEBUGGAME 0 #endif // Not using IMPLEMENT_APPLICATION here because it overrides new and delete which can cause issues in some host softwares. TCHAR GInternalProjectName[64] = TEXT( "UnrealDatasmithExporter" ); IMPLEMENT_FOREIGN_ENGINE_DIR(); FEngineLoop GEngineLoop; #endif // IS_PROGRAM IMPLEMENT_MODULE(FDefaultModuleImpl, DatasmithExporter) #if IS_PROGRAM // TODO: Integrate Datasmith logging mechanism into FDatasmithExportOutputDevice // Goal: Allow Datasmith users to track and report on errors, warnings or infos generated by the engine class FDatasmithExportOutputDevice : public FOutputDevice { public: FDatasmithExportOutputDevice() { } virtual ~FDatasmithExportOutputDevice() { } virtual void Serialize(const TCHAR* /*V*/, ELogVerbosity::Type /*Verbosity*/, const class FName& /*Category*/) override { } }; bool FDatasmithExporterManager::bEngineInitialized = false; #endif bool FDatasmithExporterManager::Initialize() { #if IS_PROGRAM if (!bEngineInitialized) { bEngineInitialized = GEngineLoop.PreInit( TEXT("-SaveToUserDir -logcmds=\"Global None\"") ) == 0; // Make sure all UObject classes are registered and default properties have been initialized ProcessNewlyLoadedUObjects(); // Tell the module manager it may now process newly-loaded UObjects when new C++ modules are loaded FModuleManager::Get().StartProcessingNewlyLoadedObjects(); if ( GLog ) { // Make sure Logger is set on the right thread GLog->SetCurrentThreadAsMasterThread(); // Clean up existing output devices GLog->TearDown(); // Add Datasmith output device GLog->AddOutputDevice(new FDatasmithExportOutputDevice()); } bEngineInitialized = true; } else if (GGameThreadId != FPlatformTLS::GetCurrentThreadId()) { // Force Game thread to be the current one GGameThreadId = FPlatformTLS::GetCurrentThreadId(); // Set the current thread on the Logger if ( GLog ) { GLog->SetCurrentThreadAsMasterThread(); } // Re-attach task graph to new game thread FTaskGraphInterface::Get().AttachToThread(ENamedThreads::GameThread); } return bEngineInitialized; #else return true; #endif } void FDatasmithExporterManager::Shutdown() { #if IS_PROGRAM if (!bEngineInitialized) { return; } // Some adjustments must be made if shutdown thread differ from the one Initialize has been called from if (GGameThreadId != FPlatformTLS::GetCurrentThreadId()) { // Force Game thread to be the current one GGameThreadId = FPlatformTLS::GetCurrentThreadId(); // Set the current thread on the Logger if ( GLog ) { GLog->SetCurrentThreadAsMasterThread(); } // Re-attach task graph to new game thread FTaskGraphInterface::Get().AttachToThread(ENamedThreads::GameThread); } // Close the logging device if ( GLog ) { GLog->TearDown(); } // Proceed with process exit GEngineLoop.AppPreExit(); GEngineLoop.AppExit(); bEngineInitialized = false; #endif }