272 lines
7.8 KiB
C
272 lines
7.8 KiB
C
#ifndef FLECS_DASH_IMPL
|
|
#include "flecs_dash.h"
|
|
#endif
|
|
|
|
|
|
static
|
|
void EcsUpdateFps(ecs_iter_t *it) {
|
|
ecs_world_t *world = it->world;
|
|
|
|
EcsFps *world_fps = ecs_column(it, EcsFps, 1);
|
|
|
|
const ecs_world_info_t *info = ecs_get_world_info(world);
|
|
world_fps->value = 1.0 / info->delta_time_raw;
|
|
world_fps->count += world_fps->value;
|
|
world_fps->target = info->target_fps;
|
|
}
|
|
|
|
static
|
|
void EcsUpdateLoad(ecs_iter_t *it) {
|
|
ecs_world_t *world = it->world;
|
|
|
|
EcsLoad *world_load = ecs_column(it, EcsLoad, 1);
|
|
|
|
const ecs_world_info_t *info = ecs_get_world_info(world);
|
|
|
|
world_load->total_time_count += info->delta_time_raw;
|
|
world_load->frame_time_count = info->frame_time_total;
|
|
world_load->system_time_count = info->system_time_total;
|
|
world_load->merge_time_count = info->merge_time_total;
|
|
}
|
|
|
|
static
|
|
void EcsUpdateTick(ecs_iter_t *it) {
|
|
ecs_world_t *world = it->world;
|
|
|
|
EcsTick *world_tick = ecs_column(it, EcsTick, 1);
|
|
|
|
const ecs_world_info_t *info = ecs_get_world_info(world);
|
|
world_tick->count = info->frame_count_total;
|
|
}
|
|
|
|
static
|
|
void EcsUpdateClock(ecs_iter_t *it) {
|
|
ecs_world_t *world = it->world;
|
|
|
|
EcsWorldClock *world_clock = ecs_column(it, EcsWorldClock, 1);
|
|
|
|
const ecs_world_info_t *info = ecs_get_world_info(world);
|
|
world_clock->world_time = info->world_time_total;
|
|
world_clock->world_time_raw = 0;
|
|
}
|
|
|
|
void FlecsDashMonitorImport(
|
|
ecs_world_t *world)
|
|
{
|
|
ECS_MODULE(world, FlecsDashMonitor);
|
|
|
|
ECS_IMPORT(world, FlecsMeta);
|
|
|
|
ecs_set_name_prefix(world, "Ecs");
|
|
|
|
ECS_META(world, EcsFps);
|
|
ECS_META(world, EcsLoad);
|
|
ECS_META(world, EcsTick);
|
|
ECS_META(world, EcsWorldClock);
|
|
|
|
/* System for keeping track of world stats */
|
|
ecs_set(world, EcsWorld, EcsFps, {0});
|
|
ECS_SYSTEM(world, EcsUpdateFps, EcsOnLoad, flecs.core.World:Fps);
|
|
|
|
ecs_set(world, EcsWorld, EcsLoad, {0});
|
|
ECS_SYSTEM(world, EcsUpdateLoad, EcsOnLoad, flecs.core.World:Load);
|
|
|
|
ecs_set(world, EcsWorld, EcsTick, {0});
|
|
ECS_SYSTEM(world, EcsUpdateTick, EcsOnLoad, flecs.core.World:Tick);
|
|
|
|
ecs_set(world, EcsWorld, EcsWorldClock, {0});
|
|
ECS_SYSTEM(world, EcsUpdateClock, EcsOnLoad, flecs.core.World:WorldClock);
|
|
}
|
|
|
|
static
|
|
bool request_this(
|
|
ecs_world_t *world,
|
|
ecs_entity_t entity,
|
|
EcsHttpEndpoint *endpoint,
|
|
EcsHttpRequest *request,
|
|
EcsHttpReply *reply)
|
|
{
|
|
ecs_entity_t server = ecs_get_parent_w_entity(world, entity, 0);
|
|
if (server) {
|
|
ecs_strbuf_t buf = ECS_STRBUF_INIT;
|
|
char *path = ecs_get_fullpath(world, server);
|
|
ecs_strbuf_append(&buf, "{\"server_id\":\"%s\"}", path);
|
|
ecs_os_free(path);
|
|
reply->body = ecs_strbuf_get(&buf);
|
|
return true;
|
|
} else {
|
|
reply->body = ecs_os_strdup("{\"server_id\":\"unknown\"}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static
|
|
bool request_files(
|
|
ecs_world_t *world,
|
|
ecs_entity_t entity,
|
|
EcsHttpEndpoint *endpoint,
|
|
EcsHttpRequest *request,
|
|
EcsHttpReply *reply)
|
|
{
|
|
const char *file = request->relative_url;
|
|
char path[1024];
|
|
|
|
if (!file || !strlen(file)) {
|
|
file = "index.html";
|
|
}
|
|
|
|
char *etc_path = ecs_os_module_to_etc("flecs.dash");
|
|
|
|
sprintf(path, "%s/%s", etc_path, file);
|
|
|
|
FILE *f = fopen(path, "r");
|
|
if (!f) {
|
|
return false;
|
|
} else {
|
|
fclose(f);
|
|
}
|
|
|
|
reply->body = ecs_os_strdup(path);
|
|
reply->is_file = true;
|
|
|
|
ecs_os_free(etc_path);
|
|
|
|
return true;
|
|
}
|
|
|
|
static
|
|
bool request_player(
|
|
ecs_world_t *world,
|
|
ecs_entity_t entity,
|
|
EcsHttpEndpoint *endpoint,
|
|
EcsHttpRequest *request,
|
|
EcsHttpReply *reply)
|
|
{
|
|
const char *cmd = request->relative_url;
|
|
|
|
ecs_entity_t ecs_typeid(EcsPlayer) = ecs_lookup_fullpath(
|
|
world, "flecs.player.Player");
|
|
|
|
if (ecs_typeid(EcsPlayer)) {
|
|
EcsPlayer *player = ecs_get_mut(world, EcsWorld, EcsPlayer, NULL);
|
|
|
|
if (!strcmp(cmd, "play")) {
|
|
player->state = EcsPlayerPlay;
|
|
} else if (!strcmp(cmd, "pause")) {
|
|
player->state = EcsPlayerPause;
|
|
} else if (!strcmp(cmd, "stop")) {
|
|
player->state = EcsPlayerStop;
|
|
}
|
|
|
|
ecs_modified(world, EcsWorld, EcsPlayer);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static
|
|
void RunServer(ecs_iter_t *it) {
|
|
ecs_world_t *world = it->world;
|
|
|
|
EcsDashServer *server = ecs_column(it, EcsDashServer, 1);
|
|
|
|
ecs_entity_t ecs_typeid(EcsHttpEndpoint) = ecs_column_entity(it, 2);
|
|
ecs_entity_t ecs_typeid(EcsRestServer) = ecs_column_entity(it, 3);
|
|
ecs_entity_t ecs_typeid(EcsMonitorServer) = ecs_column_entity(it, 4);
|
|
ecs_entity_t ecs_typeid(EcsDashApp) = ecs_column_entity(it, 5);
|
|
ecs_entity_t EcsDashInitialized = ecs_column_entity(it, 6);
|
|
|
|
int32_t i;
|
|
for (i = 0; i < it->count; i ++) {
|
|
ecs_entity_t e = it->entities[i];
|
|
EcsDashServer *s = &server[i];
|
|
|
|
/* Create REST & monitor server */
|
|
ecs_set(world, e, EcsRestServer, {.port = s->port});
|
|
ecs_set(world, e, EcsMonitorServer, {.port = s->port});
|
|
|
|
if (ecs_has_entity(world, e, EcsDashInitialized)) {
|
|
/* Don't add endpoints again if already initialized */
|
|
continue;
|
|
}
|
|
|
|
/* Add endpoint to server for serving up files */
|
|
ecs_entity_t e_files = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, e_files, EcsName, {"e_files"});
|
|
ecs_set(world, e_files, EcsHttpEndpoint, {
|
|
.url = "",
|
|
.action = request_files});
|
|
|
|
/* Add endpoint to server that returns entity id of server */
|
|
ecs_entity_t e_this = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, e_this, EcsName, {"e_this"});
|
|
ecs_set(world, e_this, EcsHttpEndpoint, {
|
|
.url = "this",
|
|
.action = request_this});
|
|
|
|
/* Add endpoint to server that returns entity id of server */
|
|
ecs_entity_t e_player = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, e_player, EcsName, {"e_player"});
|
|
ecs_set(world, e_player, EcsHttpEndpoint, {
|
|
.url = "player",
|
|
.action = request_player,
|
|
.synchronous = true});
|
|
|
|
/* Add browser app */
|
|
ecs_entity_t dash_overview = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, dash_overview, EcsName, {"overview"});
|
|
ecs_set(world, dash_overview, EcsDashApp, {
|
|
.path = "etc/apps/overview",
|
|
.icon = "images/usage.png"
|
|
});
|
|
|
|
ecs_entity_t dash_systems = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, dash_systems, EcsName, {"systems"});
|
|
ecs_set(world, dash_systems, EcsDashApp, {
|
|
.path = "etc/apps/systems",
|
|
.icon = "images/layers.png"
|
|
});
|
|
|
|
ecs_entity_t dash_browser = ecs_new_w_entity(world, ECS_CHILDOF | e);
|
|
ecs_set(world, dash_browser, EcsName, {"browser"});
|
|
ecs_set(world, dash_browser, EcsDashApp, {
|
|
.path = "etc/apps/browser",
|
|
.icon = "images/tree.png"
|
|
});
|
|
|
|
/* Prevent initializing the server again */
|
|
ecs_add_entity(world, e, EcsDashInitialized);
|
|
}
|
|
}
|
|
|
|
void FlecsDashImport(
|
|
ecs_world_t *world)
|
|
{
|
|
ECS_MODULE(world, FlecsDash);
|
|
|
|
ECS_IMPORT(world, FlecsMonitor);
|
|
ECS_IMPORT(world, FlecsDashMonitor);
|
|
|
|
ECS_IMPORT(world, FlecsMeta);
|
|
ECS_IMPORT(world, FlecsPlayer);
|
|
ECS_IMPORT(world, FlecsComponentsHttp);
|
|
ECS_IMPORT(world, FlecsRest);
|
|
|
|
ecs_set_name_prefix(world, "EcsDash");
|
|
|
|
ECS_META(world, EcsDashServer);
|
|
ECS_META(world, EcsDashApp);
|
|
|
|
ECS_TAG(world, EcsDashInitialized);
|
|
|
|
ECS_SYSTEM(world, RunServer, EcsOnSet, Server,
|
|
:flecs.components.http.Endpoint,
|
|
:flecs.rest.Server,
|
|
:flecs.monitor.Server,
|
|
:App,
|
|
:Initialized);
|
|
|
|
ECS_EXPORT_COMPONENT(EcsDashServer);
|
|
ECS_EXPORT_COMPONENT(EcsDashApp);
|
|
}
|