2019-08-23 11:56:54 -07:00
|
|
|
using System;
|
|
|
|
|
|
|
|
namespace Tests
|
|
|
|
{
|
|
|
|
class Interfaces
|
|
|
|
{
|
|
|
|
interface IFaceA
|
|
|
|
{
|
|
|
|
int FuncA(int a) mut;
|
|
|
|
int FuncA2() mut { return 0; }
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IFaceB : IFaceA
|
|
|
|
{
|
|
|
|
void FuncB(int a) mut
|
|
|
|
{
|
|
|
|
FuncA(a + 100);
|
|
|
|
}
|
2020-09-01 06:37:02 -07:00
|
|
|
|
|
|
|
void FuncC(int a) mut
|
|
|
|
{
|
|
|
|
FuncB(a + 1000);
|
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
|
2021-01-13 09:24:15 -08:00
|
|
|
interface IFaceC
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
concrete IFaceA GetConcreteIA();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct StructA : IFaceB
|
|
|
|
{
|
|
|
|
public int mA = 10;
|
|
|
|
|
|
|
|
int IFaceA.FuncA(int a) mut
|
|
|
|
{
|
|
|
|
mA += a;
|
|
|
|
return mA;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct StructB : IFaceC
|
|
|
|
{
|
|
|
|
public StructA GetConcreteIA()
|
|
|
|
{
|
|
|
|
return StructA();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int UseIA<T>(mut T val, int a) where T : IFaceA
|
|
|
|
{
|
|
|
|
return val.FuncA(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int UseIA2<T>(mut T val) where T : IFaceA
|
|
|
|
{
|
|
|
|
return val.FuncA2();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void UseIB<T>(mut T val, int a) where T : IFaceB
|
|
|
|
{
|
|
|
|
val.FuncB(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassA : IFaceA
|
|
|
|
{
|
|
|
|
public int FuncA(int a)
|
|
|
|
{
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
public virtual int FuncA2()
|
|
|
|
{
|
|
|
|
return 50;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassB : ClassA
|
|
|
|
{
|
|
|
|
public new int FuncA(int a)
|
|
|
|
{
|
|
|
|
return 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int FuncA2()
|
|
|
|
{
|
|
|
|
return 60;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassC : ClassA, IFaceA
|
|
|
|
{
|
|
|
|
public new int FuncA(int a)
|
|
|
|
{
|
|
|
|
return 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int FuncA2()
|
|
|
|
{
|
|
|
|
return 70;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-19 09:37:43 -08:00
|
|
|
public struct Rect
|
|
|
|
{
|
|
|
|
public float x, y, width, height;
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Component
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public class Hitbox : Component
|
|
|
|
{
|
|
|
|
public Rect mArea = .() { x=1, y=2, width=3, height=4, };
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface IEntity
|
|
|
|
{
|
|
|
|
public T GetComponent<T>() where T : Component;
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface IHitbox : IEntity
|
|
|
|
{
|
|
|
|
public Hitbox HitboxValue { get; set; }
|
|
|
|
|
|
|
|
public Hitbox Hitbox
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
if (HitboxValue == null)
|
|
|
|
{
|
|
|
|
HitboxValue = GetComponent<Hitbox>();
|
|
|
|
}
|
|
|
|
|
|
|
|
return HitboxValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class GameItem : IEntity, IHitbox
|
|
|
|
{
|
|
|
|
public T GetComponent<T>() where T : Component
|
|
|
|
{
|
|
|
|
return new T();
|
|
|
|
}
|
|
|
|
public Hitbox HitboxValue { get; set; }
|
|
|
|
}
|
|
|
|
|
|
|
|
static Hitbox GetHitbox<T>(T val) where T : IHitbox
|
|
|
|
{
|
|
|
|
return val.Hitbox;
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
[Test]
|
|
|
|
public static void TestBasics()
|
|
|
|
{
|
|
|
|
StructA sa = .();
|
|
|
|
UseIB(mut sa, 9);
|
|
|
|
Test.Assert(sa.mA == 119);
|
|
|
|
|
|
|
|
ClassA ca = scope ClassA();
|
|
|
|
ClassB cb = scope ClassB();
|
|
|
|
ClassA cba = cb;
|
|
|
|
ClassC cc = scope ClassC();
|
|
|
|
ClassA cca = cc;
|
|
|
|
|
|
|
|
Test.Assert(UseIA(ca, 100) == 5);
|
|
|
|
Test.Assert(UseIA(cb, 100) == 5);
|
|
|
|
Test.Assert(UseIA(cba, 100) == 5);
|
|
|
|
Test.Assert(UseIA((IFaceA)cba, 100) == 5);
|
|
|
|
Test.Assert(UseIA(cc, 100) == 7);
|
|
|
|
Test.Assert(UseIA(cca, 100) == 5);
|
|
|
|
|
|
|
|
Test.Assert(UseIA2(ca) == 50);
|
|
|
|
Test.Assert(UseIA2(cb) == 60);
|
|
|
|
Test.Assert(UseIA2(cba) == 60);
|
|
|
|
Test.Assert(UseIA2((IFaceA)cba) == 60);
|
|
|
|
Test.Assert(UseIA2(cc) == 70);
|
|
|
|
Test.Assert(UseIA2(cca) == 70);
|
2020-11-18 12:07:18 -08:00
|
|
|
|
|
|
|
IFaceA ifa = cba;
|
|
|
|
Test.Assert(ifa.GetType() == typeof(ClassB));
|
2020-11-19 09:37:43 -08:00
|
|
|
|
2021-01-19 10:40:38 -08:00
|
|
|
ClassF cf = scope .();
|
|
|
|
TestIFaceD(cf);
|
|
|
|
Test.Assert(cf.mA == 999);
|
|
|
|
ClassG cg = scope .();
|
|
|
|
TestIFaceD(cg);
|
|
|
|
Test.Assert(cg.mA == 999);
|
|
|
|
|
2020-11-19 09:37:43 -08:00
|
|
|
GameItem gameItem = scope .();
|
|
|
|
var hitbox = GetHitbox(gameItem);
|
|
|
|
Test.Assert(hitbox.mArea == .() { x=1, y=2, width=3, height=4 });
|
|
|
|
delete hitbox;
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
2020-05-27 09:46:09 -07:00
|
|
|
|
|
|
|
////
|
|
|
|
|
|
|
|
interface IFaceD<T>
|
|
|
|
{
|
|
|
|
T GetVal();
|
|
|
|
|
|
|
|
T Add<T2>(T lhs, T2 rhs) where T : operator T + T2
|
|
|
|
{
|
|
|
|
return lhs + rhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static T SMethod(T val);
|
|
|
|
|
|
|
|
static T SMethod2(T val)
|
|
|
|
{
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension IFaceD<T>
|
|
|
|
{
|
|
|
|
T GetVal2()
|
|
|
|
{
|
|
|
|
return GetVal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassD : IFaceD<int16>
|
|
|
|
{
|
|
|
|
public int16 GetVal()
|
|
|
|
{
|
|
|
|
return 123;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int16 Add<T2>(int16 lhs, T2 rhs) where int16 : operator int16 + T2
|
|
|
|
{
|
|
|
|
return lhs + rhs + 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int16 SMethod(int16 val)
|
|
|
|
{
|
|
|
|
return val + 2000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassE : IFaceD<int16>
|
|
|
|
{
|
|
|
|
public int16 GetVal()
|
|
|
|
{
|
|
|
|
return 234;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int16 SMethod(int16 val)
|
|
|
|
{
|
|
|
|
return val + 3000;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int16 SMethod2(int16 val)
|
|
|
|
{
|
|
|
|
return val + 4000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int IDAdd<T>(T val) where T : IFaceD<int16>
|
|
|
|
{
|
|
|
|
return val.Add((int16)23, (int8)100);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static T2 SGet<T, T2>(T val) where T : IFaceD<T2>
|
|
|
|
{
|
|
|
|
return T.SMethod(val.GetVal());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static T2 SGet2<T, T2>(T val) where T : IFaceD<T2>
|
|
|
|
{
|
|
|
|
return T.SMethod2(val.GetVal());
|
|
|
|
}
|
|
|
|
|
2021-01-19 10:40:38 -08:00
|
|
|
interface IFaceD
|
|
|
|
{
|
|
|
|
int32 Val
|
|
|
|
{
|
|
|
|
get; set;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassF : IFaceD
|
|
|
|
{
|
|
|
|
public int32 mA;
|
|
|
|
|
|
|
|
int32 IFaceD.Val
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return mA;
|
|
|
|
}
|
|
|
|
|
|
|
|
set
|
|
|
|
{
|
|
|
|
mA = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ClassG : ClassF
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TestIFaceD<T>(T val) where T : IFaceD
|
|
|
|
{
|
|
|
|
val.Val = 999;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int TestIFaceD2<T>(T val) where T : IFaceD
|
|
|
|
{
|
|
|
|
return val.Val;
|
|
|
|
}
|
|
|
|
|
2020-05-27 09:46:09 -07:00
|
|
|
[Test]
|
|
|
|
public static void TestDefaults()
|
|
|
|
{
|
|
|
|
ClassD cd = scope .();
|
|
|
|
IFaceD<int16> ifd = cd;
|
|
|
|
|
|
|
|
int v = ifd.GetVal();
|
|
|
|
|
|
|
|
Test.Assert(v == 123);
|
|
|
|
v = ifd.GetVal2();
|
|
|
|
Test.Assert(v == 123);
|
|
|
|
v = IDAdd(cd);
|
|
|
|
Test.Assert(v == 1123);
|
|
|
|
v = SGet<ClassD, int16>(cd);
|
|
|
|
Test.Assert(v == 2123);
|
|
|
|
v = SGet2<ClassD, int16>(cd);
|
|
|
|
Test.Assert(v == 123);
|
|
|
|
|
|
|
|
ClassE ce = scope .();
|
|
|
|
ifd = ce;
|
|
|
|
v = ifd.GetVal();
|
|
|
|
Test.Assert(v == 234);
|
|
|
|
v = ifd.GetVal2();
|
|
|
|
Test.Assert(v == 234);
|
|
|
|
v = IDAdd(ce);
|
|
|
|
Test.Assert(v == 123);
|
|
|
|
v = SGet<ClassE, int16>(ce);
|
|
|
|
Test.Assert(v == 3234);
|
|
|
|
v = SGet2<ClassE, int16>(ce);
|
|
|
|
Test.Assert(v == 4234);
|
2021-01-19 10:40:38 -08:00
|
|
|
|
|
|
|
ClassF cf = scope .();
|
|
|
|
TestIFaceD(cf);
|
|
|
|
Test.Assert(cf.mA == 999);
|
|
|
|
Test.Assert(TestIFaceD2(cf) == 999);
|
|
|
|
ClassG cg = scope .();
|
|
|
|
TestIFaceD(cg);
|
|
|
|
Test.Assert(cg.mA == 999);
|
|
|
|
Test.Assert(TestIFaceD2(cg) == 999);
|
2020-05-27 09:46:09 -07:00
|
|
|
}
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
}
|