252 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			252 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// Tencent is pleased to support the open source community by making UnLua available.
							 | 
						||
| 
								 | 
							
								// 
							 | 
						||
| 
								 | 
							
								// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Licensed under the MIT License (the "License"); 
							 | 
						||
| 
								 | 
							
								// you may not use this file except in compliance with the License. You may obtain a copy of the License at
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// http://opensource.org/licenses/MIT
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Unless required by applicable law or agreed to in writing, 
							 | 
						||
| 
								 | 
							
								// software distributed under the License is distributed on an "AS IS" BASIS, 
							 | 
						||
| 
								 | 
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
							 | 
						||
| 
								 | 
							
								// See the License for the specific language governing permissions and limitations under the License.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Compat/UObjectHash.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaEditorStyle.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaEditorCommands.h"
							 | 
						||
| 
								 | 
							
								#include "Misc/CoreDelegates.h"
							 | 
						||
| 
								 | 
							
								#include "Editor.h"
							 | 
						||
| 
								 | 
							
								#include "BlueprintEditorModule.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaIntelliSenseGenerator.h"
							 | 
						||
| 
								 | 
							
								#include "UnLua.h"
							 | 
						||
| 
								 | 
							
								#include "ISettingsModule.h"
							 | 
						||
| 
								 | 
							
								#include "ISettingsSection.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaEditorSettings.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaEditorFunctionLibrary.h"
							 | 
						||
| 
								 | 
							
								#include "UnLuaFunctionLibrary.h"
							 | 
						||
| 
								 | 
							
								#include "Kismet2/DebuggerCommands.h"
							 | 
						||
| 
								 | 
							
								#include "Interfaces/IMainFrameModule.h"
							 | 
						||
| 
								 | 
							
								#include "Interfaces/IPluginManager.h"
							 | 
						||
| 
								 | 
							
								#include "Settings/ProjectPackagingSettings.h"
							 | 
						||
| 
								 | 
							
								#include "Toolbars/AnimationBlueprintToolbar.h"
							 | 
						||
| 
								 | 
							
								#include "Toolbars/BlueprintToolbar.h"
							 | 
						||
| 
								 | 
							
								#include "Toolbars/MainMenuToolbar.h"
							 | 
						||
| 
								 | 
							
								#if ENGINE_MAJOR_VERSION > 4
							 | 
						||
| 
								 | 
							
								#include "UObject/ObjectSaveContext.h"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LOCTEXT_NAMESPACE "FUnLuaEditorModule"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class FUnLuaEditorModule : public IModuleInterface
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    FUnLuaEditorModule()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void StartupModule() override
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        Style = FUnLuaEditorStyle::GetInstance();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        FUnLuaEditorCommands::Register();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        FCoreDelegates::OnPostEngineInit.AddRaw(this, &FUnLuaEditorModule::OnPostEngineInit);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        MainMenuToolbar = MakeShareable(new FMainMenuToolbar);
							 | 
						||
| 
								 | 
							
								        BlueprintToolbar = MakeShareable(new FBlueprintToolbar);
							 | 
						||
| 
								 | 
							
								        AnimationBlueprintToolbar = MakeShareable(new FAnimationBlueprintToolbar);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UUnLuaEditorFunctionLibrary::WatchScriptDirectory();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if ENGINE_MAJOR_VERSION > 4
							 | 
						||
| 
								 | 
							
								        UPackage::PreSavePackageWithContextEvent.AddRaw(this, &FUnLuaEditorModule::OnPackageSavingWithContext);
							 | 
						||
| 
								 | 
							
								        UPackage::PackageSavedWithContextEvent.AddRaw(this, &FUnLuaEditorModule::OnPackageSavedWithContext);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UPackage::PreSavePackageEvent.AddRaw(this, &FUnLuaEditorModule::OnPackageSaving);
							 | 
						||
| 
								 | 
							
								        UPackage::PackageSavedEvent.AddRaw(this, &FUnLuaEditorModule::OnPackageSaved);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        SetupPackagingSettings();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    virtual void ShutdownModule() override
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        FUnLuaEditorCommands::Unregister();
							 | 
						||
| 
								 | 
							
								        FCoreDelegates::OnPostEngineInit.RemoveAll(this);
							 | 
						||
| 
								 | 
							
								        UnregisterSettings();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if ENGINE_MAJOR_VERSION > 4
							 | 
						||
| 
								 | 
							
								        UPackage::PreSavePackageWithContextEvent.RemoveAll(this);
							 | 
						||
| 
								 | 
							
								        UPackage::PackageSavedWithContextEvent.RemoveAll(this);
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								        UPackage::PreSavePackageEvent.RemoveAll(this);
							 | 
						||
| 
								 | 
							
								        UPackage::PackageSavedEvent.RemoveAll(this);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    void OnPostEngineInit()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        RegisterSettings();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!GEditor)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // Loading MainFrame module with '-game' is not supported
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        MainMenuToolbar->Initialize();
							 | 
						||
| 
								 | 
							
								        BlueprintToolbar->Initialize();
							 | 
						||
| 
								 | 
							
								        AnimationBlueprintToolbar->Initialize();
							 | 
						||
| 
								 | 
							
								        FUnLuaIntelliSenseGenerator::Get()->Initialize();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
							 | 
						||
| 
								 | 
							
								        MainFrameModule.OnMainFrameCreationFinished().AddRaw(this, &FUnLuaEditorModule::OnMainFrameCreationFinished);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void OnMainFrameCreationFinished(TSharedPtr<SWindow> InRootWindow, bool bIsNewProjectWindow)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // register default key input to 'HotReload' Lua
							 | 
						||
| 
								 | 
							
								        FPlayWorldCommands::GlobalPlayWorldActions->MapAction(
							 | 
						||
| 
								 | 
							
								            FUnLuaEditorCommands::Get().HotReload, FExecuteAction::CreateStatic(UUnLuaFunctionLibrary::HotReload), FCanExecuteAction());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void RegisterSettings() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
							 | 
						||
| 
								 | 
							
								        if (SettingsModule)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            const TSharedPtr<ISettingsSection> Section = SettingsModule->RegisterSettings("Project", "Plugins", "UnLua Editor",
							 | 
						||
| 
								 | 
							
								                                                                                          LOCTEXT("UnLuaEditorSettingsName", "UnLua Editor"),
							 | 
						||
| 
								 | 
							
								                                                                                          LOCTEXT("UnLuaEditorSettingsDescription", "UnLua Editor Settings"),
							 | 
						||
| 
								 | 
							
								                                                                                          GetMutableDefault<UUnLuaEditorSettings>());
							 | 
						||
| 
								 | 
							
								            Section->OnModified().BindRaw(this, &FUnLuaEditorModule::OnSettingsModified);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void UnregisterSettings() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
							 | 
						||
| 
								 | 
							
								        if (SettingsModule)
							 | 
						||
| 
								 | 
							
								            SettingsModule->UnregisterSettings("Project", "Plugins", "UnLua Editor");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bool OnSettingsModified() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        const auto BuildFile = IPluginManager::Get().FindPlugin(TEXT("UnLua"))->GetBaseDir() / "Source/UnLua/UnLua.Build.cs";
							 | 
						||
| 
								 | 
							
								        auto& FileManager = IFileManager::Get();
							 | 
						||
| 
								 | 
							
								        if (FileManager.FileExists(*BuildFile))
							 | 
						||
| 
								 | 
							
								            FileManager.SetTimeStamp(*BuildFile, FDateTime::UtcNow());
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if ENGINE_MAJOR_VERSION > 4
							 | 
						||
| 
								 | 
							
								    void OnPackageSavingWithContext(UPackage* Package, FObjectPreSaveContext Context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        OnPackageSaving(Package);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void OnPackageSavedWithContext(const FString& PackageFileName, UPackage* Package, FObjectPostSaveContext Context)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        OnPackageSaved(PackageFileName, Package);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void OnPackageSaving(UPackage* Package)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!GEditor || !GEditor->PlayWorld)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ForEachObjectWithPackage(Package, [this, Package](UObject* Object)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            const auto Class = Cast<UClass>(Object);
							 | 
						||
| 
								 | 
							
								            if (!Class || Class->GetName().StartsWith(TEXT("SKEL_")) || Class->GetName().StartsWith(TEXT("REINST_")))
							 | 
						||
| 
								 | 
							
								                return true;
							 | 
						||
| 
								 | 
							
								            SuspendedPackages.Add(Package, Class);
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }, false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (const auto Pair : SuspendedPackages)
							 | 
						||
| 
								 | 
							
								            ULuaFunction::SuspendOverrides(Pair.Value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void OnPackageSaved(const FString& PackageFileName, UObject* Outer)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!GEditor || !GEditor->PlayWorld)
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        UPackage* Package = (UPackage*)Outer;
							 | 
						||
| 
								 | 
							
								        if (SuspendedPackages.Contains(Package))
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            ULuaFunction::ResumeOverrides(SuspendedPackages[Package]);
							 | 
						||
| 
								 | 
							
								            SuspendedPackages.Remove(Package);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void SetupPackagingSettings()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        auto ScriptPaths = TArray<FString>{TEXT("Script"), TEXT("../Plugins/UnLua/Content/Script")};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const auto Plugins = IPluginManager::Get().GetEnabledPlugins();
							 | 
						||
| 
								 | 
							
								        for (const auto Plugin : Plugins)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (!Plugin->CanContainContent())
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            const auto ContentDir = Plugin->GetContentDir();
							 | 
						||
| 
								 | 
							
								            if (!ContentDir.Contains("UnLuaExtensions"))
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            auto ScriptPath = ContentDir / "Script";
							 | 
						||
| 
								 | 
							
								            if (!FPaths::DirectoryExists(ScriptPath))
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (FPaths::MakePathRelativeTo(ScriptPath, *FPaths::ProjectContentDir()))
							 | 
						||
| 
								 | 
							
								                ScriptPaths.Add(ScriptPath);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const auto PackagingSettings = GetMutableDefault<UProjectPackagingSettings>();
							 | 
						||
| 
								 | 
							
								        bool bModified = false;
							 | 
						||
| 
								 | 
							
								        auto Exists = [&](const auto Path)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            for (const auto& DirPath : PackagingSettings->DirectoriesToAlwaysStageAsUFS)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if (DirPath.Path == Path)
							 | 
						||
| 
								 | 
							
								                    return true;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for (auto& ScriptPath : ScriptPaths)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (Exists(ScriptPath))
							 | 
						||
| 
								 | 
							
								                continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            FDirectoryPath DirectoryPath;
							 | 
						||
| 
								 | 
							
								            DirectoryPath.Path = ScriptPath;
							 | 
						||
| 
								 | 
							
								            PackagingSettings->DirectoriesToAlwaysStageAsUFS.Add(DirectoryPath);
							 | 
						||
| 
								 | 
							
								            bModified = true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (bModified)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								#if ENGINE_MAJOR_VERSION >= 5
							 | 
						||
| 
								 | 
							
								            PackagingSettings->TryUpdateDefaultConfigFile();
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								            PackagingSettings->UpdateDefaultConfigFile();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    TSharedPtr<FBlueprintToolbar> BlueprintToolbar;
							 | 
						||
| 
								 | 
							
								    TSharedPtr<FAnimationBlueprintToolbar> AnimationBlueprintToolbar;
							 | 
						||
| 
								 | 
							
								    TSharedPtr<FMainMenuToolbar> MainMenuToolbar;
							 | 
						||
| 
								 | 
							
								    TSharedPtr<FUnLuaIntelliSenseGenerator> IntelliSenseGenerator;
							 | 
						||
| 
								 | 
							
								    TSharedPtr<ISlateStyle> Style;
							 | 
						||
| 
								 | 
							
								    TMap<UPackage*, UClass*> SuspendedPackages;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef LOCTEXT_NAMESPACE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								IMPLEMENT_MODULE(FUnLuaEditorModule, UnLuaEditor)
							 |