Remove stringbuilder parameter for handlers
This commit is contained in:
@@ -260,57 +260,17 @@ TStatId UMCPServer::GetStatId() const
|
||||
|
||||
FString UMCPServer::HandleRequest(const FString& Line)
|
||||
{
|
||||
// Turn the request string into a JSON tree.
|
||||
TSharedPtr<FJsonObject> Request;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Line);
|
||||
FJsonSerializer::Deserialize(Reader, Request);
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
return TEXT("Request is not valid JSON");
|
||||
}
|
||||
|
||||
// Extract the command from the request.
|
||||
FString Command;
|
||||
if (!Request->TryGetStringField(TEXT("command"), Command))
|
||||
{
|
||||
return TEXT("Request does not contain 'command' parameter");
|
||||
}
|
||||
Request->RemoveField(TEXT("command"));
|
||||
|
||||
// Find the handler UClass for the specified command.
|
||||
UClass** HandlerClass = MCPHandlerRegistry.Find(Command);
|
||||
if (!HandlerClass)
|
||||
{
|
||||
return FString::Printf(TEXT("Unknown command: %s"), *Command);
|
||||
}
|
||||
|
||||
// Make an object of the handler class.
|
||||
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
|
||||
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
||||
|
||||
// Populate the handler object with the request parameters.
|
||||
HandlerOutput.Reset();
|
||||
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||
{
|
||||
HandlerOutput.Append(TEXT("\nUsage:\n"));
|
||||
MCPUtils::FormatCommandHelp(*HandlerClass, HandlerOutput);
|
||||
FString Result = HandlerOutput.ToString();
|
||||
HandlerOutput.Reset();
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Invoke the handler with log capture.
|
||||
LogCapture.CapturedErrors.Empty();
|
||||
LogCapture.bEnabled = true;
|
||||
HandlerOutput.Reset();
|
||||
Handler->Handle(HandlerOutput);
|
||||
|
||||
TryCallHandler(Line);
|
||||
|
||||
Notifier.SendNotifications();
|
||||
LogCapture.bEnabled = false;
|
||||
for (const FString& Msg : LogCapture.CapturedErrors)
|
||||
{
|
||||
HandlerOutput.Append(TEXT("LOG: "));
|
||||
HandlerOutput.Append(Msg);
|
||||
HandlerOutput.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT("UE_LOG: %s\n"), *Msg);
|
||||
}
|
||||
LogCapture.CapturedErrors.Empty();
|
||||
FString Result = HandlerOutput.ToString();
|
||||
@@ -322,6 +282,51 @@ FString UMCPServer::HandleRequest(const FString& Line)
|
||||
return Result;
|
||||
}
|
||||
|
||||
void UMCPServer::TryCallHandler(const FString &Line)
|
||||
{
|
||||
// Turn the request string into a JSON tree.
|
||||
TSharedPtr<FJsonObject> Request;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Line);
|
||||
FJsonSerializer::Deserialize(Reader, Request);
|
||||
if (!Request.IsValid())
|
||||
{
|
||||
UMCPServer::Printf(TEXT("Request is not valid JSON"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract the command from the request.
|
||||
FString Command;
|
||||
if (!Request->TryGetStringField(TEXT("command"), Command))
|
||||
{
|
||||
UMCPServer::Printf(TEXT("Request does not contain 'command' parameter"));
|
||||
return;
|
||||
}
|
||||
Request->RemoveField(TEXT("command"));
|
||||
|
||||
// Find the handler UClass for the specified command.
|
||||
UClass** HandlerClass = MCPHandlerRegistry.Find(Command);
|
||||
if (!HandlerClass)
|
||||
{
|
||||
UMCPServer::Printf(TEXT("Unknown command: %s"), *Command);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make an object of the handler class.
|
||||
TStrongObjectPtr<UObject> HandlerObj(NewObject<UObject>(GetTransientPackage(), *HandlerClass));
|
||||
IMCPHandler* Handler = Cast<IMCPHandler>(HandlerObj.Get());
|
||||
|
||||
// Populate the handler object with the request parameters.
|
||||
if (!MCPUtils::PopulateFromJson(HandlerObj->GetClass(), HandlerObj.Get(), &*Request))
|
||||
{
|
||||
UMCPServer::Printf(TEXT("\nUsage:\n\n"));
|
||||
MCPUtils::FormatCommandHelp(*HandlerClass);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the handler.
|
||||
Handler->Handle();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Connection Maintenance
|
||||
// ============================================================
|
||||
|
||||
@@ -813,7 +813,7 @@ bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialPa
|
||||
return true;
|
||||
}
|
||||
|
||||
void MCPUtils::FormatMaterialParameter(FStringBuilderBase& Result, const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
||||
void MCPUtils::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
||||
{
|
||||
// Association prefix for layer/blend parameters.
|
||||
FString Prefix;
|
||||
@@ -825,35 +825,35 @@ void MCPUtils::FormatMaterialParameter(FStringBuilderBase& Result, const FMateri
|
||||
switch (Meta.Value.Type)
|
||||
{
|
||||
case EMaterialParameterType::Scalar:
|
||||
Result.Appendf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
||||
UMCPServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
||||
break;
|
||||
case EMaterialParameterType::Vector:
|
||||
{
|
||||
FLinearColor C = Meta.Value.AsLinearColor();
|
||||
Result.Appendf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
|
||||
UMCPServer::Printf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
|
||||
*Prefix, *Info.Name.ToString(), C.R, C.G, C.B, C.A);
|
||||
break;
|
||||
}
|
||||
case EMaterialParameterType::DoubleVector:
|
||||
{
|
||||
FVector4d V = Meta.Value.AsVector4d();
|
||||
Result.Appendf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
||||
UMCPServer::Printf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
||||
*Prefix, *Info.Name.ToString(), V.X, V.Y, V.Z, V.W);
|
||||
break;
|
||||
}
|
||||
case EMaterialParameterType::Texture:
|
||||
{
|
||||
UTexture* Tex = Cast<UTexture>(Meta.Value.AsTextureObject());
|
||||
Result.Appendf(TEXT(" %sTexture \"%s\" = %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
|
||||
*Prefix, *Info.Name.ToString(), Tex ? *MCPUtils::FormatName(Tex) : TEXT("None"));
|
||||
break;
|
||||
}
|
||||
case EMaterialParameterType::StaticSwitch:
|
||||
Result.Appendf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
||||
UMCPServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
||||
*Prefix, *Info.Name.ToString(), Meta.Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"));
|
||||
break;
|
||||
default:
|
||||
Result.Appendf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
||||
UMCPServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1398,29 +1398,29 @@ TArray<FProperty*> MCPUtils::SearchProperties(UObject* Obj, const FString& Query
|
||||
// FormatCommandHelp — verbose description of one handler command
|
||||
// ============================================================
|
||||
|
||||
void MCPUtils::FormatCommandHelp(UClass* HandlerClass, FStringBuilderBase& Result)
|
||||
void MCPUtils::FormatCommandHelp(UClass* HandlerClass)
|
||||
{
|
||||
const IMCPHandler* Handler = Cast<IMCPHandler>(HandlerClass->GetDefaultObject());
|
||||
if (!Handler) return;
|
||||
|
||||
FString ToolName = GetHandlerName(HandlerClass);
|
||||
|
||||
Result.Append(TEXT("\n"));
|
||||
Result.Append(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
UMCPServer::Print(WrapText(Handler->GetDescription(), 80, TEXT("// ")));
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
|
||||
// Command signature line
|
||||
Result.Append(ToolName);
|
||||
Result.Append(TEXT("("));
|
||||
UMCPServer::Print(ToolName);
|
||||
UMCPServer::Print(TEXT("("));
|
||||
bool bFirst = true;
|
||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||
{
|
||||
if (!bFirst) Result.Append(TEXT(","));
|
||||
if (!bFirst) UMCPServer::Print(TEXT(","));
|
||||
bFirst = false;
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) Result.Append(TEXT("?"));
|
||||
Result.Append(PropertyNameToJsonKey(PropIt->GetName()));
|
||||
if (PropIt->HasMetaData(TEXT("Optional"))) UMCPServer::Print(TEXT("?"));
|
||||
UMCPServer::Print(PropertyNameToJsonKey(PropIt->GetName()));
|
||||
}
|
||||
Result.Append(TEXT(")\n"));
|
||||
UMCPServer::Print(TEXT(")\n"));
|
||||
|
||||
// parameter details
|
||||
for (TFieldIterator<FProperty> PropIt(HandlerClass, EFieldIterationFlags::None); PropIt; ++PropIt)
|
||||
@@ -1431,10 +1431,10 @@ void MCPUtils::FormatCommandHelp(UClass* HandlerClass, FStringBuilderBase& Resul
|
||||
bool bOptional = Prop->HasMetaData(TEXT("Optional"));
|
||||
const FString& Desc = Prop->GetMetaData(TEXT("Description"));
|
||||
|
||||
Result.Appendf(TEXT(" %s %s%s"),
|
||||
UMCPServer::Printf(TEXT(" %s %s%s"),
|
||||
*Type, *Name, bOptional ? TEXT(" (optional)") : TEXT(""));
|
||||
if (!Desc.IsEmpty())
|
||||
Result.Appendf(TEXT(" — %s"), *Desc);
|
||||
Result.Append(TEXT("\n"));
|
||||
UMCPServer::Printf(TEXT(" — %s"), *Desc);
|
||||
UMCPServer::Print(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user