195 lines
7.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "AIGC.h"
#include "AIGCSetting.h"
#include "AIGCStyle.h"
#include "AssetToolsModule.h"
#include "FileHelpers.h"
#include "ISettingsModule.h"
#include "LevelEditor.h"
#include "ToolMenu.h"
#include "ToolMenus.h"
#include "WebSocketManager.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "Misc/MessageDialog.h"
#include "UObject/SavePackage.h"
#include "Widget/AIGCWindow.h"
#include "Widget/CharacterWindow.h"
#define LOCTEXT_NAMESPACE "FAIGCModule"
#define AIGCWindowName FName("AIGC")
#define CharacterWindowName FName("Character")
void FAIGCModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
RegeisterSettings();
//添加style
FAIGCStyle::Initialize();
FAIGCStyle::ReloadTextures();
//添加菜单
UToolMenu* menu = UToolMenus::Get()->FindMenu(FName("LevelEditor.MainMenu.AIGC"));
if (!menu)
{
menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu");
FToolMenuSection& section = menu->FindOrAddSection(FName("TestSection"));
// 添加子菜单入口
section = menu->FindOrAddSection(FName("AIGC Section"));
FToolMenuEntry& entry = section.AddSubMenu("AIGC Section", FText::FromString("AIGC"),
FText::FromString("AIGC ToolTip"),
FNewToolMenuDelegate::CreateLambda([this](UToolMenu* SubMenu)
{
// 填充第一个子菜单项
FToolMenuSection& SubSection = SubMenu->AddSection("AIChat");
SubSection.AddMenuEntry(
"AIChat",
LOCTEXT("AIChat", "生成NPC对话"),
LOCTEXT("AIChatToolTip", ""),
FSlateIcon(FAIGCStyle::GetStyleSetName(), "AIGCStyle.AIChat"),
FUIAction(FExecuteAction::CreateLambda([this]()
{
FGlobalTabmanager::Get()->TryInvokeTab(AIGCWindowName);
})));
//添加人员配置菜单
FToolMenuSection& CharacterSection = SubMenu->AddSection("Character");
SubSection.AddMenuEntry(
"Character",
LOCTEXT("Character", "角色配置"),
LOCTEXT("CharacterToolTip", ""),
FSlateIcon(FAIGCStyle::GetStyleSetName(), "AIGCStyle.AIChat"),
FUIAction(FExecuteAction::CreateLambda([this]()
{
FGlobalTabmanager::Get()->TryInvokeTab(CharacterWindowName);
})));
}),
false, // 是否动态生成
FSlateIcon());
entry.InsertPosition = FToolMenuInsert("Help", EToolMenuInsertType::After); //将自定义的菜单项置于"Help"菜单项的后面
menu = UToolMenus::Get()->RegisterMenu(FName("LevelEditor.MainMenu.AIGC"));
}
//注册Chat窗口
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(AIGCWindowName, FOnSpawnTab::CreateRaw(this, &FAIGCModule::OnSpawnAIChatTab))
.SetDisplayName(LOCTEXT("AIGCWindow", "AIGCWindow"))
.SetMenuType(ETabSpawnerMenuType::Hidden);
//注册角色窗口
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(CharacterWindowName, FOnSpawnTab::CreateRaw(this, &FAIGCModule::OnSpawnCharacterTab))
.SetDisplayName(LOCTEXT("CharacterWindow", "CharacterWindow"))
.SetMenuType(ETabSpawnerMenuType::Hidden);
}
void FAIGCModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
UnregisterSettings();
UToolMenus::UnregisterOwner(this);
FAIGCStyle::Shutdown();
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(AIGCWindowName);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(CharacterWindowName);
}
void FAIGCModule::RegeisterSettings()
{
#if WITH_EDITOR
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (!SettingsModule)
return;
const auto Section = SettingsModule->RegisterSettings("Project", "Plugins", "AIGC",
FText::FromString(TEXT("AIGC")),
FText::FromString(TEXT("AIGC Setting")),
GetMutableDefault<UAIGCSetting>());
#endif
}
void FAIGCModule::UnregisterSettings()
{
#if WITH_EDITOR
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (SettingsModule)
SettingsModule->UnregisterSettings("Project", "Plugins", "AIGC");
#endif
}
TSharedRef<SDockTab> FAIGCModule::OnSpawnAIChatTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SAIGCWindow)
]
];
}
TSharedRef<SDockTab> FAIGCModule::OnSpawnCharacterTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SCharacterWindow)
]
];
}
void FAIGCModule::CreateOrAddData(const FString& DataTablePath, const FString& RowValue)
{
FString PackagePath, AssetName;
DataTablePath.Split(".", &PackagePath, &AssetName);
// 1. 检测资源是否存在
UDataTable* DataTable = LoadObject<UDataTable>(nullptr, *DataTablePath);
if (!DataTable) {
// 2. 创建新DataTable
UPackage* Package = CreatePackage(*PackagePath);
DataTable = NewObject<UDataTable>(Package, FName(*AssetName), RF_Public | RF_Standalone );
DataTable->RowStruct = FNPCChatRow::StaticStruct();
}
// 3. 添加数据
FNPCChatRow NewRow;
NewRow.ChatText = RowValue;
FString DynamicName = FString::Printf(TEXT("DynamicRow%d"), DataTable->GetRowMap().Num());
DataTable->AddRow(FName(*DynamicName), NewRow);
// 保存
DataTable->MarkPackageDirty();
// 保存参数配置
FSavePackageArgs SaveArgs;
SaveArgs.TopLevelFlags = RF_Standalone | RF_Public;
SaveArgs.SaveFlags = SAVE_NoError;
FString FilePath = FPackageName::LongPackageNameToFilename(PackagePath) + ".uasset";
UPackage::SavePackage(DataTable->GetPackage(), DataTable, *FilePath, SaveArgs);
}
UWebSocketManager* FAIGCModule::GetWebSocketManager()
{
return WebSocketManager;
}
void FAIGCModule::InitWebSocketManager()
{
auto& Settings = *GetDefault<UAIGCSetting>();
WebSocketManager = NewObject<UWebSocketManager>();
WebSocketManager->InitWebSocket(Settings.ServerIP);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FAIGCModule, AIGC)