Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with Generating code for Unreal Engine and GRPC [C++, MSVC 2017, Windows, master] #4469

Closed
fire opened this issue Oct 23, 2017 · 7 comments
Labels

Comments

@fire
Copy link

fire commented Oct 23, 2017

Unreal engine has special macros for implementing instance method access.

How would I put this code generation in flat buffers and grpc?

Here is an example UE4 class.

//////////////////////////////////////////////////////////////////////////
// Base class for mobile units (soldiers)

#include "StrategyTypes.h"
#include "StrategyChar.generated.h"

UCLASS(Abstract)
class AStrategyChar : public ACharacter, public IStrategyTeamInterface
{
	GENERATED_UCLASS_BODY()

	/** How many resources this pawn is worth when it dies. */
	UPROPERTY(EditAnywhere, Category=Pawn)
	int32 ResourcesToGather;

	/** set attachment for weapon slot */
	UFUNCTION(BlueprintCallable, Category=Attachment)
	void SetWeaponAttachment(class UStrategyAttachment* Weapon);

	UFUNCTION(BlueprintCallable, Category=Attachment)
	bool IsWeaponAttached();

	protected:

	/** melee anim */
	UPROPERTY(EditDefaultsOnly, Category=Pawn)
	UAnimMontage* MeleeAnim;

	/** Armor attachment slot */
	UPROPERTY()
	UStrategyAttachment* ArmorSlot;

	/** team number */
	uint8 MyTeamNum;

	[more code omitted]
};

https://www.unrealengine.com/en-US/blog/unreal-property-system-reflection

Given the example greeter https://github.com/google/flatbuffers/blob/master/grpc/samples/greeter/greeter.fbs

It would probably look something like

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FHelloReplyDelegate, FHelloReply );


USTRUCT()
struct FHelloReply : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString message;
}

USTRUCT()
struct FHelloRequest : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString name;
}

USTRUCT()
struct FManyHellosRequest : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString name;
        UPROPERTY()
        uint8 num_greetings;
}

UCLASS()
class UGreeterBlueprintLibrary:
    public UBlueprintFunctionLibrary
{
    GENERATED_UCLASS_BODY()
    UFUNCTION(BlueprintCallable, Category="Greeter")
    static HelloReply SayHello(HelloRequest Hello);

    UFUNCTION(BlueprintCallable, Category="Greeter")
    // Requests the user to provide a callback  delegate
    // Returns 0 if Callback is not bound
    static int32 SayManyHellos(ManyHellosRequest Hello, FHelloReplyDelegate Callback); 
}

// Implement C++

Note that the coding standard for UE4 says that variables and functions should be PascalCased.

Edit #1: Changed from class to struct.
Edit #2: Added prefix to struct names.
Edit #3: Add delegate

@aardappel
Copy link
Collaborator

I'm not entirely sure what you're asking.

First, for the actual request/response messages, those will need to be in FlatBuffer format, so there is no automatic way to create those from a UObject / UProperties currently. You'll have to write code to construct a FlatBuffer from whatever is in your game objects explicitly.

For the client, there is no class structure requirement, you can put the code that creates a request wherever you want, including presumably inside these Unreal classes.

For the server, you need to inherit from the generated interface (in the sample case that is Greeter::Service, and implement the methods with the same interface. It may be possible to use multiple inheritance to add this directly to an Unreal class, but if not, you may be better of with a seperate server implementation that then calls into the apropriate Unreal classes afterwards.

@fire
Copy link
Author

fire commented Oct 23, 2017

Sorry for not being clear. I want to generate a wrapper for

table HelloReply {
  message:string;
}

table HelloRequest {
  name:string;
}

table ManyHellosRequest {
  name:string;
  num_greetings:int;
}

rpc_service Greeter {
  SayHello(HelloRequest):HelloReply;
  SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
}

and convert it to something like:

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FHelloReplyDelegate, FHelloReply );


USTRUCT()
struct FHelloReply : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString message;
}

USTRUCT()
struct FHelloRequest : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString name;
}

USTRUCT()
struct FManyHellosRequest : public UObject
{
	GENERATED_UCLASS_BODY()
        UPROPERTY()
        UString name;
        UPROPERTY()
        uint8 num_greetings;
}

UCLASS()
class UGreeterBlueprintLibrary:
    public UBlueprintFunctionLibrary
{
    GENERATED_UCLASS_BODY()
    UFUNCTION(BlueprintCallable, Category="Greeter")
    static HelloReply SayHello(HelloRequest Hello);

    UFUNCTION(BlueprintCallable, Category="Greeter")
    // Requests the user to provide a callback  delegate
    // Returns 0 if Callback is not bound
    static int32 SayManyHellos(ManyHellosRequest Hello, FHelloReplyDelegate Callback); 
}

// Implementation ...

This should be possible to do within the flatc executable.

@fire
Copy link
Author

fire commented Oct 23, 2017

Where should I place this code to generate the wrappers?

@fire
Copy link
Author

fire commented Oct 23, 2017

@aardappel
Copy link
Collaborator

That file is verbatim from the gRPC project.. to modify it, you'd make a PR with them first I guess. Not sure if they'd welcome an Unreal specific code generator.

What is ugly about it?

Instead you may want to just add an Unreal specific generator to FlatBuffers. Have a look to see how all the current generators work to get some inspiration for how to do that.

@stale
Copy link

stale bot commented Jul 27, 2019

This issue has been automatically marked as stale because it has not had activity for 1 year. It will be automatically closed if no further activity occurs. To keep it open, simply post a new comment. Maintainers will re-open on new activity. Thank you for your contributions.

@stale stale bot added the stale label Jul 27, 2019
@fire
Copy link
Author

fire commented Jul 27, 2019

I've stopped using ue4.

@fire fire closed this as completed Jul 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants