Files
integration/Plugins/UEWingman/Source/UEWingman/Public/WingBasics.h

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;
};