#ifndef OVM_TASK_MAIN_H #define OVM_TASK_MAIN_H #include "task.h" #include "trace.h" typedef void (*task_app_t)(task_t *task, gpointer userdata); static inline void trace_simulate(task_t *task, gpointer userdata) { trace_t *trace = (trace_t*) userdata; trace_entry_t *te; if (trace->pos > trace->data->len) { fprintf(stderr, "Unexpected end of solution\n"); exit(11); } te = g_ptr_array_index(trace->data, trace->pos); if (te->timestamp == task->timestamp) { guint32 i; trace->pos++; for (i = 0; i < te->count; i++) { if (te->data[i].addr != 0x3e80) { if (te->data[i].addr >= ovm_ins) { fprintf(stderr, "in[]-index out of range: %u at timestamp %u\n", te->data[i].addr, (guint) task->timestamp); exit(1); } task->in[te->data[i].addr] = te->data[i].value; } else if (te->data[i].value != (gdouble) task->scenario) { fprintf(stderr, "Setting wrong scenario at timestamp %u\n", (guint) task->timestamp); exit(1); } } } } static inline void task_do_nothing(task_t *task, gpointer userdata) { UNUSED(task); UNUSED(userdata); } static inline gdouble task_run(task_t *task, task_app_t app, gpointer userdata, const gchar *tracefile) { gboolean dotrace = (NULL != tracefile); ovm_init(); if (dotrace) { task_trace_start(task, tracefile); } for ( ; task->out[0] == 0.0 && task->timestamp < 3000000; task->timestamp++) { app(task, userdata); if (dotrace) task_trace_step(task); ovm_step(task->scenario, task->in, task->out); } task->finished = TRUE; app(task, userdata); if (dotrace) task_trace_end(task); return task->out[0]; } static inline void task_main(int argc, char **argv, task_app_t app, task_app_t debug_app, gpointer userdata, guint default_scenario) { GError *error = NULL; GOptionContext *context; gboolean res; gdouble score; task_t *task; guint scenario = default_scenario; const gchar *tracefile = NULL; const gchar *simulate_file = NULL; gboolean debug = FALSE, do_nothing = FALSE; GOptionEntry entries[] = { { "scenario", 's', 0, G_OPTION_ARG_INT, &scenario, "run scenario", "number" }, { "simulate", 'm', 0, G_OPTION_ARG_FILENAME, &simulate_file, "Save trace in file", "PATH" }, { "trace", 't', 0, G_OPTION_ARG_FILENAME, &tracefile, "Run input data (trace from another run)", "PATH" }, { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Show debug", NULL }, { "nothing", 'n', 0, G_OPTION_ARG_NONE, &do_nothing, "Do nothing", NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL } }; context = g_option_context_new("- ovm task runner"); g_option_context_add_main_entries(context, entries, NULL); res = g_option_context_parse(context, &argc, &argv, &error); g_option_context_free(context); if (!res) { g_printerr("failed to parse command line arguments: %s\n", error->message); g_error_free(error); exit(1); } if (simulate_file) { trace_t *trace = trace_load(simulate_file); userdata = trace; app = trace_simulate; scenario = trace->scenario; fprintf(stderr, "Simulating solution: Team #%u, Scenario %u\n\n", (guint) trace->team, (guint) trace->scenario); } else if (debug) { app = debug_app; } else if (do_nothing) { app = task_do_nothing; } task = task_new(scenario); score = task_run(task, app, userdata, tracefile); fprintf(stderr, "Finale score: %f (steps: %u)\n", score, (guint) task->timestamp); fprintf(stderr, "Fuel: %f, Position: %f/%f\n", task->out[1], task->out[2], task->out[3]); task_free(task); } #endif