diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Add.h b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Add.h index b7340b45..1278959f 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Add.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Add.h @@ -20,7 +20,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_ActorComponent_Add : public UObject, public IWingHandler +class UWing_ActorComponent_Add : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Remove.h b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Remove.h index 59350498..0cdfe415 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Remove.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Remove.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_ActorComponent_Remove : public UObject, public IWingHandler +class UWing_ActorComponent_Remove : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Reparent.h b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Reparent.h index a19bcd93..6e5d9509 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Reparent.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/ActorComponent_Reparent.h @@ -17,7 +17,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_ActorComponent_Reparent : public UObject, public IWingHandler +class UWing_ActorComponent_Reparent : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Backup.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Backup.h index 93766419..eea316c6 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Backup.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Backup.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_Backup : public UObject, public IWingHandler +class UWing_Asset_Backup : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h index 572a1ed7..aea03296 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_ContentBrowse.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_ContentBrowse : public UObject, public IWingHandler +class UWing_Asset_ContentBrowse : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Create.h deleted file mode 100644 index 15b5bdcf..00000000 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Create.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "WingServer.h" -#include "WingHandler.h" -#include "WingFactories.h" -#include "Asset_Create.generated.h" - - -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - -UCLASS() -class UWing_Asset_Create : public UObject, public IWingHandler -{ - GENERATED_BODY() - -public: - UPROPERTY(meta=(Description="Full asset path for the new asset (e.g. '/Game/MyFolder/MyAsset')")) - FString AssetPath; - - UPROPERTY(meta=(Description="Factory type name from Asset_SearchTypes (e.g. 'Material', 'Blueprint')")) - FString Factory; - - UPROPERTY(meta=(Optional, Description="Factory configuration properties as key-value pairs")) - FWingJsonObject Config; - - virtual FString GetDescription() const override - { - return TEXT("Create a new asset using a factory. Use Asset_SearchTypes to find " - "available factory types and their configurable properties."); - } - - virtual void Handle() override - { - UWingFactories::CreateAsset(AssetPath, Factory, Config); - } -}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Delete.h index 39dd8bdc..a92abcf9 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Delete.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_Delete : public UObject, public IWingHandler +class UWing_Asset_Delete : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_FindReferences.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_FindReferences.h index e00dffeb..9f770689 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_FindReferences.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_FindReferences.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_FindReferences : public UObject, public IWingHandler +class UWing_Asset_FindReferences : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Rename.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Rename.h index d05d15dc..98dcc75e 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Rename.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Rename.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_Rename : public UObject, public IWingHandler +class UWing_Asset_Rename : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Restore.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Restore.h index bf9c9954..62c66ed8 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Restore.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Restore.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_Restore : public UObject, public IWingHandler +class UWing_Asset_Restore : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Search.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Search.h index 4fbeff71..e36aed2c 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Search.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_Search.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Asset_Search : public UObject, public IWingHandler +class UWing_Asset_Search : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_SearchTypes.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_SearchTypes.h deleted file mode 100644 index 44137c98..00000000 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Asset_SearchTypes.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "CoreMinimal.h" -#include "WingServer.h" -#include "WingHandler.h" -#include "WingFactories.h" -#include "Asset_SearchTypes.generated.h" - - -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- -// --------------------------------------------------------------------------- - -UCLASS() -class UWing_Asset_SearchTypes : public UObject, public IWingHandler -{ - GENERATED_BODY() - -public: - UPROPERTY(meta=(Description="Query string, can contain *")) - FString Query; - - UPROPERTY(meta=(Optional, Description="Maximum number of results (default 50)")) - int32 MaxResults = 50; - - virtual FString GetDescription() const override - { - return TEXT("Search for asset factory types that can be used with Asset_Create. " - "Returns factory names and their configurable properties."); - } - - virtual void Handle() override - { - FString ExtQuery = TEXT("*") + Query + TEXT("*"); - const TArray& All = UWingFactories::AllFactories(); - - int32 Count = 0; - for (const UWingFactories::Info& Entry : All) - { - if (Count >= MaxResults) break; - if (!Entry.CanCreateNew()) continue; - if (!Entry.Name.MatchesWildcard(ExtQuery, ESearchCase::IgnoreCase)) continue; - - UWingServer::Printf(TEXT("%s\n"), *Entry.Name); - - for (const FName& Prop : Entry.Config) - { - UWingServer::Printf(TEXT(" %s\n"), *Prop.ToString()); - } - - Count++; - } - - if (Count == 0) - { - UWingServer::Print(TEXT("No matching factory types found.\n")); - } - else if (Count >= MaxResults) - { - UWingServer::Printf(TEXT("WARNING: Reached limit of %d results. You may specify MaxResults.\n"), MaxResults); - } - } -}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Create.h index 2a55395c..25e0ba42 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Create.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_BlueprintGraph_Create : public UObject, public IWingHandler +class UWing_BlueprintGraph_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Delete.h index 27a271b8..5f532f7e 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintGraph_Delete.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_BlueprintGraph_Delete : public UObject, public IWingHandler +class UWing_BlueprintGraph_Delete : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Add.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Add.h index 66bf87e8..8f4fa435 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Add.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Add.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_AddInterface : public UObject, public IWingHandler +class UWing_Blueprint_AddInterface : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Remove.h b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Remove.h index 849b7262..62199b6d 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Remove.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/BlueprintInterface_Remove.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_RemoveInterface : public UObject, public IWingHandler +class UWing_Blueprint_RemoveInterface : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Compile.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Compile.h index 6e5408d4..832ae937 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Compile.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Compile.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_Compile : public UObject, public IWingHandler +class UWing_Blueprint_Compile : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Create.h index a9dce7d5..047ace8a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Create.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_Create : public UObject, public IWingHandler +class UWing_Blueprint_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Dump.h index 6c4a701f..3077acf4 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Dump.h @@ -26,7 +26,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_Dump : public UObject, public IWingHandler +class UWing_Blueprint_Dump : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Reparent.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Reparent.h index 7e39e942..706ab9ea 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Reparent.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Blueprint_Reparent.h @@ -17,7 +17,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Blueprint_Reparent : public UObject, public IWingHandler +class UWing_Blueprint_Reparent : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Create_UsingFactory.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Create_UsingFactory.h new file mode 100644 index 00000000..267599df --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Create_UsingFactory.h @@ -0,0 +1,51 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Factories/Factory.h" +#include "WingServer.h" +#include "WingHandler.h" +#include "WingFactories.h" +#include "WingProperty.h" +#include "Create_UsingFactory.generated.h" + +UCLASS() +class UWing_Create_UsingFactory : public UWingHandler +{ + GENERATED_BODY() + +public: + UPROPERTY(meta=(Description="Full asset path for the new asset (e.g. '/Game/MyFolder/MyAsset')")) + FString AssetPath; + + virtual FString GetDescription() const override + { + return TEXT("Create a new asset using a factory."); + } + + virtual void Register(UWingServer* Server) override + { + TArray FactoryClasses; + GetDerivedClasses(UFactory::StaticClass(), FactoryClasses); + + for (UClass* Class : FactoryClasses) + { + if (Class->HasAnyClassFlags(CLASS_Abstract)) continue; + + UFactory* CDO = Class->GetDefaultObject(); + if (!CDO->CanCreateNew() || !CDO->ShouldShowInNewMenu()) continue; + + TArray ConfigProps = FWingProperty::GetNames(Class, CPF_Edit); + if (ConfigProps.Num() > 0) continue; + + FString CommandName = FString::Printf(TEXT("Create_%s"), *UWingFactories::DeriveFactoryName(Class)); + Server->AddHandler(CommandName, GetClass(), Class, EWingHandlerKind::Create); + } + } + + virtual void Handle() override + { + UClass* FactoryClass = Cast(ConfigurationObject); + UFactory* Factory = NewObject(GetTransientPackage(), FactoryClass); + UWingFactories::CreateAsset(AssetPath, Factory); + } +}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_ListOpenAssets.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_ListOpenAssets.h index 30f5bd75..dc466708 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_ListOpenAssets.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_ListOpenAssets.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Editor_ListOpenAssets : public UObject, public IWingHandler +class UWing_Editor_ListOpenAssets : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_OpenAsset.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_OpenAsset.h index d9573f7c..f4cedeeb 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_OpenAsset.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Editor_OpenAsset.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Editor_OpenAsset : public UObject, public IWingHandler +class UWing_Editor_OpenAsset : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Create.h index 192515a8..88a4157b 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Create.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_EventDispatcher_Create : public UObject, public IWingHandler +class UWing_EventDispatcher_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Delete.h index eacfaea4..34a8fd87 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/EventDispatcher_Delete.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_EventDispatcher_Delete : public UObject, public IWingHandler +class UWing_EventDispatcher_Delete : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ChooseMenu.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ChooseMenu.h index 07bcfc0c..e15e0063 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ChooseMenu.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ChooseMenu.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_ChooseMenu : public UObject, public IWingHandler +class UWing_GraphNode_ChooseMenu : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Create.h index 3c8dd0b3..0d9ff283 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Create.h @@ -34,7 +34,7 @@ struct FSpawnNodeEntry UCLASS() -class UWing_GraphNode_Create : public UObject, public IWingHandler +class UWing_GraphNode_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Delete.h index edf61b9e..13920202 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Delete.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_Delete : public UObject, public IWingHandler +class UWing_GraphNode_Delete : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Dump.h index eb613ff2..ca450df7 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Dump.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_Dump : public UObject, public IWingHandler +class UWing_GraphNode_Dump : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_GetComment.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_GetComment.h index 5cd41b9d..7bd3f621 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_GetComment.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_GetComment.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_GetComment : public UObject, public IWingHandler +class UWing_GraphNode_GetComment : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Rename.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Rename.h index 9971ddb2..5cc8a7e2 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Rename.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_Rename.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_Rename : public UObject, public IWingHandler +class UWing_GraphNode_Rename : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h index 89121a35..ec29e7ce 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SearchTypes.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_SearchTypes : public UObject, public IWingHandler +class UWing_GraphNode_SearchTypes : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetComment.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetComment.h index b786d144..c013e389 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetComment.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetComment.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_SetComment : public UObject, public IWingHandler +class UWing_GraphNode_SetComment : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefaults.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefaults.h index 557a4c1c..35680e0a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefaults.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetDefaults.h @@ -33,7 +33,7 @@ struct FSetNodeDefaultEntry UCLASS() -class UWing_GraphNode_SetDefaults : public UObject, public IWingHandler +class UWing_GraphNode_SetDefaults : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPositions.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPositions.h index 164a6ed6..20e5cbb7 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPositions.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_SetPositions.h @@ -31,7 +31,7 @@ struct FMoveNodeEntry UCLASS() -class UWing_GraphNode_SetPositions : public UObject, public IWingHandler +class UWing_GraphNode_SetPositions : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ShowMenu.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ShowMenu.h index 53c0e649..88e8c012 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ShowMenu.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphNode_ShowMenu.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_GraphNode_ShowMenu : public UObject, public IWingHandler +class UWing_GraphNode_ShowMenu : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h index 89bc618c..d4291580 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Connect.h @@ -31,7 +31,7 @@ struct FConnectPinsEntry UCLASS() -class UWing_GraphPin_Connect : public UObject, public IWingHandler +class UWing_GraphPin_Connect : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h index db641d88..e7bf5999 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/GraphPin_Disconnect.h @@ -30,7 +30,7 @@ struct FDisconnectPinEntry UCLASS() -class UWing_GraphPin_Disconnect : public UObject, public IWingHandler +class UWing_GraphPin_Disconnect : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Graph_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Graph_Dump.h index 792fee44..62e59ddb 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Graph_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Graph_Dump.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Graph_Dump : public UObject, public IWingHandler +class UWing_Graph_Dump : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_ClearParameter.h b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_ClearParameter.h index de140df5..48657a8a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_ClearParameter.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_ClearParameter.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_MaterialInstance_ClearParameter : public UObject, public IWingHandler +class UWing_MaterialInstance_ClearParameter : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_Create.h index da716410..40d6af74 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_Create.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_MaterialInstance_Create : public UObject, public IWingHandler +class UWing_MaterialInstance_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_DumpParameters.h b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_DumpParameters.h index 5afaab29..3570937f 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_DumpParameters.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_DumpParameters.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_MaterialInstance_DumpParameters : public UObject, public IWingHandler +class UWing_MaterialInstance_DumpParameters : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_SetParameter.h b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_SetParameter.h index bad14395..0e7d8263 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_SetParameter.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/MaterialInstance_SetParameter.h @@ -17,7 +17,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_MaterialInstance_SetParameter : public UObject, public IWingHandler +class UWing_MaterialInstance_SetParameter : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Compile.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Compile.h index 47462ab3..8874cd4b 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Compile.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Compile.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Material_Compile : public UObject, public IWingHandler +class UWing_Material_Compile : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Create.h index e35cc16d..79808ae5 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_Create.h @@ -16,7 +16,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Material_Create : public UObject, public IWingHandler +class UWing_Material_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_DumpParameters.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_DumpParameters.h index 9424cec2..1ff6d299 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Material_DumpParameters.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Material_DumpParameters.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Material_DumpParameters : public UObject, public IWingHandler +class UWing_Material_DumpParameters : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Dump.h index 6c81add1..5371e445 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Dump.h @@ -15,7 +15,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Property_Dump : public UObject, public IWingHandler +class UWing_Property_Dump : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Get.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Get.h index 7b06fd98..c89e751e 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Get.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Get.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Property_Get : public UObject, public IWingHandler +class UWing_Property_Get : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Set.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Set.h index 294976bf..b22e6c98 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Set.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Property_Set.h @@ -14,7 +14,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Property_Set : public UObject, public IWingHandler +class UWing_Property_Set : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/ShowCommands.h b/Plugins/UEWingman/Source/UEWingman/Handlers/ShowCommands.h index 434b1fca..d172052b 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/ShowCommands.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/ShowCommands.h @@ -10,7 +10,7 @@ #include "ShowCommands.generated.h" UCLASS() -class UWing_ShowCommands : public UObject, public IWingHandler +class UWing_ShowCommands : public UWingHandler { GENERATED_BODY() @@ -21,6 +21,9 @@ public: UPROPERTY(meta=(Optional, Description="If true, return full details including parameter types and descriptions")) bool Verbose = false; + UPROPERTY(meta=(Optional, Description="Kind of command: Normal, or Create")) + EWingHandlerKind Kind = EWingHandlerKind::Normal; + virtual FString GetDescription() const override { return TEXT("List all available commands with their descriptions."); @@ -31,16 +34,15 @@ public: FString QueryLower = Query.ToLower(); FString PrevGroup; - for (UClass* Class : WingUtils::CollectHandlerClasses()) + for (const FWingHandlerConfig& H : UWingServer::AllHandlers()) { - FString ToolName = WingUtils::GetHandlerName(Class); - if (!ToolName.ToLower().Contains(QueryLower)) - continue; + if (H.Kind != Kind) continue; + if (!H.Name.ToLower().Contains(QueryLower)) continue; // Blank line between groups if (!Verbose) { - FString Group = WingUtils::GetHandlerGroup(Class); + FString Group = WingUtils::GetHandlerGroup(H.Class.Get()); if (Group != PrevGroup) { if (!PrevGroup.IsEmpty()) @@ -51,12 +53,20 @@ public: if (Verbose) { - WingManual::PrintHandlerHelp(Class); + WingManual::PrintHandlerHelp(H); } else { - WingManual::PrintHandlerPrototype(Class); + WingManual::PrintHandlerPrototype(H); } } + if (Kind == EWingHandlerKind::Normal) + { + UWingServer::Printf(TEXT( + "\n" + "You can also use ShowCommands with Kind=Create to see\n" + "commands that create new assets.\n" + "\n")); + } } }; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/SysInfo_Factories.h b/Plugins/UEWingman/Source/UEWingman/Handlers/SysInfo_Factories.h new file mode 100644 index 00000000..d882aafc --- /dev/null +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/SysInfo_Factories.h @@ -0,0 +1,48 @@ +#pragma once + +#include "CoreMinimal.h" +#include "WingServer.h" +#include "WingHandler.h" +#include "WingFactories.h" +#include "SysInfo_Factories.generated.h" + + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- + +UCLASS() +class UWing_SysInfo_Factories : public UWingHandler +{ + GENERATED_BODY() + +public: + virtual FString GetDescription() const override + { + return TEXT("Sysinfo commands are intended for the human who " + "is developing this plugin, they help him to understand. " + "unreal's internals better."); + } + + virtual void Handle() override + { + const TArray& All = UWingFactories::AllFactories(); + + for (int nparam = 0; nparam < 10; nparam++) + { + for (const UWingFactories::Info& Entry : All) + { + if (Entry.Config.Num() != nparam) continue; + if (!Entry.CanCreateNew()) continue; + UWingServer::Printf(TEXT("%s"), *Entry.Name); + + for (const FName& Prop : Entry.Config) + { + UWingServer::Printf(TEXT(" PARAM: %s"), *Prop.ToString()); + } + UWingServer::Printf(TEXT("\n")); + } + UWingServer::Printf(TEXT("\n")); + } + } +}; diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Sanitizer.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Sanitizer.h index 8a434326..d9efe129 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Sanitizer.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Sanitizer.h @@ -12,7 +12,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Test_Sanitizer : public UObject, public IWingHandler +class UWing_Test_Sanitizer : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Tokenizer.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Tokenizer.h index 4a68d1f8..f2a35eb9 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Tokenizer.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Tokenizer.h @@ -12,7 +12,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Test_Tokenizer : public UObject, public IWingHandler +class UWing_Test_Tokenizer : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_TypeToText.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_TypeToText.h index 0ec5ebdc..2e5d7394 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_TypeToText.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_TypeToText.h @@ -12,7 +12,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Test_TypeToText : public UObject, public IWingHandler +class UWing_Test_TypeToText : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Unsanitize.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Unsanitize.h index 791fb9d6..f2c59550 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Unsanitize.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Test_Unsanitize.h @@ -12,7 +12,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Test_Unsanitize : public UObject, public IWingHandler +class UWing_Test_Unsanitize : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/TypeName_Search.h b/Plugins/UEWingman/Source/UEWingman/Handlers/TypeName_Search.h index 78a7e69c..0da6945d 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/TypeName_Search.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/TypeName_Search.h @@ -18,7 +18,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_TypeName_Search : public UObject, public IWingHandler +class UWing_TypeName_Search : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/UserManual.h b/Plugins/UEWingman/Source/UEWingman/Handlers/UserManual.h index 0ab772dd..fdb4c764 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/UserManual.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/UserManual.h @@ -6,7 +6,7 @@ #include "UserManual.generated.h" UCLASS() -class UWing_UserManual : public UObject, public IWingHandler +class UWing_UserManual : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Create.h index 091d6868..44c06f01 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Create.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Variables_Create : public UObject, public IWingHandler +class UWing_Variables_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Dump.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Dump.h index 796199fd..92194c8c 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Dump.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Dump.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Variables_Dump : public UObject, public IWingHandler +class UWing_Variables_Dump : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Modify.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Modify.h index adc89fe7..e9a18a01 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Modify.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Modify.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Variables_Modify : public UObject, public IWingHandler +class UWing_Variables_Modify : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Remove.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Remove.h index b36cfb5c..e2acd0ba 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Remove.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Variables_Remove.h @@ -13,7 +13,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Variables_Remove : public UObject, public IWingHandler +class UWing_Variables_Remove : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Create.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Create.h index 72e77732..b144cf54 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Create.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Create.h @@ -19,7 +19,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Widget_Create : public UObject, public IWingHandler +class UWing_Widget_Create : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Delete.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Delete.h index fe9c268a..7ed17682 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Delete.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Delete.h @@ -17,7 +17,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Widget_Delete : public UObject, public IWingHandler +class UWing_Widget_Delete : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Reparent.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Reparent.h index 21e9aca5..2e835b4a 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Reparent.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_Reparent.h @@ -17,7 +17,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Widget_Reparent : public UObject, public IWingHandler +class UWing_Widget_Reparent : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h index 5040c6bd..3899faac 100644 --- a/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h +++ b/Plugins/UEWingman/Source/UEWingman/Handlers/Widget_SearchTypes.h @@ -12,7 +12,7 @@ // --------------------------------------------------------------------------- UCLASS() -class UWing_Widget_SearchTypes : public UObject, public IWingHandler +class UWing_Widget_SearchTypes : public UWingHandler { GENERATED_BODY() diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp index 6a9b71c0..708fb4c0 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingFactories.cpp @@ -3,7 +3,7 @@ #include "Editor.h" #include "WingUtils.h" #include "WingProperty.h" -#include "WingPackageMaker.h" +#include "PackageTools.h" #include "Kismet2/KismetEditorUtilities.h" #include "Kismet2/EnumEditorUtils.h" #include "Factories/BlueprintFactory.h" @@ -62,6 +62,78 @@ void UWingFactories::DisableFactory(const TCHAR* Name) Entry->Disabled = true; } + +bool UWingFactories::CheckNewAssetPath(const FString& Path) +{ + if (UPackageTools::SanitizePackageName(Path) != Path) + { + UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path); + return false; + } + if (!FPackageName::IsValidTextForLongPackageName(Path)) + { + UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path); + return false; + } + if (!Path.StartsWith(TEXT("/Game"))) + { + UWingServer::Printf(TEXT("ERROR: Package path '%s' must start with '/Game'\n"), *Path); + return false; + } + if (FindObject(nullptr, *Path)) + { + UWingServer::Printf(TEXT("ERROR: An asset already exists at '%s'\n"), *Path); + return false; + } + return true; +} + +UPackage *UWingFactories::CreateNewPackage(const FString &Path) +{ + UPackage *Pkg = CreatePackage(*Path); + if (!Pkg) + { + UWingServer::Printf(TEXT("ERROR: Failed to create package at '%s'\n"), *Path); + return nullptr; + } + + Pkg->ClearFlags(RF_Transient); + Pkg->SetIsExternallyReferenceable(true); + Pkg->MarkPackageDirty(); + return Pkg; +} + + +UObject* UWingFactories::CreateAsset(const FString& Path, UFactory* Factory) +{ + // Validate the path, and that there's not already something there. + if (!CheckNewAssetPath(Path)) return nullptr; + FName Name = FName(FPackageName::GetShortName(Path)); + + // Pre-check: block factories that would cause problems. + // In particular, this blocks those that would pop a dialog. + if (!PreCheck(Factory, Name, Path)) return nullptr; + + // Create the asset. + UPackage *Package = CreateNewPackage(Path); + UObject* NewAsset = Factory->FactoryCreateNew( + Factory->GetSupportedClass(), + Package, + Name, + RF_Public | RF_Standalone | RF_Transactional, + nullptr, + GWarn + ); + if (!NewAsset) + { + UWingServer::Printf(TEXT("ERROR: Factory '%s' returned null\n"), *Factory->GetClass()->GetName()); + return nullptr; + } + + UWingServer::Printf(TEXT("Created: %s\n"), *WingUtils::ExternalizeID(Name)); + return NewAsset; +} + UObject* UWingFactories::CreateAsset(const FString& Path, const FString& FactoryName, FWingJsonObject& Config) { UWingFactories* Self = GEditor->GetEditorSubsystem(); @@ -74,18 +146,13 @@ UObject* UWingFactories::CreateAsset(const FString& Path, const FString& Factory return nullptr; } - // Make sure this is the a creation factory, as opposed to an import factory. + // Make sure this is a creation factory, as opposed to an import factory. if (!FactoryInfo->CanCreateNew()) { UWingServer::Printf(TEXT("ERROR: Factory '%s' cannot create objects from scratch\n"), *FactoryName); return nullptr; } - // Validate the path, and that there's not already something there. - WingPackageMaker Maker(Path); - if (!Maker.Ok()) return nullptr; - FName Name = Maker.GetFName(); - // Create the factory instance. UFactory* Factory = NewObject(GetTransientPackage(), FactoryInfo->FactoryClass); @@ -101,28 +168,7 @@ UObject* UWingFactories::CreateAsset(const FString& Path, const FString& Factory if (!FWingProperty::PopulateFromJson(Props, ConfigJson.Get(), false)) return nullptr; - // Pre-check: block factories that would cause problems. - // In particular, this blocks those that would pop a dialog. - if (!PreCheck(Factory, Name, Path)) return nullptr; - - // Create the asset. - if (!Maker.Make()) return nullptr; - UObject* NewAsset = Factory->FactoryCreateNew( - FactoryInfo->FactoryClass->GetDefaultObject()->GetSupportedClass(), - Maker.Package(), - Name, - RF_Public | RF_Standalone | RF_Transactional, - nullptr, - GWarn - ); - if (!NewAsset) - { - UWingServer::Printf(TEXT("ERROR: Factory '%s' returned null\n"), *FactoryName); - return nullptr; - } - - UWingServer::Printf(TEXT("Created: %s\n"), *WingUtils::ExternalizeID(Name)); - return NewAsset; + return CreateAsset(Path, Factory); } bool UWingFactories::PreCheck(UFactory* Factory, FName Name, const FString &Path) diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp index 56708340..98660311 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingManual.cpp @@ -3,12 +3,12 @@ #include "WingHandler.h" #include "WingTypes.h" -void WingManual::PrintHandlerPrototype(UClass *HandlerClass) +void WingManual::PrintHandlerPrototype(const FWingHandlerConfig& Handler) { - UWingServer::Print(WingUtils::GetHandlerName(HandlerClass)); + UWingServer::Print(Handler.Name); UWingServer::Print(TEXT("(")); bool bFirst = true; - for (TFieldIterator PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt) + for (TFieldIterator PropIt(Handler.Class.Get(), EFieldIterationFlags::None); PropIt; ++PropIt) { if (!bFirst) UWingServer::Print(TEXT(",")); bFirst = false; @@ -18,10 +18,10 @@ void WingManual::PrintHandlerPrototype(UClass *HandlerClass) UWingServer::Print(TEXT(")\n")); } -void WingManual::PrintHandlerArguments(UClass *HandlerClass) +void WingManual::PrintHandlerArguments(const FWingHandlerConfig& Handler) { // parameter details - for (TFieldIterator PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt) + for (TFieldIterator PropIt(Handler.Class.Get(), EFieldIterationFlags::None); PropIt; ++PropIt) { FProperty* Prop = *PropIt; FString Name = Prop->GetName(); @@ -42,23 +42,23 @@ void WingManual::PrintHandlerArguments(UClass *HandlerClass) } } -void WingManual::PrintHandlerDescription(UClass *HandlerClass) +void WingManual::PrintHandlerDescription(const FWingHandlerConfig& Handler) { - const IWingHandler* Handler = Cast(HandlerClass->GetDefaultObject()); - if (!Handler) return; - UWingServer::Print(WingUtils::WrapText(Handler->GetDescription(), 80, TEXT(" // "))); + const UWingHandler* HandlerCDO = Cast(Handler.Class->GetDefaultObject()); + if (!HandlerCDO) return; + UWingServer::Print(WingUtils::WrapText(HandlerCDO->GetDescription(), 80, TEXT(" // "))); } -void WingManual::PrintHandlerHelp(UClass* HandlerClass) +void WingManual::PrintHandlerHelp(const FWingHandlerConfig& Handler) { UWingServer::Print(TEXT("\n")); - PrintHandlerPrototype(HandlerClass); - PrintHandlerArguments(HandlerClass); - PrintHandlerDescription(HandlerClass); + PrintHandlerPrototype(Handler); + PrintHandlerArguments(Handler); + PrintHandlerDescription(Handler); UWingServer::Print(TEXT("\n")); } -void WingManual::PrintManual(TSet
Sections, UClass *Handler, bool Abridged) +void WingManual::PrintManual(TSet
Sections, const FWingHandlerConfig* Handler, bool Abridged) { if (Sections.IsEmpty()) return; @@ -71,7 +71,7 @@ void WingManual::PrintManual(TSet
Sections, UClass *Handler, bool Abrid if (Handler && (Sections.Contains(Section::HandlerHelp) || bPrintAll)) { - PrintHandlerHelp(Handler); + PrintHandlerHelp(*Handler); } if (Sections.Contains(Section::Paths) || bPrintAll) diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingPackageMaker.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingPackageMaker.cpp index 8913a420..11705dcf 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingPackageMaker.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingPackageMaker.cpp @@ -1,4 +1,5 @@ #include "WingPackageMaker.h" +#include "PackageTools.h" #include "AssetRegistry/AssetRegistryModule.h" WingPackageMaker::WingPackageMaker(const FString& InFullPath) @@ -13,6 +14,11 @@ WingPackageMaker::WingPackageMaker(const FString& InFullPath) bool WingPackageMaker::CheckNewAssetPath(const FString& Path) { + if (UPackageTools::SanitizePackageName(Path) != Path) + { + UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path); + return false; + } if (!FPackageName::IsValidTextForLongPackageName(Path)) { UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path); diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingServer.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingServer.cpp index f0e0153c..a4505b96 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingServer.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingServer.cpp @@ -265,7 +265,7 @@ FString UWingServer::HandleRequest(const FString& Line) LogCapture.bEnabled = true; HandlerOutput.Reset(); SuggestedManualSections.Empty(); - LastHandlerClass = nullptr; + LastHandler = nullptr; TryCallHandler(Line); @@ -279,7 +279,7 @@ FString UWingServer::HandleRequest(const FString& Line) if (!SuggestedManualSections.IsEmpty()) { UWingServer::SuggestManual(WingManual::Section::HandlerHelp); - WingManual::PrintManual(SuggestedManualSections, LastHandlerClass, true); + WingManual::PrintManual(SuggestedManualSections, LastHandler, true); } FString Result = HandlerOutput.ToString(); HandlerOutput.Reset(); @@ -312,19 +312,20 @@ void UWingServer::TryCallHandler(const FString &Line) } Request->RemoveField(TEXT("command")); - // Find the handler UClass for the specified command. - TObjectPtr* HandlerClass = WingHandlerRegistry.Find(Command); - if (!HandlerClass) + // Find the handler for the specified command. + FWingHandlerConfig* Found = FindHandler(Command); + if (!Found) { UWingServer::Printf(TEXT("Unknown command: %s"), *Command); UWingServer::SuggestManual(WingManual::Section::ImportantCommands); return; } - LastHandlerClass = *HandlerClass; + LastHandler = Found; // Make an object of the handler class. - TStrongObjectPtr HandlerObj(NewObject(GetTransientPackage(), *HandlerClass)); - IWingHandler* Handler = Cast(HandlerObj.Get()); + TStrongObjectPtr HandlerObj(NewObject(GetTransientPackage(), Found->Class.Get())); + UWingHandler* Handler = Cast(HandlerObj.Get()); + Handler->ConfigurationObject = Found->Config.Get(); // Populate the handler object with the request parameters. if (!FWingProperty::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request)) @@ -451,10 +452,39 @@ void UWingServer::ClientThreadFunc(UWingServer* Server, TSharedPtrAddHandler(WingUtils::GetHandlerName(Class), Class, nullptr, EWingHandlerKind::Normal); +} + +void UWingServer::AddHandler(const FString& Name, UClass* Class, UObject* Config, EWingHandlerKind Kind) +{ + FWingHandlerConfig H; + H.Name = Name; + H.Class = TStrongObjectPtr(Class); + H.Config = TStrongObjectPtr(Config); + H.Kind = Kind; + + WingHandlerRegistry.Add(MoveTemp(H)); +} + void UWingServer::BuildWingHandlerRegistry() { for (UClass* Class : WingUtils::CollectHandlerClasses()) { - WingHandlerRegistry.FindOrAdd(WingUtils::GetHandlerName(Class)) = Class; + UWingHandler* CDO = Cast(Class->GetDefaultObject()); + CDO->Register(this); } + WingHandlerRegistry.Sort([](const FWingHandlerConfig& A, const FWingHandlerConfig& B) { return A.Name < B.Name; }); +} + +FWingHandlerConfig* UWingServer::FindHandler(const FString& Name) +{ + int32 Index = Algo::LowerBoundBy(WingHandlerRegistry, Name, [](const FWingHandlerConfig& H) { return H.Name; }); + if (Index < WingHandlerRegistry.Num() && WingHandlerRegistry[Index].Name == Name) + { + return &WingHandlerRegistry[Index]; + } + return nullptr; } diff --git a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp index 476bdb0e..d24b1518 100644 --- a/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp +++ b/Plugins/UEWingman/Source/UEWingman/Private/WingUtils.cpp @@ -600,7 +600,7 @@ TArray WingUtils::CollectHandlerClasses() { UClass* Class = *It; if (Class->HasAnyClassFlags(CLASS_Abstract)) continue; - if (!Class->ImplementsInterface(UWingHandler::StaticClass())) continue; + if (!Class->IsChildOf(UWingHandler::StaticClass())) continue; Result.Add(Class); } Result.Sort([](UClass& A, UClass& B) { return GetHandlerName(&A) < GetHandlerName(&B); }); diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h b/Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h index 883e38b7..ac50b092 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingFactories.h @@ -26,17 +26,22 @@ public: static const TArray& AllFactories(); - // Create an asset on disk, using a factory. Returns the main object. + // Create an asset on disk, using a factory instance. Returns the main object. // If there are problems, prints error messages and returns nullptr. - static UObject *CreateAsset(const FString &Path, const FString &Factory, FWingJsonObject &Config); + static UObject *CreateAsset(const FString &Path, UFactory *Factory); + + // Create an asset on disk, looking up the factory by name and configuring it. + static UObject *CreateAsset(const FString &Path, const FString &FactoryName, FWingJsonObject &Config); + + static FString DeriveFactoryName(UClass* FactoryClass); private: TArray Registry; Info* Find(const FString& Name); - + static UPackage *CreateNewPackage(const FString &Path); + static bool CheckNewAssetPath(const FString &Path); void PopulateRegistry(); void DisableFactory(const TCHAR* Name); static bool PreCheck(UFactory *Factory, FName Name, const FString &Path); - static FString DeriveFactoryName(UClass* FactoryClass); }; diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingHandler.h b/Plugins/UEWingman/Source/UEWingman/Public/WingHandler.h index a3bb4ed5..feaf5170 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingHandler.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingHandler.h @@ -1,8 +1,8 @@ #pragma once #include "CoreMinimal.h" -#include "UObject/Interface.h" #include "UObject/Object.h" +#include "UObject/StrongObjectPtr.h" #include "Dom/JsonObject.h" #include "WingHandler.generated.h" @@ -24,32 +24,40 @@ struct FWingJsonArray TArray> Array; }; -// Interface for self-registering MCP tool handlers. -// -// Implementing classes declare their parameters as UPROPERTY fields, which are -// automatically populated from the incoming JSON request and used to -// generate the tool's JSON Schema for MCP tools/list. -// -// Class metadata: -// ToolName - the MCP tool name (e.g. "spawn_node") -// -// Property metadata: -// Optional - marks a parameter as not required -// -UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint)) -class UWingHandler : public UInterface +class UWingServer; + +UENUM() +enum class EWingHandlerKind { - GENERATED_BODY() + Normal, + Create }; -class UEWINGMAN_API IWingHandler +USTRUCT() +struct FWingHandlerConfig +{ + GENERATED_BODY() + FString Name; + TStrongObjectPtr Class; + TStrongObjectPtr Config; + EWingHandlerKind Kind = EWingHandlerKind::Normal; +}; + +UCLASS(Abstract) +class UEWINGMAN_API UWingHandler : public UObject { GENERATED_BODY() public: // Human-readable tool description for MCP tools/list. - virtual FString GetDescription() const = 0; + virtual FString GetDescription() const PURE_VIRTUAL(UWingHandler::GetDescription, return FString();); + + // Register this handler's commands with the server. + virtual void Register(UWingServer* Server); // Called after parameter fields have been populated from JSON. virtual void Handle() {} + + // The configuration object. + UObject *ConfigurationObject; }; diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h b/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h index eea7a7ab..4d452d9b 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingManual.h @@ -1,5 +1,6 @@ #pragma once #include "Containers/Set.h" +#include "WingHandler.h" class WingManual { @@ -17,9 +18,9 @@ public: ImportantCommands, }; - static void PrintHandlerPrototype(UClass *Handler); - static void PrintHandlerArguments(UClass *Handler); - static void PrintHandlerDescription(UClass *Handler); - static void PrintHandlerHelp(UClass *Handler); - static void PrintManual(TSet
Sections, UClass *Handler, bool Abridged); + static void PrintHandlerPrototype(const FWingHandlerConfig& Handler); + static void PrintHandlerArguments(const FWingHandlerConfig& Handler); + static void PrintHandlerDescription(const FWingHandlerConfig& Handler); + static void PrintHandlerHelp(const FWingHandlerConfig& Handler); + static void PrintManual(TSet
Sections, const FWingHandlerConfig* Handler, bool Abridged); }; diff --git a/Plugins/UEWingman/Source/UEWingman/Public/WingServer.h b/Plugins/UEWingman/Source/UEWingman/Public/WingServer.h index 0bc1aa89..cdc1a6a8 100644 --- a/Plugins/UEWingman/Source/UEWingman/Public/WingServer.h +++ b/Plugins/UEWingman/Source/UEWingman/Public/WingServer.h @@ -9,6 +9,7 @@ #include "WingUtils.h" #include "WingNotifier.h" #include "WingLogCapture.h" +#include "WingHandler.h" #include "WingManual.h" #include "WingServer.generated.h" @@ -72,19 +73,22 @@ public: /** Port the server is listening on. */ int32 GetPort() const { return Port; } + // ----- Tool dispatch ----- + void AddHandler(const FString& Name, UClass* Class, UObject* Config, EWingHandlerKind Kind); + static const TArray& AllHandlers() { return GWingServer->WingHandlerRegistry; } + private: static UWingServer* GWingServer; - // ----- Tool dispatch ----- UPROPERTY() FWingNotifier Notifier; - UClass* LastHandlerClass; + FWingHandlerConfig* LastHandler; TStringBuilder<16384> HandlerOutput; TSet SuggestedManualSections; FLogCaptureOutputDevice LogCapture; // installed once at startup, enabled per-request - UPROPERTY() - TMap> WingHandlerRegistry; // tool name -> UWingHandler subclass + TArray WingHandlerRegistry; // sorted by Name void BuildWingHandlerRegistry(); + FWingHandlerConfig* FindHandler(const FString& Name); // Handle a complete JSON line and return the response JSON FString HandleRequest(const FString& Line);