/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
third_party/flecs-3.2.11/src/addons/monitor.c
375 строк
12 KB
Den163
Added flecs and glm to the repo
31 май 2024, 23:08
31 май 2024, 23:08
5d252b3
Код
Авторство
О чём код?
/** * @file addons/monitor.c * @brief Monitor addon. */ #include "flecs.h" #include "../private_api.h" #ifdef FLECS_MONITOR ECS_COMPONENT_DECLARE(FlecsMonitor); ECS_COMPONENT_DECLARE(EcsWorldStats); ECS_COMPONENT_DECLARE(EcsWorldSummary); ECS_COMPONENT_DECLARE(EcsPipelineStats); ecs_entity_t EcsPeriod1s = 0; ecs_entity_t EcsPeriod1m = 0; ecs_entity_t EcsPeriod1h = 0; ecs_entity_t EcsPeriod1d = 0; ecs_entity_t EcsPeriod1w = 0; static int32_t flecs_day_interval_count = 24; static int32_t flecs_week_interval_count = 168; static ECS_COPY(EcsPipelineStats, dst, src, { (void)dst; (void)src; ecs_abort(ECS_INVALID_OPERATION, "cannot copy pipeline stats component"); }) static ECS_MOVE(EcsPipelineStats, dst, src, { ecs_os_memcpy_t(dst, src, EcsPipelineStats); ecs_os_zeromem(src); }) static ECS_DTOR(EcsPipelineStats, ptr, { ecs_pipeline_stats_fini(&ptr->stats); }) static void UpdateWorldSummary(ecs_iter_t *it) { EcsWorldSummary *summary = ecs_field(it, EcsWorldSummary, 1); const ecs_world_info_t *info = ecs_get_world_info(it->world); int32_t i, count = it->count; for (i = 0; i < count; i ++) { summary[i].target_fps = (double)info->target_fps; summary[i].frame_time_last = (double)info->frame_time_total - summary[i].frame_time_total; summary[i].system_time_last = (double)info->system_time_total - summary[i].system_time_total; summary[i].merge_time_last = (double)info->merge_time_total - summary[i].merge_time_total; summary[i].frame_time_total = (double)info->frame_time_total; summary[i].system_time_total = (double)info->system_time_total; summary[i].merge_time_total = (double)info->merge_time_total; } } static void MonitorStats(ecs_iter_t *it) { ecs_world_t *world = it->real_world; EcsStatsHeader *hdr = ecs_field_w_size(it, 0, 1); ecs_id_t kind = ecs_pair_first(it->world, ecs_field_id(it, 1)); void *stats = ECS_OFFSET_T(hdr, EcsStatsHeader); ecs_ftime_t elapsed = hdr->elapsed; hdr->elapsed += it->delta_time; int32_t t_last = (int32_t)(elapsed * 60); int32_t t_next = (int32_t)(hdr->elapsed * 60); int32_t i, dif = t_last - t_next; ecs_world_stats_t last_world = {0}; ecs_pipeline_stats_t last_pipeline = {0}; void *last = NULL; if (!dif) { /* Copy last value so we can pass it to reduce_last */ if (kind == ecs_id(EcsWorldStats)) { last = &last_world; ecs_world_stats_copy_last(&last_world, stats); } else if (kind == ecs_id(EcsPipelineStats)) { last = &last_pipeline; ecs_pipeline_stats_copy_last(&last_pipeline, stats); } } if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_get(world, stats); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_get(world, ecs_get_pipeline(world), stats); } if (!dif) { /* Still in same interval, combine with last measurement */ hdr->reduce_count ++; if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_reduce_last(stats, last, hdr->reduce_count); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_reduce_last(stats, last, hdr->reduce_count); } } else if (dif > 1) { /* More than 16ms has passed, backfill */ for (i = 1; i < dif; i ++) { if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_repeat_last(stats); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_world_stats_repeat_last(stats); } } hdr->reduce_count = 0; } if (last && kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_fini(last); } } static void ReduceStats(ecs_iter_t *it) { void *dst = ecs_field_w_size(it, 0, 1); void *src = ecs_field_w_size(it, 0, 2); ecs_id_t kind = ecs_pair_first(it->world, ecs_field_id(it, 1)); dst = ECS_OFFSET_T(dst, EcsStatsHeader); src = ECS_OFFSET_T(src, EcsStatsHeader); if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_reduce(dst, src); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_reduce(dst, src); } } static void AggregateStats(ecs_iter_t *it) { int32_t interval = *(int32_t*)it->ctx; EcsStatsHeader *dst_hdr = ecs_field_w_size(it, 0, 1); EcsStatsHeader *src_hdr = ecs_field_w_size(it, 0, 2); void *dst = ECS_OFFSET_T(dst_hdr, EcsStatsHeader); void *src = ECS_OFFSET_T(src_hdr, EcsStatsHeader); ecs_id_t kind = ecs_pair_first(it->world, ecs_field_id(it, 1)); ecs_world_stats_t last_world = {0}; ecs_pipeline_stats_t last_pipeline = {0}; void *last = NULL; if (dst_hdr->reduce_count != 0) { /* Copy last value so we can pass it to reduce_last */ if (kind == ecs_id(EcsWorldStats)) { last_world.t = 0; ecs_world_stats_copy_last(&last_world, dst); last = &last_world; } else if (kind == ecs_id(EcsPipelineStats)) { last_pipeline.t = 0; ecs_pipeline_stats_copy_last(&last_pipeline, dst); last = &last_pipeline; } } /* Reduce from minutes to the current day */ if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_reduce(dst, src); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_reduce(dst, src); } if (dst_hdr->reduce_count != 0) { if (kind == ecs_id(EcsWorldStats)) { ecs_world_stats_reduce_last(dst, last, dst_hdr->reduce_count); } else if (kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_reduce_last(dst, last, dst_hdr->reduce_count); } } /* A day has 60 24 minute intervals */ dst_hdr->reduce_count ++; if (dst_hdr->reduce_count >= interval) { dst_hdr->reduce_count = 0; } if (last && kind == ecs_id(EcsPipelineStats)) { ecs_pipeline_stats_fini(last); } } static void flecs_stats_monitor_import( ecs_world_t *world, ecs_id_t kind, size_t size) { ecs_entity_t prev = ecs_set_scope(world, kind); // Called each frame, collects 60 measurements per second ecs_system(world, { .entity = ecs_entity(world, { .name = "Monitor1s", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms = {{ .id = ecs_pair(kind, EcsPeriod1s), .src.id = EcsWorld }}, .callback = MonitorStats }); // Called each second, reduces into 60 measurements per minute ecs_entity_t mw1m = ecs_system(world, { .entity = ecs_entity(world, { .name = "Monitor1m", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms = {{ .id = ecs_pair(kind, EcsPeriod1m), .src.id = EcsWorld }, { .id = ecs_pair(kind, EcsPeriod1s), .src.id = EcsWorld }}, .callback = ReduceStats, .interval = 1.0 }); // Called each minute, reduces into 60 measurements per hour ecs_system(world, { .entity = ecs_entity(world, { .name = "Monitor1h", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms = {{ .id = ecs_pair(kind, EcsPeriod1h), .src.id = EcsWorld }, { .id = ecs_pair(kind, EcsPeriod1m), .src.id = EcsWorld }}, .callback = ReduceStats, .rate = 60, .tick_source = mw1m }); // Called each minute, reduces into 60 measurements per day ecs_system(world, { .entity = ecs_entity(world, { .name = "Monitor1d", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms = {{ .id = ecs_pair(kind, EcsPeriod1d), .src.id = EcsWorld }, { .id = ecs_pair(kind, EcsPeriod1m), .src.id = EcsWorld }}, .callback = AggregateStats, .rate = 60, .tick_source = mw1m, .ctx = &flecs_day_interval_count }); // Called each hour, reduces into 60 measurements per week ecs_system(world, { .entity = ecs_entity(world, { .name = "Monitor1w", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms = {{ .id = ecs_pair(kind, EcsPeriod1w), .src.id = EcsWorld }, { .id = ecs_pair(kind, EcsPeriod1h), .src.id = EcsWorld }}, .callback = AggregateStats, .rate = 60, .tick_source = mw1m, .ctx = &flecs_week_interval_count }); ecs_set_scope(world, prev); ecs_set_id(world, EcsWorld, ecs_pair(kind, EcsPeriod1s), size, NULL); ecs_set_id(world, EcsWorld, ecs_pair(kind, EcsPeriod1m), size, NULL); ecs_set_id(world, EcsWorld, ecs_pair(kind, EcsPeriod1h), size, NULL); ecs_set_id(world, EcsWorld, ecs_pair(kind, EcsPeriod1d), size, NULL); ecs_set_id(world, EcsWorld, ecs_pair(kind, EcsPeriod1w), size, NULL); } static void flecs_world_monitor_import( ecs_world_t *world) { ECS_COMPONENT_DEFINE(world, EcsWorldStats); flecs_stats_monitor_import(world, ecs_id(EcsWorldStats), sizeof(EcsWorldStats)); } static void flecs_pipeline_monitor_import( ecs_world_t *world) { ECS_COMPONENT_DEFINE(world, EcsPipelineStats); ecs_set_hooks(world, EcsPipelineStats, { .ctor = ecs_default_ctor, .copy = ecs_copy(EcsPipelineStats), .move = ecs_move(EcsPipelineStats), .dtor = ecs_dtor(EcsPipelineStats) }); flecs_stats_monitor_import(world, ecs_id(EcsPipelineStats), sizeof(EcsPipelineStats)); } void FlecsMonitorImport( ecs_world_t *world) { ECS_MODULE_DEFINE(world, FlecsMonitor); ECS_IMPORT(world, FlecsPipeline); ECS_IMPORT(world, FlecsTimer); #ifdef FLECS_META ECS_IMPORT(world, FlecsMeta); #endif #ifdef FLECS_UNITS ECS_IMPORT(world, FlecsUnits); #endif #ifdef FLECS_COREDOC ECS_IMPORT(world, FlecsDoc); ecs_doc_set_brief(world, ecs_id(FlecsMonitor), "Module that automatically monitors statistics for the world & systems"); #endif ecs_set_name_prefix(world, "Ecs"); EcsPeriod1s = ecs_new_entity(world, "EcsPeriod1s"); EcsPeriod1m = ecs_new_entity(world, "EcsPeriod1m"); EcsPeriod1h = ecs_new_entity(world, "EcsPeriod1h"); EcsPeriod1d = ecs_new_entity(world, "EcsPeriod1d"); EcsPeriod1w = ecs_new_entity(world, "EcsPeriod1w"); ECS_COMPONENT_DEFINE(world, EcsWorldSummary); #if defined(FLECS_META) && defined(FLECS_UNITS) ecs_struct(world, { .entity = ecs_id(EcsWorldSummary), .members = { { .name = "target_fps", .type = ecs_id(ecs_f64_t), .unit = EcsHertz }, { .name = "frame_time_total", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds }, { .name = "system_time_total", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds }, { .name = "merge_time_total", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds }, { .name = "frame_time_last", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds }, { .name = "system_time_last", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds }, { .name = "merge_time_last", .type = ecs_id(ecs_f64_t), .unit = EcsSeconds } } }); #endif ecs_system(world, { .entity = ecs_entity(world, { .name = "UpdateWorldSummary", .add = {ecs_dependson(EcsPreFrame)} }), .query.filter.terms[0] = { .id = ecs_id(EcsWorldSummary) }, .callback = UpdateWorldSummary }); ECS_SYSTEM(world, UpdateWorldSummary, EcsPreFrame, WorldSummary); ecs_set(world, EcsWorld, EcsWorldSummary, {0}); flecs_world_monitor_import(world); flecs_pipeline_monitor_import(world); if (ecs_os_has_time()) { ecs_measure_frame_time(world, true); ecs_measure_system_time(world, true); } } #endif