Add unit test for scripting event to ensure generated bindings code works fine
This commit is contained in:
@@ -21,7 +21,9 @@ TEST_CASE("Scripting")
|
||||
CHECK(object->Is<TestClassNative>());
|
||||
TestClassNative* testClass = (TestClassNative*)object;
|
||||
CHECK(testClass->SimpleField == 1);
|
||||
int32 methodResult = testClass->Test(TEXT("123"));
|
||||
CHECK(testClass->SimpleStruct.Object == nullptr);
|
||||
CHECK(testClass->SimpleStruct.Vector == Float3::One);
|
||||
int32 methodResult = testClass->TestMethod(TEXT("123"));
|
||||
CHECK(methodResult == 3);
|
||||
|
||||
// Test managed class
|
||||
@@ -34,7 +36,33 @@ TEST_CASE("Scripting")
|
||||
MObject* managed = testClass->GetOrCreateManagedInstance(); // Ensure to create C# object and run it's ctor
|
||||
CHECK(managed);
|
||||
CHECK(testClass->SimpleField == 2);
|
||||
methodResult = testClass->Test(TEXT("123"));
|
||||
CHECK(testClass->SimpleStruct.Object == testClass);
|
||||
CHECK(testClass->SimpleStruct.Vector == Float3::UnitX);
|
||||
methodResult = testClass->TestMethod(TEXT("123"));
|
||||
CHECK(methodResult == 6);
|
||||
}
|
||||
|
||||
SECTION("Test Event")
|
||||
{
|
||||
ScriptingTypeHandle type = Scripting::FindScriptingType("FlaxEngine.TestClassManaged");
|
||||
CHECK(type);
|
||||
ScriptingObject* object = Scripting::NewObject(type.GetType().ManagedClass);
|
||||
CHECK(object);
|
||||
MObject* managed = object->GetOrCreateManagedInstance(); // Ensure to create C# object and run it's ctor
|
||||
CHECK(managed);
|
||||
TestClassNative* testClass = (TestClassNative*)object;
|
||||
CHECK(testClass->SimpleField == 2);
|
||||
String str1 = TEXT("1");
|
||||
String str2 = TEXT("2");
|
||||
Array<TestStruct> arr1 = { testClass->SimpleStruct };
|
||||
Array<TestStruct> arr2 = { testClass->SimpleStruct };
|
||||
testClass->SimpleEvent(1, Float3::One, str1, str2, arr1, arr2);
|
||||
CHECK(testClass->SimpleField == 4);
|
||||
CHECK(str2 == TEXT("4"));
|
||||
CHECK(arr2.Count() == 2);
|
||||
CHECK(arr2[0].Vector == Float3::Half);
|
||||
CHECK(arr2[0].Object == nullptr);
|
||||
CHECK(arr2[1].Vector == testClass->SimpleStruct.Vector);
|
||||
CHECK(arr2[1].Object == testClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,48 @@
|
||||
#if FLAX_TESTS
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial struct TestStruct : System.IEquatable<TestStruct>
|
||||
{
|
||||
/// <summary></summary>
|
||||
public static bool operator ==(TestStruct left, TestStruct right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary></summary>
|
||||
public static bool operator !=(TestStruct left, TestStruct right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(TestStruct other)
|
||||
{
|
||||
return Vector.Equals(other.Vector) && Equals(Object, other.Object);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is TestStruct other && Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Vector.GetHashCode() * 397) ^ (Object != null ? Object.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Vector={Vector}, Object={Object?.ToString() ?? "null"}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test class.
|
||||
/// </summary>
|
||||
@@ -10,13 +52,46 @@ namespace FlaxEngine
|
||||
{
|
||||
TestClassManaged()
|
||||
{
|
||||
// Test setting C++ values from C#
|
||||
SimpleField = 2;
|
||||
SimpleStruct = new TestStruct
|
||||
{
|
||||
Vector = Float3.UnitX,
|
||||
Object = this,
|
||||
};
|
||||
SimpleEvent += OnSimpleEvent;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Test(string str)
|
||||
public override int TestMethod(string str)
|
||||
{
|
||||
return str.Length + base.Test(str);
|
||||
// Test C++ base method invocation
|
||||
return str.Length + base.TestMethod(str);
|
||||
}
|
||||
|
||||
private void OnSimpleEvent(int arg1, Float3 arg2, string arg3, ref string arg4, TestStruct[] arg5, ref TestStruct[] arg6)
|
||||
{
|
||||
// Verify that C++ passed proper data to C# via event bindings
|
||||
if (arg1 == 1 &&
|
||||
arg2 == Float3.One &&
|
||||
arg3 == "1" &&
|
||||
arg4 == "2" &&
|
||||
arg5 != null && arg5.Length == 1 && arg5[0] == SimpleStruct &&
|
||||
arg6 != null && arg6.Length == 1 && arg6[0] == SimpleStruct)
|
||||
{
|
||||
// Test passing data back from C# to C++
|
||||
SimpleField = 4;
|
||||
arg4 = "4";
|
||||
arg6 = new TestStruct[2]
|
||||
{
|
||||
new TestStruct
|
||||
{
|
||||
Vector = Float3.Half,
|
||||
Object = null,
|
||||
},
|
||||
SimpleStruct,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/ISerializable.h"
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Scripting/ScriptingObject.h"
|
||||
|
||||
// Test structure.
|
||||
API_STRUCT(NoDefault) struct TestStruct : public ISerializable
|
||||
{
|
||||
API_AUTO_SERIALIZATION();
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(TestStruct);
|
||||
|
||||
// Var
|
||||
API_FIELD() Float3 Vector = Float3::One;
|
||||
// Ref
|
||||
API_FIELD() ScriptingObject* Object = nullptr;
|
||||
};
|
||||
|
||||
// Test class.
|
||||
API_CLASS() class TestClassNative : public ScriptingObject, public ISerializable
|
||||
{
|
||||
@@ -15,8 +29,14 @@ public:
|
||||
// Test value
|
||||
API_FIELD() int32 SimpleField = 1;
|
||||
|
||||
// Test struct
|
||||
API_FIELD() TestStruct SimpleStruct;
|
||||
|
||||
// Test event
|
||||
API_EVENT() Delegate<int32, Float3, const String&, String&, const Array<TestStruct>&, Array<TestStruct>&> SimpleEvent;
|
||||
|
||||
// Test virtual method
|
||||
API_FUNCTION() virtual int32 Test(const String& str)
|
||||
API_FUNCTION() virtual int32 TestMethod(const String& str)
|
||||
{
|
||||
return str.Length();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user