C# и Variant API: методы, свойства и сигналы
Когда нужен прямой C#-вызов, а когда Call, Get и сгенерированные имена.
Выберите границу вызова
Для двух известных C#-типов предпочитайте прямой вызов: компилятор проверит имя, аргументы и результат. Call нужен на динамической движковой границе, где имя метода и аргументы представлены Variant. Он не делает произвольный .NET-тип поддерживаемым движком.
CounterService.cs
using Reckfell;
public partial class CounterService : Entity
{
[Signal] public delegate void CountChangedEventHandler(int count);
private int _count;
public int Count => _count;
public bool TryAdd(int amount)
{
if (amount <= 0 || amount > 1000 - _count) return false;
_count += amount;
EmitSignal(SignalName.CountChanged, _count);
return true;
}
}В полном примере используется counter.Call(CounterService.MethodName.TryAdd, 5).AsBool(). После него Count равен 5, подписчик CountChanged получает 5. Get("Count") читает поддерживаемое свойство через движковый API; это не синтаксис доступа ко всем приватным полям C#.
Имена и типы
Генератор сохраняет C#-имя TryAdd. try_add не является его вторым именем. Используйте MethodName, PropertyName и SignalName там, где они сгенерированы; не редактируйте сгенерированный код.
Аргументы и результат динамического вызова должны соответствовать сигнатуре. Проверяйте HasMethod для неизвестного объекта и отдельно валидность нативного экземпляра; наличие имени не проверяет игровые условия команды.
Событие CountChanged — C#-представление движкового сигнала. IDamageable и обычные .NET-модели остаются C#-контрактами и не получают автоматический Variant-маршаллинг. Эта страница объясняет движковую границу C#, а не обещает поддержку произвольного второго языка.