Skip to content

Files

Latest commit

Oct 12, 2021
37a7a1b · Oct 12, 2021

History

History
132 lines (106 loc) · 3.34 KB

interfaces.md

File metadata and controls

132 lines (106 loc) · 3.34 KB

Interfaces

Flax Scripting API supports using interfaces on classes to splitting unrelated functionality into separate interfaces. This comes useful when desiging larger game systems or when ensuring the code can be extended.

Interface declaration

Declaring an interface is quite similar to declaring a normal class: simply use API_INTERFACE tag. Then you can declare virtual function to be part of the interface.

#pragma once

#include "Engine/Scripting/ScriptingType.h"

API_INTERFACE() class GAME_API IMyInterface
{
DECLARE_SCRIPTING_TYPE_MINIMAL(IMyInterface);

    // Interface virtual method
    API_FUNCTION() virtual float GetSpeed(const Vector3& v) = 0;
};

Tip

Interfaces with an abstract method (deleted virtual) that don't contain API_FUNCTION tag are not supported.

Interface implementation

The next step is to define interface inheritance on an class and implement all it's methods. Interfaces can be implemented on any Scripting Object such as Script, Actor, PersistentScriptingObject. Interface methods are virtual thus they can be overridden also in C# and Visual Scripting.

C++

#pragma once

#include "IMyInterface.h"
#include "Engine/Scripting/Script.h"

// Script that implements custom interface
API_CLASS() class GAME_API InterfaceInCpp : public Script, public IMyInterface
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE(InterfaceInCpp);

    float GetSpeed(const Vector3& v) override
    {
        // Implement interface method
        return v.Length();
    }
};

C#

// Script that implements custom interface
public class InterfaceInCSharp : Script, IMyInterface
{
    public float GetSpeed(Vector3 v)
    {
        // Implement interface method
        return v.Length;
    }
}

Interface calling

C++

#pragma once

#include "IMyInterface.h"
#include "Engine/Scripting/Script.h"

API_CLASS() class GAME_API InterfaceInCpp : public Script
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE(InterfaceInCpp);

    // Pointer to object with interface implementation (can be set from other script in C++ or C# or VS)
    API_FIELD() ScriptingObject* MyInterface = nullptr;

    void OnUpdate() override
    {
        // Cast object into interface
        auto interface = ToInterface<IMyInterface>(MyInterface);
        if (interface)
        {
            // Call interface method (works with both C++ and C# interface implementations)
            interface->GetSpeed(Vector3::One);
        }
    }
};

C#

public class InterfaceInCSharp : Script, IMyInterface
{
    // Reference to object with interface implementation (can be set from other script in C# or VS)
    public FlaxEngine.Object MyInterface;

    public override void OnUpdate()
    {
        // Cast object into interface
        var inter = MyInterface as IMyInterface;
        if (inter != null)
        {
            // Call interface method (works with both C++ and C# interface implementations)
            inter.GetSpeed(Vector3.One);
        }
    }
}

Checking if object implements interface

C++

auto someObject = GetActor();
if (someObject && someObject->GetType().GetInterface(IMyInterface::TypeInitializer))
{
    // someObject implements IMyInterface interface...
}

C#

var someObject = Actor;
if (someObject is IMyInterface)
{
    // someObject implements IMyInterface interface...
}