Getting owner who implements an interface from within interface

I writing an interface for my save system in c++. I wanted to know if there was a way to get the UObject that’s implementing the interface when an interface function is called.

I can of course do something like this in cpp.

void IMySaveSystem::Save(UObject* ObjectToSave)
{
 //Saving Logic
}

But I was wondering if maybe there was a way I could guarantee that the object being passed is the Object implementing the interface that the function is being called on.

I do have a subsystem, so I could remove the interface and let objects save via the subsystem, but the interface is just so clean.

It does seem silly to have to implement the same logic for each class with the interface to pass in a reference to themselves every time I setup the interface.

I’m thinking of adding an actor component that has a defined implementation of this interface to standardize it for actors, but I do want it compatible down to the object level also not just for actors.

Open to suggestions!

So I’m a bit confused?

You’re asking if there is a way to send a reference of the interface holder, to said interface holder.

The point of an interface is just to guarantee that certain functions will be there, you still have to create the function on each object type that implements your interface.

Interface ISomeInterface
→ ISomeInterface::SomeInterfaceFunction

Class SomeClass1: ISomeInterface
→ SomeClass1::SomeInterfaceFunction → You still have to write this, and you know
you are a SomeClass1

Class SomeClass2: ISomeInterface
→ SomeClass2::SomeInterfaceFunction → You still have to write this one too, and
you know you are a SomeClass2

You may be more interested in abstract classes where some of the logic is in the base abstract class, and more of it goes in the derived class. Not sure how exactly you are trying to do what you’re doing.

Yeah essentially I wanted to know if you could do something like GetOwner() within the interface class itself. Technically at some point the interface is instance as a subclass of UObject and it’s outer will be the Object implementing the interface.

Then I just wanted a c++ default implementation of a virtual function within the interface where I could always call Save() with no arguments and get the object reference of the interface owner automatically.

IE the implemtation of save is something like/

void ISaveInterface::Save()
{
 //Get subsystem reference
 // Subsystem->Save(GetOwnerOfInterface()); 
}

I maybe wasn’t so clear about that in my original question.

I do realize I can just have all object that want to save access the subsystem function directly. But I like having the ability of checking which object are “saveable” via implementation of the interface.

I do realize this. And a workaround for actors is that I implement a component which implements the interface in the way I want it to. but not every system in unreal can compose like actors (with components) so for lower level UObject derived classes I’d like to avoid making a SaveObject class like USaveGame system does to wrap all the functionality via inheritance.

There is the GetOuter() function. Maybe that would work?

I’m assuming that Interface is a UObject casted to the type of interface? That’s kinda defeats the purpose of what I was trying to do.

IE what you have is

void Save(UObject* Object) //This function is just in some class somewhere
{
 if(ISomeInterface* Interface = Cast<ISomeInterface>(Object))
   {
      Interface->Save(Interface->GetOuter());
      // Interface->Save(Object); //The exact same thing as above
   }
}

And the function is the interface looks like this

void ISomeInterface::Save(UObject* Object)
{
   //Do save logic
}

But really I’d like the interface to be able to do this so I can always ensure I’m using the owner of the interface as the object being saved, but I don’t think that’s possible.

void ISomeInterface::Save()
{
    if(UObject* ObjectToSave = GetOuter())
    {
        //Do save logic
    }

}

Just to clarify to, these are not blueprint visible functions in the interface.

No, I have it set up as this.

No matter how much I think about it, this is exactly what you’re asking for:

Edit: It should be this for the save everything function:

2 Likes

There should be a _getUObject() function that’s automatically generated by Unreal Header Tool. It’s hidden behind the GENERATED_BODY() macro of the ITestInterface or ISaveInterface class. It looks like this virtual UObject* _getUObject() const { check(0 && "Missing required implementation."); return nullptr; } and will also be overridden automatically by the classes that implement the interface.

2 Likes

That is certainly it. I’m using resharper and relied too heavily on the auto-generated options without ever actually compiling, I believe I tried typing out something similar before posting. I was missing _getUObject().

Anyways, this is exactly what I was looking for, thank you!

Thank you for the clarification!

Actually one more thing if you’re planning to have blueprint classes implementing this interface. I’m not entirely certain but I don’t think it’s possible that the _getUObject is overridden for those (since there’s no GENERATED_BODY() where it could be overridden). So unless you have a native class that already implements the interface in C++ calling _getUObject on an object that only implements the interface in blueprint may not work (i.e. fails the check). You may be able to work around that by using TScriptInterface which has pointers for both the UObject and the interface.

1 Like

I tested just inheriting from AActor in blueprints with the issue you listed. I’ll post my code if I get it working for blueprints for future readers.

EDIT:
This is not possible to do for blueprint generated classes. You will not be able to call a virtual function for a blueprint generated class defining the interface via blueprints. The reason is because interfaces declared in blueprints are constructed from the default object of the interface in the engine. This default object has a vtable and thus the virtual function is findable. But interfaces declared in blueprints only generate UFUNCTION declared functions for the class because that code can be generated.

So while you can call blueprint interface functions from c++ that are declared UFUNCTION with UObject::ProcessEvent or Execute_FunctionName from the object reference, you will not be able to call a virtual interface function unless it is inherited by the class in code.

2 Likes