Handler registration overhaul
This commit is contained in:
@@ -20,7 +20,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_ActorComponent_Add : public UObject, public IWingHandler
|
class UWing_ActorComponent_Add : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_ActorComponent_Remove : public UObject, public IWingHandler
|
class UWing_ActorComponent_Remove : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_ActorComponent_Reparent : public UObject, public IWingHandler
|
class UWing_ActorComponent_Reparent : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_Backup : public UObject, public IWingHandler
|
class UWing_Asset_Backup : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_ContentBrowse : public UObject, public IWingHandler
|
class UWing_Asset_ContentBrowse : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_Delete : public UObject, public IWingHandler
|
class UWing_Asset_Delete : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_FindReferences : public UObject, public IWingHandler
|
class UWing_Asset_FindReferences : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_Rename : public UObject, public IWingHandler
|
class UWing_Asset_Rename : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_Restore : public UObject, public IWingHandler
|
class UWing_Asset_Restore : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Asset_Search : public UObject, public IWingHandler
|
class UWing_Asset_Search : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -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<UWingFactories::Info>& 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_BlueprintGraph_Create : public UObject, public IWingHandler
|
class UWing_BlueprintGraph_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_BlueprintGraph_Delete : public UObject, public IWingHandler
|
class UWing_BlueprintGraph_Delete : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_AddInterface : public UObject, public IWingHandler
|
class UWing_Blueprint_AddInterface : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_RemoveInterface : public UObject, public IWingHandler
|
class UWing_Blueprint_RemoveInterface : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_Compile : public UObject, public IWingHandler
|
class UWing_Blueprint_Compile : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_Create : public UObject, public IWingHandler
|
class UWing_Blueprint_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_Dump : public UObject, public IWingHandler
|
class UWing_Blueprint_Dump : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Blueprint_Reparent : public UObject, public IWingHandler
|
class UWing_Blueprint_Reparent : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -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<UClass*> FactoryClasses;
|
||||||
|
GetDerivedClasses(UFactory::StaticClass(), FactoryClasses);
|
||||||
|
|
||||||
|
for (UClass* Class : FactoryClasses)
|
||||||
|
{
|
||||||
|
if (Class->HasAnyClassFlags(CLASS_Abstract)) continue;
|
||||||
|
|
||||||
|
UFactory* CDO = Class->GetDefaultObject<UFactory>();
|
||||||
|
if (!CDO->CanCreateNew() || !CDO->ShouldShowInNewMenu()) continue;
|
||||||
|
|
||||||
|
TArray<FName> 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<UClass>(ConfigurationObject);
|
||||||
|
UFactory* Factory = NewObject<UFactory>(GetTransientPackage(), FactoryClass);
|
||||||
|
UWingFactories::CreateAsset(AssetPath, Factory);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Editor_ListOpenAssets : public UObject, public IWingHandler
|
class UWing_Editor_ListOpenAssets : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Editor_OpenAsset : public UObject, public IWingHandler
|
class UWing_Editor_OpenAsset : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_EventDispatcher_Create : public UObject, public IWingHandler
|
class UWing_EventDispatcher_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_EventDispatcher_Delete : public UObject, public IWingHandler
|
class UWing_EventDispatcher_Delete : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_ChooseMenu : public UObject, public IWingHandler
|
class UWing_GraphNode_ChooseMenu : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ struct FSpawnNodeEntry
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_Create : public UObject, public IWingHandler
|
class UWing_GraphNode_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_Delete : public UObject, public IWingHandler
|
class UWing_GraphNode_Delete : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_Dump : public UObject, public IWingHandler
|
class UWing_GraphNode_Dump : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_GetComment : public UObject, public IWingHandler
|
class UWing_GraphNode_GetComment : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_Rename : public UObject, public IWingHandler
|
class UWing_GraphNode_Rename : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_SearchTypes : public UObject, public IWingHandler
|
class UWing_GraphNode_SearchTypes : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_SetComment : public UObject, public IWingHandler
|
class UWing_GraphNode_SetComment : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ struct FSetNodeDefaultEntry
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_SetDefaults : public UObject, public IWingHandler
|
class UWing_GraphNode_SetDefaults : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct FMoveNodeEntry
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_SetPositions : public UObject, public IWingHandler
|
class UWing_GraphNode_SetPositions : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphNode_ShowMenu : public UObject, public IWingHandler
|
class UWing_GraphNode_ShowMenu : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct FConnectPinsEntry
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphPin_Connect : public UObject, public IWingHandler
|
class UWing_GraphPin_Connect : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ struct FDisconnectPinEntry
|
|||||||
|
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_GraphPin_Disconnect : public UObject, public IWingHandler
|
class UWing_GraphPin_Disconnect : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Graph_Dump : public UObject, public IWingHandler
|
class UWing_Graph_Dump : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_MaterialInstance_ClearParameter : public UObject, public IWingHandler
|
class UWing_MaterialInstance_ClearParameter : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_MaterialInstance_Create : public UObject, public IWingHandler
|
class UWing_MaterialInstance_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_MaterialInstance_DumpParameters : public UObject, public IWingHandler
|
class UWing_MaterialInstance_DumpParameters : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_MaterialInstance_SetParameter : public UObject, public IWingHandler
|
class UWing_MaterialInstance_SetParameter : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Material_Compile : public UObject, public IWingHandler
|
class UWing_Material_Compile : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Material_Create : public UObject, public IWingHandler
|
class UWing_Material_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Material_DumpParameters : public UObject, public IWingHandler
|
class UWing_Material_DumpParameters : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Property_Dump : public UObject, public IWingHandler
|
class UWing_Property_Dump : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Property_Get : public UObject, public IWingHandler
|
class UWing_Property_Get : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Property_Set : public UObject, public IWingHandler
|
class UWing_Property_Set : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "ShowCommands.generated.h"
|
#include "ShowCommands.generated.h"
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_ShowCommands : public UObject, public IWingHandler
|
class UWing_ShowCommands : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
@@ -21,6 +21,9 @@ public:
|
|||||||
UPROPERTY(meta=(Optional, Description="If true, return full details including parameter types and descriptions"))
|
UPROPERTY(meta=(Optional, Description="If true, return full details including parameter types and descriptions"))
|
||||||
bool Verbose = false;
|
bool Verbose = false;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Optional, Description="Kind of command: Normal, or Create"))
|
||||||
|
EWingHandlerKind Kind = EWingHandlerKind::Normal;
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("List all available commands with their descriptions.");
|
return TEXT("List all available commands with their descriptions.");
|
||||||
@@ -31,16 +34,15 @@ public:
|
|||||||
FString QueryLower = Query.ToLower();
|
FString QueryLower = Query.ToLower();
|
||||||
FString PrevGroup;
|
FString PrevGroup;
|
||||||
|
|
||||||
for (UClass* Class : WingUtils::CollectHandlerClasses())
|
for (const FWingHandlerConfig& H : UWingServer::AllHandlers())
|
||||||
{
|
{
|
||||||
FString ToolName = WingUtils::GetHandlerName(Class);
|
if (H.Kind != Kind) continue;
|
||||||
if (!ToolName.ToLower().Contains(QueryLower))
|
if (!H.Name.ToLower().Contains(QueryLower)) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// Blank line between groups
|
// Blank line between groups
|
||||||
if (!Verbose)
|
if (!Verbose)
|
||||||
{
|
{
|
||||||
FString Group = WingUtils::GetHandlerGroup(Class);
|
FString Group = WingUtils::GetHandlerGroup(H.Class.Get());
|
||||||
if (Group != PrevGroup)
|
if (Group != PrevGroup)
|
||||||
{
|
{
|
||||||
if (!PrevGroup.IsEmpty())
|
if (!PrevGroup.IsEmpty())
|
||||||
@@ -51,12 +53,20 @@ public:
|
|||||||
|
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
{
|
{
|
||||||
WingManual::PrintHandlerHelp(Class);
|
WingManual::PrintHandlerHelp(H);
|
||||||
}
|
}
|
||||||
else
|
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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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<UWingFactories::Info>& 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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Test_Sanitizer : public UObject, public IWingHandler
|
class UWing_Test_Sanitizer : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Test_Tokenizer : public UObject, public IWingHandler
|
class UWing_Test_Tokenizer : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Test_TypeToText : public UObject, public IWingHandler
|
class UWing_Test_TypeToText : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Test_Unsanitize : public UObject, public IWingHandler
|
class UWing_Test_Unsanitize : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_TypeName_Search : public UObject, public IWingHandler
|
class UWing_TypeName_Search : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "UserManual.generated.h"
|
#include "UserManual.generated.h"
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_UserManual : public UObject, public IWingHandler
|
class UWing_UserManual : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Variables_Create : public UObject, public IWingHandler
|
class UWing_Variables_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Variables_Dump : public UObject, public IWingHandler
|
class UWing_Variables_Dump : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Variables_Modify : public UObject, public IWingHandler
|
class UWing_Variables_Modify : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Variables_Remove : public UObject, public IWingHandler
|
class UWing_Variables_Remove : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Widget_Create : public UObject, public IWingHandler
|
class UWing_Widget_Create : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Widget_Delete : public UObject, public IWingHandler
|
class UWing_Widget_Delete : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Widget_Reparent : public UObject, public IWingHandler
|
class UWing_Widget_Reparent : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class UWing_Widget_SearchTypes : public UObject, public IWingHandler
|
class UWing_Widget_SearchTypes : public UWingHandler
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "Editor.h"
|
#include "Editor.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingProperty.h"
|
#include "WingProperty.h"
|
||||||
#include "WingPackageMaker.h"
|
#include "PackageTools.h"
|
||||||
#include "Kismet2/KismetEditorUtilities.h"
|
#include "Kismet2/KismetEditorUtilities.h"
|
||||||
#include "Kismet2/EnumEditorUtils.h"
|
#include "Kismet2/EnumEditorUtils.h"
|
||||||
#include "Factories/BlueprintFactory.h"
|
#include "Factories/BlueprintFactory.h"
|
||||||
@@ -62,6 +62,78 @@ void UWingFactories::DisableFactory(const TCHAR* Name)
|
|||||||
Entry->Disabled = true;
|
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<UPackage>(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)
|
UObject* UWingFactories::CreateAsset(const FString& Path, const FString& FactoryName, FWingJsonObject& Config)
|
||||||
{
|
{
|
||||||
UWingFactories* Self = GEditor->GetEditorSubsystem<UWingFactories>();
|
UWingFactories* Self = GEditor->GetEditorSubsystem<UWingFactories>();
|
||||||
@@ -74,18 +146,13 @@ UObject* UWingFactories::CreateAsset(const FString& Path, const FString& Factory
|
|||||||
return nullptr;
|
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())
|
if (!FactoryInfo->CanCreateNew())
|
||||||
{
|
{
|
||||||
UWingServer::Printf(TEXT("ERROR: Factory '%s' cannot create objects from scratch\n"), *FactoryName);
|
UWingServer::Printf(TEXT("ERROR: Factory '%s' cannot create objects from scratch\n"), *FactoryName);
|
||||||
return nullptr;
|
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.
|
// Create the factory instance.
|
||||||
UFactory* Factory = NewObject<UFactory>(GetTransientPackage(), FactoryInfo->FactoryClass);
|
UFactory* Factory = NewObject<UFactory>(GetTransientPackage(), FactoryInfo->FactoryClass);
|
||||||
|
|
||||||
@@ -101,28 +168,7 @@ UObject* UWingFactories::CreateAsset(const FString& Path, const FString& Factory
|
|||||||
if (!FWingProperty::PopulateFromJson(Props, ConfigJson.Get(), false))
|
if (!FWingProperty::PopulateFromJson(Props, ConfigJson.Get(), false))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Pre-check: block factories that would cause problems.
|
return CreateAsset(Path, Factory);
|
||||||
// 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<UFactory>()->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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UWingFactories::PreCheck(UFactory* Factory, FName Name, const FString &Path)
|
bool UWingFactories::PreCheck(UFactory* Factory, FName Name, const FString &Path)
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingTypes.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("("));
|
UWingServer::Print(TEXT("("));
|
||||||
bool bFirst = true;
|
bool bFirst = true;
|
||||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
for (TFieldIterator<FProperty> PropIt(Handler.Class.Get(), EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||||
{
|
{
|
||||||
if (!bFirst) UWingServer::Print(TEXT(","));
|
if (!bFirst) UWingServer::Print(TEXT(","));
|
||||||
bFirst = false;
|
bFirst = false;
|
||||||
@@ -18,10 +18,10 @@ void WingManual::PrintHandlerPrototype(UClass *HandlerClass)
|
|||||||
UWingServer::Print(TEXT(")\n"));
|
UWingServer::Print(TEXT(")\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingManual::PrintHandlerArguments(UClass *HandlerClass)
|
void WingManual::PrintHandlerArguments(const FWingHandlerConfig& Handler)
|
||||||
{
|
{
|
||||||
// parameter details
|
// parameter details
|
||||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
for (TFieldIterator<FProperty> PropIt(Handler.Class.Get(), EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||||
{
|
{
|
||||||
FProperty* Prop = *PropIt;
|
FProperty* Prop = *PropIt;
|
||||||
FString Name = Prop->GetName();
|
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<IWingHandler>(HandlerClass->GetDefaultObject());
|
const UWingHandler* HandlerCDO = Cast<UWingHandler>(Handler.Class->GetDefaultObject());
|
||||||
if (!Handler) return;
|
if (!HandlerCDO) return;
|
||||||
UWingServer::Print(WingUtils::WrapText(Handler->GetDescription(), 80, TEXT(" // ")));
|
UWingServer::Print(WingUtils::WrapText(HandlerCDO->GetDescription(), 80, TEXT(" // ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingManual::PrintHandlerHelp(UClass* HandlerClass)
|
void WingManual::PrintHandlerHelp(const FWingHandlerConfig& Handler)
|
||||||
{
|
{
|
||||||
UWingServer::Print(TEXT("\n"));
|
UWingServer::Print(TEXT("\n"));
|
||||||
PrintHandlerPrototype(HandlerClass);
|
PrintHandlerPrototype(Handler);
|
||||||
PrintHandlerArguments(HandlerClass);
|
PrintHandlerArguments(Handler);
|
||||||
PrintHandlerDescription(HandlerClass);
|
PrintHandlerDescription(Handler);
|
||||||
UWingServer::Print(TEXT("\n"));
|
UWingServer::Print(TEXT("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abridged)
|
void WingManual::PrintManual(TSet<Section> Sections, const FWingHandlerConfig* Handler, bool Abridged)
|
||||||
{
|
{
|
||||||
if (Sections.IsEmpty()) return;
|
if (Sections.IsEmpty()) return;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ void WingManual::PrintManual(TSet<Section> Sections, UClass *Handler, bool Abrid
|
|||||||
|
|
||||||
if (Handler && (Sections.Contains(Section::HandlerHelp) || bPrintAll))
|
if (Handler && (Sections.Contains(Section::HandlerHelp) || bPrintAll))
|
||||||
{
|
{
|
||||||
PrintHandlerHelp(Handler);
|
PrintHandlerHelp(*Handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Sections.Contains(Section::Paths) || bPrintAll)
|
if (Sections.Contains(Section::Paths) || bPrintAll)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "WingPackageMaker.h"
|
#include "WingPackageMaker.h"
|
||||||
|
#include "PackageTools.h"
|
||||||
#include "AssetRegistry/AssetRegistryModule.h"
|
#include "AssetRegistry/AssetRegistryModule.h"
|
||||||
|
|
||||||
WingPackageMaker::WingPackageMaker(const FString& InFullPath)
|
WingPackageMaker::WingPackageMaker(const FString& InFullPath)
|
||||||
@@ -13,6 +14,11 @@ WingPackageMaker::WingPackageMaker(const FString& InFullPath)
|
|||||||
|
|
||||||
bool WingPackageMaker::CheckNewAssetPath(const FString& Path)
|
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))
|
if (!FPackageName::IsValidTextForLongPackageName(Path))
|
||||||
{
|
{
|
||||||
UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path);
|
UWingServer::Printf(TEXT("ERROR: Package path '%s' is not a valid package name\n"), *Path);
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ FString UWingServer::HandleRequest(const FString& Line)
|
|||||||
LogCapture.bEnabled = true;
|
LogCapture.bEnabled = true;
|
||||||
HandlerOutput.Reset();
|
HandlerOutput.Reset();
|
||||||
SuggestedManualSections.Empty();
|
SuggestedManualSections.Empty();
|
||||||
LastHandlerClass = nullptr;
|
LastHandler = nullptr;
|
||||||
|
|
||||||
TryCallHandler(Line);
|
TryCallHandler(Line);
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ FString UWingServer::HandleRequest(const FString& Line)
|
|||||||
if (!SuggestedManualSections.IsEmpty())
|
if (!SuggestedManualSections.IsEmpty())
|
||||||
{
|
{
|
||||||
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
UWingServer::SuggestManual(WingManual::Section::HandlerHelp);
|
||||||
WingManual::PrintManual(SuggestedManualSections, LastHandlerClass, true);
|
WingManual::PrintManual(SuggestedManualSections, LastHandler, true);
|
||||||
}
|
}
|
||||||
FString Result = HandlerOutput.ToString();
|
FString Result = HandlerOutput.ToString();
|
||||||
HandlerOutput.Reset();
|
HandlerOutput.Reset();
|
||||||
@@ -312,19 +312,20 @@ void UWingServer::TryCallHandler(const FString &Line)
|
|||||||
}
|
}
|
||||||
Request->RemoveField(TEXT("command"));
|
Request->RemoveField(TEXT("command"));
|
||||||
|
|
||||||
// Find the handler UClass for the specified command.
|
// Find the handler for the specified command.
|
||||||
TObjectPtr<UClass>* HandlerClass = WingHandlerRegistry.Find(Command);
|
FWingHandlerConfig* Found = FindHandler(Command);
|
||||||
if (!HandlerClass)
|
if (!Found)
|
||||||
{
|
{
|
||||||
UWingServer::Printf(TEXT("Unknown command: %s"), *Command);
|
UWingServer::Printf(TEXT("Unknown command: %s"), *Command);
|
||||||
UWingServer::SuggestManual(WingManual::Section::ImportantCommands);
|
UWingServer::SuggestManual(WingManual::Section::ImportantCommands);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LastHandlerClass = *HandlerClass;
|
LastHandler = Found;
|
||||||
|
|
||||||
// Make an object of the handler class.
|
// Make an object of the handler class.
|
||||||
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
|
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), Found->Class.Get()));
|
||||||
IWingHandler* Handler = Cast<IWingHandler>(HandlerObj.Get());
|
UWingHandler* Handler = Cast<UWingHandler>(HandlerObj.Get());
|
||||||
|
Handler->ConfigurationObject = Found->Config.Get();
|
||||||
|
|
||||||
// Populate the handler object with the request parameters.
|
// Populate the handler object with the request parameters.
|
||||||
if (!FWingProperty::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
if (!FWingProperty::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||||
@@ -451,10 +452,39 @@ void UWingServer::ClientThreadFunc(UWingServer* Server, TSharedPtr<FClientConnec
|
|||||||
// BuildWingHandlerRegistry
|
// BuildWingHandlerRegistry
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
|
void UWingHandler::Register(UWingServer* Server)
|
||||||
|
{
|
||||||
|
UClass* Class = GetClass();
|
||||||
|
Server->AddHandler(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<UClass>(Class);
|
||||||
|
H.Config = TStrongObjectPtr<UObject>(Config);
|
||||||
|
H.Kind = Kind;
|
||||||
|
|
||||||
|
WingHandlerRegistry.Add(MoveTemp(H));
|
||||||
|
}
|
||||||
|
|
||||||
void UWingServer::BuildWingHandlerRegistry()
|
void UWingServer::BuildWingHandlerRegistry()
|
||||||
{
|
{
|
||||||
for (UClass* Class : WingUtils::CollectHandlerClasses())
|
for (UClass* Class : WingUtils::CollectHandlerClasses())
|
||||||
{
|
{
|
||||||
WingHandlerRegistry.FindOrAdd(WingUtils::GetHandlerName(Class)) = Class;
|
UWingHandler* CDO = Cast<UWingHandler>(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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ TArray<UClass*> WingUtils::CollectHandlerClasses()
|
|||||||
{
|
{
|
||||||
UClass* Class = *It;
|
UClass* Class = *It;
|
||||||
if (Class->HasAnyClassFlags(CLASS_Abstract)) continue;
|
if (Class->HasAnyClassFlags(CLASS_Abstract)) continue;
|
||||||
if (!Class->ImplementsInterface(UWingHandler::StaticClass())) continue;
|
if (!Class->IsChildOf(UWingHandler::StaticClass())) continue;
|
||||||
Result.Add(Class);
|
Result.Add(Class);
|
||||||
}
|
}
|
||||||
Result.Sort([](UClass& A, UClass& B) { return GetHandlerName(&A) < GetHandlerName(&B); });
|
Result.Sort([](UClass& A, UClass& B) { return GetHandlerName(&A) < GetHandlerName(&B); });
|
||||||
|
|||||||
@@ -26,17 +26,22 @@ public:
|
|||||||
|
|
||||||
static const TArray<Info>& AllFactories();
|
static const TArray<Info>& 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.
|
// 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:
|
private:
|
||||||
TArray<Info> Registry;
|
TArray<Info> Registry;
|
||||||
|
|
||||||
Info* Find(const FString& Name);
|
Info* Find(const FString& Name);
|
||||||
|
static UPackage *CreateNewPackage(const FString &Path);
|
||||||
|
static bool CheckNewAssetPath(const FString &Path);
|
||||||
void PopulateRegistry();
|
void PopulateRegistry();
|
||||||
void DisableFactory(const TCHAR* Name);
|
void DisableFactory(const TCHAR* Name);
|
||||||
static bool PreCheck(UFactory *Factory, FName Name, const FString &Path);
|
static bool PreCheck(UFactory *Factory, FName Name, const FString &Path);
|
||||||
static FString DeriveFactoryName(UClass* FactoryClass);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "UObject/Interface.h"
|
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
|
#include "UObject/StrongObjectPtr.h"
|
||||||
#include "Dom/JsonObject.h"
|
#include "Dom/JsonObject.h"
|
||||||
#include "WingHandler.generated.h"
|
#include "WingHandler.generated.h"
|
||||||
|
|
||||||
@@ -24,32 +24,40 @@ struct FWingJsonArray
|
|||||||
TArray<TSharedPtr<FJsonValue>> Array;
|
TArray<TSharedPtr<FJsonValue>> Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Interface for self-registering MCP tool handlers.
|
class UWingServer;
|
||||||
//
|
|
||||||
// Implementing classes declare their parameters as UPROPERTY fields, which are
|
UENUM()
|
||||||
// automatically populated from the incoming JSON request and used to
|
enum class EWingHandlerKind
|
||||||
// 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
|
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
Normal,
|
||||||
|
Create
|
||||||
};
|
};
|
||||||
|
|
||||||
class UEWINGMAN_API IWingHandler
|
USTRUCT()
|
||||||
|
struct FWingHandlerConfig
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
FString Name;
|
||||||
|
TStrongObjectPtr<UClass> Class;
|
||||||
|
TStrongObjectPtr<UObject> Config;
|
||||||
|
EWingHandlerKind Kind = EWingHandlerKind::Normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS(Abstract)
|
||||||
|
class UEWINGMAN_API UWingHandler : public UObject
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Human-readable tool description for MCP tools/list.
|
// 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.
|
// Called after parameter fields have been populated from JSON.
|
||||||
virtual void Handle() {}
|
virtual void Handle() {}
|
||||||
|
|
||||||
|
// The configuration object.
|
||||||
|
UObject *ConfigurationObject;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Containers/Set.h"
|
#include "Containers/Set.h"
|
||||||
|
#include "WingHandler.h"
|
||||||
|
|
||||||
class WingManual
|
class WingManual
|
||||||
{
|
{
|
||||||
@@ -17,9 +18,9 @@ public:
|
|||||||
ImportantCommands,
|
ImportantCommands,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void PrintHandlerPrototype(UClass *Handler);
|
static void PrintHandlerPrototype(const FWingHandlerConfig& Handler);
|
||||||
static void PrintHandlerArguments(UClass *Handler);
|
static void PrintHandlerArguments(const FWingHandlerConfig& Handler);
|
||||||
static void PrintHandlerDescription(UClass *Handler);
|
static void PrintHandlerDescription(const FWingHandlerConfig& Handler);
|
||||||
static void PrintHandlerHelp(UClass *Handler);
|
static void PrintHandlerHelp(const FWingHandlerConfig& Handler);
|
||||||
static void PrintManual(TSet<Section> Sections, UClass *Handler, bool Abridged);
|
static void PrintManual(TSet<Section> Sections, const FWingHandlerConfig* Handler, bool Abridged);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingNotifier.h"
|
#include "WingNotifier.h"
|
||||||
#include "WingLogCapture.h"
|
#include "WingLogCapture.h"
|
||||||
|
#include "WingHandler.h"
|
||||||
#include "WingManual.h"
|
#include "WingManual.h"
|
||||||
#include "WingServer.generated.h"
|
#include "WingServer.generated.h"
|
||||||
|
|
||||||
@@ -72,19 +73,22 @@ public:
|
|||||||
/** Port the server is listening on. */
|
/** Port the server is listening on. */
|
||||||
int32 GetPort() const { return Port; }
|
int32 GetPort() const { return Port; }
|
||||||
|
|
||||||
|
// ----- Tool dispatch -----
|
||||||
|
void AddHandler(const FString& Name, UClass* Class, UObject* Config, EWingHandlerKind Kind);
|
||||||
|
static const TArray<FWingHandlerConfig>& AllHandlers() { return GWingServer->WingHandlerRegistry; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static UWingServer* GWingServer;
|
static UWingServer* GWingServer;
|
||||||
|
|
||||||
// ----- Tool dispatch -----
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FWingNotifier Notifier;
|
FWingNotifier Notifier;
|
||||||
UClass* LastHandlerClass;
|
FWingHandlerConfig* LastHandler;
|
||||||
TStringBuilder<16384> HandlerOutput;
|
TStringBuilder<16384> HandlerOutput;
|
||||||
TSet<WingManual::Section> SuggestedManualSections;
|
TSet<WingManual::Section> SuggestedManualSections;
|
||||||
FLogCaptureOutputDevice LogCapture; // installed once at startup, enabled per-request
|
FLogCaptureOutputDevice LogCapture; // installed once at startup, enabled per-request
|
||||||
UPROPERTY()
|
TArray<FWingHandlerConfig> WingHandlerRegistry; // sorted by Name
|
||||||
TMap<FString, TObjectPtr<UClass>> WingHandlerRegistry; // tool name -> UWingHandler subclass
|
|
||||||
void BuildWingHandlerRegistry();
|
void BuildWingHandlerRegistry();
|
||||||
|
FWingHandlerConfig* FindHandler(const FString& Name);
|
||||||
|
|
||||||
// Handle a complete JSON line and return the response JSON
|
// Handle a complete JSON line and return the response JSON
|
||||||
FString HandleRequest(const FString& Line);
|
FString HandleRequest(const FString& Line);
|
||||||
|
|||||||
Reference in New Issue
Block a user