95 lines
2.7 KiB
C
95 lines
2.7 KiB
C
#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)
|
|
task->in[te->data[i].addr] = te->data[i].value;
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
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 },
|
|
{ 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;
|
|
}
|
|
|
|
task = task_new(scenario);
|
|
score = task_run(task, app, userdata, tracefile);
|
|
fprintf(stderr, "Finale score: %f\n", score);
|
|
task_free(task);
|
|
}
|
|
|
|
#endif |