Собственные мониторы: значения, единицы и очистка
C# счётчик с кешированным значением: секунды, количество, уникальный ID и удаление при выходе.
Создать два счётчика
Добавьте JobTelemetry.cs в C#-проект 1.0.0 и прикрепите к Entity. При входе в дерево он создаёт мониторы времени и количества с уникальной категорией docs_perf_<instance ID>. Начальные значения — 0. В своём коде главного потока вызовите Publish(0.125, 9592): API вернёт 0,125 секунды и количество 9592.
JobTelemetry.cs
using System;
using Reckfell;
public partial class JobTelemetry : Entity
{
public string SecondsId { get; private set; } = "";
public string CountId { get; private set; } = "";
public double Seconds { get; private set; }
public int Count { get; private set; }
private bool _registered;
public override void _EnterTree()
{
string category = "docs_perf_" + GetInstanceId();
SecondsId = category + "/prime_seconds";
CountId = category + "/prime_count";
Performance.AddCustomMonitor(SecondsId, Callable.From(() => Seconds),
type: Performance.MonitorType.Time);
Performance.AddCustomMonitor(CountId, Callable.From(() => Count),
type: Performance.MonitorType.Quantity);
_registered = true;
}
public void Publish(double seconds, int count)
{
if (!ReckfellThread.IsMainThread())
throw new InvalidOperationException("Publish must run on the main thread");
if (!double.IsFinite(seconds) || seconds < 0 || count < 0)
throw new ArgumentOutOfRangeException(nameof(seconds));
Seconds = seconds;
Count = count;
}
public override void _ExitTree()
{
if (!_registered) return;
Performance.RemoveCustomMonitor(SecondsId);
Performance.RemoveCustomMonitor(CountId);
_registered = false;
}
}Если проект запущен с подключённым отладчиком редактора, откройте нижнюю панель отладки и вкладку мониторов, найдите категорию docs_perf_<instance ID> и включите нужные графики. Время 0,125 секунды форматируется как 125 мс. API-регистрация, типы, значения и очистка проверены в runtime; действия мышью и отображение этих пользовательских графиков в нативном редакторе в этом стенде не проверены.
Чтобы получить ненулевые значения без дополнительного игрового кода, запустите PrimeJobsDemo и его файлы. Он публикует итоговое количество и время от постановки .NET-задачи до принятия результата. Это длительность всей операции с ожиданиями, а не чистое время CPU.
Callback не является накопителем
GetCustomMonitor синхронно вызывает зарегистрированный Callable. Движок не измеряет вашу функцию автоматически и не хранит историю её событий вместо вас. Callback примера лишь возвращает заранее сохранённые Seconds/Count; тяжёлое вычисление, загрузку, запись файла и создание Entity в нём не выполняйте.
В текущем remote debugger опрос отправляется примерно раз в секунду. Короткий всплеск между опросами может остаться незамеченным. Для события накапливайте количество либо максимум за явно определённый интервал; для длинных кадров используйте сборщик интервалов. Не называйте график секундного опроса полным профилем каждого кадра.
Единицы и имена
| MonitorType | Передаваемое значение | Форматирование редактора |
|---|---|---|
| Quantity | Количество | Целое число |
| Time | Секунды | Значение × 1000, мс |
| Memory | Байты | Размер памяти |
| Percentage | Доля от 0 до 1 | Значение × 100, % |
Тип задаёт смысл и форматирование, а не вычисляет показатель. Для 25% передайте 0,25. Для 125 мс — 0,125, не 125. Не путайте байты выделений, занятый объём managed heap и всю память процесса.
Имена глобальны в текущем процессе. Повторный AddCustomMonitor с тем же ID вызывает ошибку; пример добавляет instance ID. Ровно один разделитель «/» делит имя на категорию и показатель в проверенных исходниках редактора. Два экземпляра JobTelemetry не заменяют друг друга.
Жизненный цикл
Callable захватывает компонент. _ExitTree удаляет оба принадлежащих ему монитора до исчезновения получателя; _EnterTree регистрирует их при повторном входе. Не удаляйте чужой монитор только из-за совпадения короткого имени. Не обращайтесь к старому ID после удаления без HasCustomMonitor.
Publish выполняйте в главном потоке. Для worker сначала передайте результат туда, затем обновите кэш. Отсутствие подключённого редактора не запрещает HasCustomMonitor/GetCustomMonitor, но и не создаёт запись графика. Сохранять результаты в файл, экспортировать историю и показывать собственный оверлей нужно отдельным кодом.