Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
 All Forums
 Visual Assist
 Feature Requests
 ImplementVirtualMethods from UE4 style interfaces

You must be registered to post a reply.
Click here to register.

Screensize:
UserName:
Password:
Format: BoldItalicizeUnderlineStrikethrough Align leftCenterAlign right Insert horizontal ruleUpload and insert imageInsert hyperlinkInsert email addressInsert codeInsert quoted textInsert listInsert Emoji
   
Message:

Forum code is on.
Html is off.

 
Check to subscribe to this topic.
   

T O P I C    R E V I E W
korku Posted - Jun 27 2018 : 4:45:53 PM
Hi.

When creating a UE4 UInterface (such that C++ classes can derive the I<InterfaceName> class, and BP can "implement" the U<InterfaceName>), if you specify any of the UFUNCTIONs as BlueprintNative you cannot implement them with this tool.



#include "NoExportTypes.h"
#include "Filename.generated.h"

UINTERFACE()
class UMyInterface : public UInterface
{
	GENERATED_BODY()
};

class IMyInterface
{
	GENERATED_IINTERFACE_BODY() // @note: this macro has to be IINTERFACE_BODY, it cannot be GENERATED_BODY;

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void TestFunction(UObject* InParam);
	// virtual void TestFunction_Implementation(UObject* InParam); // @note: you can't declare this yourself - UHT will unconditionally generate the below line
	// virtual void TestFunction_Implementation(UObject* InParam)=0;
};

// elsewhere, or even in the same file

UCLASS()
class UMyTestObject : public UObject, public IMyInterface
{
	GENERATED_BODY()
};


Placing your cursor over IMyInterface in UMyTestObject's declaration and invoking ImplementVirtualMethods will result in Visual Assist not finding the virtual functions from IMyInterface.

Suggestion - generate a commented out declaration such as in my example rather than or alongside an implementation body in the source; granted a method body makes zero sense here as the function is declared pure virtual. Tangentially, it'd be nice to have the declaration for Validate and Implementation functions generated when their bodies are generated via CreateImplementation (if Validate is automatically generated for Server RPCs, and this isn't the default behavior).
5   L A T E S T    R E P L I E S    (Newest First)
sean Posted - Sep 24 2018 : 2:27:36 PM
case=117506 is implemented in build 2291.
korku Posted - Jun 30 2018 : 2:29:38 PM
Indeed.
accord Posted - Jun 30 2018 : 2:06:16 PM
Thank you for the detailed explanation. I have put in a feature request to support UFUNCTIONs:

case=117506

Your detailed description will surely help when implementing this.

So in your case the expected method to list would be TestFunction_Implementation, right?
korku Posted - Jun 28 2018 : 1:15:37 PM
UFUNCTION acts as a marker for UHT, and you can provide specifiers to control the output that'll be generated. The `GENERATED_BODY` class of macros all do basically the same thing, with some minor differences.

At a minimum, UFUNCTION will register the function into a lookup table so that you can get a function ptr by knowing its textual name.

BlueprintNativeEvent will cause the UFUNCTION's normal definition to be replaced by a wrapper which dispatches the call dynamically either to the blueprint implementation or the C++ `FuncName_Implementation`. This specifier will expect the original declaration to be non-virtual, and the `_Implementation` to be virtual. All of the BlueprintNativeEvents have virtual `_Implementation` versions declared in the `filename.generated.h`, and those decls will appear all in one block which occurs a few times.

BlueprintCallable allows it to appear in the list of functions when scripting in Blueprint - BlueprintPure would as well.

Another specifier to be aware of is `UFUNCTION(Server)` - this specifier MUST be accompanied with either `Unreliable` or `Reliable` along with `WithValidation` (though maybe you can turn this off). WithValidation will cause `virtual bool FuncName_Validate($MethodArgs$);` to be declared along with the rest of the generated function declarations. The normal definition of the function will be replaced with a generated RPC and then Validate is used for... well... Validation.

All of the generated body macros will include ctors, dtors, along with a few functions used by the reflection layer. So, as for GENERATED_IINTERFACE_BODY - its special in that its generated virtual functions are declared as pure virtual.

In case the answers to your questions got lost in there.

No, UFUNCTIONs with specifiers usually aren't virtual - though more basic UFUNCTIONs can be. Where a UFUNCTION cannot be virtual, a `virtual rType FuncName_Implementation($MethodArgs$);` is implicitly declared in the generated header (actually will occur on the line of GENERATED_BODY, ofc) and defining the body of such a UFUNCTION (eg `void ClassName::FuncName(){}`) is invalid. In the case of IINTERFACE, Epic choose to enforce a wholly abstract interface and the generated declarations are pure virtual.

You can observe this yourself if you have a UE4 environment ready to go and you build my example - I didn't include several includes you would need to drop this file in and build - so let me do that (I'll edit).

If you decide to dig around in the generated header, you might also be interested in the `FileName.gen.cpp` that will be in the same dir as the generated.h.
accord Posted - Jun 28 2018 : 12:04:37 AM
I'm not familiar with Unreal Engine. I tried to understand the role of UFUNCTION and GENERATED_IINTERFACE_BODY but didn't find a good entry-level description of them.

So my question: are UFUNCTIONs always virtual? So in other words, do you expect implement virtual methods to find TestFunction?

Next question: what methods generated via the macro GENERATED_IINTERFACE_BODY? Are there any virtual ones that you would expect implement virtual methods to pick up?

© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000