190 lines
4.9 KiB
C++
190 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "UObject/Object.h"
|
|
#include "UObject/StrongObjectPtr.h"
|
|
#include "WingBasics.generated.h"
|
|
|
|
class UEdGraphNode;
|
|
class UEdGraphPin;
|
|
class UBlueprint;
|
|
class FJsonObject;
|
|
class FJsonValue;
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//
|
|
// Handlers.
|
|
//
|
|
// Each command supported by the MCP is implemented by a
|
|
// 'handler'. The server receives the request, which
|
|
// contains a command. The server looks up the right
|
|
// handler class for the command, and creates a handler
|
|
// object. Using reflection, it inserts the command
|
|
// parameters into uproperty fields of the handler, then
|
|
// calls the handle method, which executes the command.
|
|
//
|
|
////////////////////////////////////////////////////////////
|
|
|
|
UENUM()
|
|
enum class EWingHandlerKind
|
|
{
|
|
Normal,
|
|
Create
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FWingHandlerConfig
|
|
{
|
|
GENERATED_BODY()
|
|
FString Name;
|
|
FString Documentation;
|
|
TStrongObjectPtr<UClass> HandlerClass;
|
|
TStrongObjectPtr<UObject> Config;
|
|
TStrongObjectPtr<UClass> FactoryClass;
|
|
EWingHandlerKind Kind = EWingHandlerKind::Normal;
|
|
};
|
|
|
|
UCLASS(Abstract)
|
|
class UEWINGMAN_API UWingHandler : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// Register this handler's commands with the server.
|
|
virtual void Register() PURE_VIRTUAL(UWingHandler::Register);
|
|
|
|
// Called after parameter fields have been populated from JSON.
|
|
virtual void Handle() {}
|
|
|
|
// The configuration object.
|
|
FWingHandlerConfig *Configuration;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//
|
|
// A simple type to store the remaining arguments in
|
|
// an Argv Array.
|
|
//
|
|
////////////////////////////////////////////////////////////
|
|
|
|
USTRUCT()
|
|
struct FWingRestOfArgv
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY()
|
|
TArray<FString> Argv;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//
|
|
// WingOut.
|
|
//
|
|
// A thin wrapper around unreal string builders. Handlers
|
|
// put their output into a WingOut (string builder), which
|
|
// eventually gets forwarded to the agent. This output
|
|
// buffer is called WingOut::Stdout.
|
|
//
|
|
// Subroutines that can generate error messages take a
|
|
// parameter 'WingOut Errors', a string builder where they
|
|
// can put the error message. Unlike a raw string builder,
|
|
// a WingOut can be nullptr, which is useful if you want to
|
|
// ignore error messages from certain subroutines. You can
|
|
// also direct error messages directly to WingOut::Stdout.
|
|
//
|
|
////////////////////////////////////////////////////////////
|
|
|
|
class WingOut
|
|
{
|
|
public:
|
|
WingOut(FStringBuilderBase *O) : Buffer(O) {}
|
|
WingOut(FStringBuilderBase &O) : Buffer(&O) {}
|
|
static WingOut Stdout;
|
|
static WingOut None;
|
|
|
|
void PrintChar(TCHAR Ch) { if (Buffer) Buffer->AppendChar(Ch); }
|
|
void Print(const TCHAR* Text) { if (Buffer) Buffer->Append(Text); }
|
|
void Print(const FString& Text) { if (Buffer) Buffer->Append(Text); }
|
|
template <typename FmtType, typename... ArgTypes>
|
|
void Printf(const FmtType& Fmt, ArgTypes&&... Args)
|
|
{ if (Buffer) Buffer->Appendf(Fmt, Forward<ArgTypes>(Args)...); }
|
|
|
|
static TStringBuilder<65536> StdoutBuffer;
|
|
|
|
private:
|
|
FStringBuilderBase *Buffer;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//
|
|
// References.
|
|
//
|
|
// The MCP has a variety of operations that can manipulate
|
|
// any object, including: actors, components, graphs, graph
|
|
// nodes, graph pins, widgets, and so forth. For example,
|
|
// the agent can request a 'details panel' for any of these.
|
|
//
|
|
// However, some of those objects aren't UObjects. This
|
|
// makes it awkward to write code that deals with them
|
|
// uniformly. To homogenize them, we turn them all into
|
|
// UObjects by creating wrappers for those that aren't.
|
|
//
|
|
// Some things that you would think are UObjects, like
|
|
// components, are actually only UObjects at runtime.
|
|
// When a blueprint is still being edited, the component
|
|
// is represented by a bunch of related data structures
|
|
// inside the blueprint. At that time, there is no one
|
|
// UObject to point to as 'the component.'
|
|
//
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Pin Ref: A pointer to a graph node, plus a pin name.
|
|
UCLASS()
|
|
class UWingGraphPinRef : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UPROPERTY()
|
|
UEdGraphNode* Node = nullptr;
|
|
|
|
FName PinName;
|
|
};
|
|
|
|
// Component Ref: A pointer to a blueprint plus a component
|
|
// name. The component can be an inherited component, as
|
|
// opposed to one that is defined in the blueprint itself.
|
|
UCLASS()
|
|
class UWingComponentRef : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
public:
|
|
UPROPERTY()
|
|
UBlueprint* BP = nullptr;
|
|
|
|
// The component name.
|
|
FName VariableName;
|
|
};
|
|
|
|
// Struct Ref: A pointer to an object, and a struct inside
|
|
// that object. The editable flag indicates whether the
|
|
// struct is marked CPF_Edit. If not, then the intent is
|
|
// that this struct is for viewing only.
|
|
UCLASS()
|
|
class UWingStructRef : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
public:
|
|
UPROPERTY()
|
|
UObject* Object;
|
|
|
|
void *StructBase;
|
|
|
|
UPROPERTY()
|
|
UStruct* StructType;
|
|
|
|
bool Editable;
|
|
};
|
|
|