Clean up code

feature/trainlines-wip
Markus Koch 2020-05-02 16:51:12 +02:00
parent 25ccfc5df5
commit 0d2945d76f
5 changed files with 135 additions and 112 deletions

View File

@ -4,6 +4,7 @@
#include <math.h>
#define FP_THRESHOLD 0.01
int dijkstra_node_same (struct dijkstra_node *node_a,
struct dijkstra_node *node_b)
{
@ -16,6 +17,27 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
return same;
}
/*!
* \brief dijkstra_node_new creates a new dijkstra_node
* \param x x position
* \param y y position
* \return a new dijkstra node or NULL. Needs to be freed manually.
*/
struct dijkstra_node *dijkstra_node_new(float x,
float y)
{
struct dijkstra_node *node;
node = malloc(sizeof(*node));
if (node) {
node->position.x = x;
node->position.y = y;
node->paths = NULL;
}
return node;
}
struct dijkstra_node *dijkstra_node_exists(GList *list,
struct dijkstra_node *node)
{
@ -125,6 +147,29 @@ struct dijkstra_path *dijkstra_path_dup_shallow(struct dijkstra_path *path)
return dup;
}
/*!
* \brief dijkstra_path_new creates a new dijkstra_path between two nodes.
* \param name the name of the path (pointer is not copied and must stay valid!)
* \return a new dijkstra path or NULL. Needs to be freed manually.
*/
struct dijkstra_path *dijkstra_path_new(char *name,
struct dijkstra_node *source,
struct dijkstra_node *destination,
dijkstra_cost weight)
{
struct dijkstra_path *path;
path = malloc(sizeof(*path));
if (path) {
path->name = name;
path->weight = weight;
dijkstra_connect_nodes_to_path(source, destination, path);
}
return path;
}
struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *path,
struct dijkstra_node *node,
int ref_only)
@ -142,8 +187,7 @@ struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *p
return node;
}
int dijkstra_path_intersect(GList **nodes,
GList **paths,
int dijkstra_path_intersect(struct dijkstra_solver *solver,
struct dijkstra_path *path_a,
struct dijkstra_path *path_b)
{
@ -190,11 +234,11 @@ int dijkstra_path_intersect(GList **nodes,
i_x = p0_x + (t * s1_x);
i_y = p0_y + (t * s1_y);
node_new = dijkstra_node_new_to_list(nodes, i_x, i_y, &is_new);
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, &is_new);
if (node_new != path_a->source && node_new != path_a->destination) {
path_new = dijkstra_path_dup_shallow(path_a);
*paths = g_list_append(*paths, (gpointer) path_new);
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
dijkstra_disconnect_node_from_path(path_a, path_a->destination, 1);
dijkstra_connect_destination_node_to_path(node_new, path_a);
@ -204,7 +248,7 @@ int dijkstra_path_intersect(GList **nodes,
// Now do the same thing for path b
if (node_new != path_b->source && node_new != path_b->destination) {
path_new = dijkstra_path_dup_shallow(path_b);
*paths = g_list_append(*paths, (gpointer) path_new);
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
dijkstra_disconnect_node_from_path(path_b, path_b->destination, 1);
dijkstra_connect_destination_node_to_path(node_new, path_b);
dijkstra_connect_source_node_to_path(node_new, path_new);
@ -215,8 +259,7 @@ int dijkstra_path_intersect(GList **nodes,
return 0; // No collision
}
struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
GList **paths,
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
float x1,
float y1,
float x2,
@ -229,16 +272,16 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
struct dijkstra_path *existing_path;
GList *l, *l_last;
n1 = dijkstra_node_new_to_list(nodes, x1, y1, NULL);
n2 = dijkstra_node_new_to_list(nodes, x2, y2, NULL);
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, NULL);
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, NULL);
path = dijkstra_path_new(name, n1, n2, weight);
l_last = g_list_last(*paths);
*paths = g_list_append(*paths, (gpointer) path);
l_last = g_list_last(solver->paths);
solver->paths = g_list_append(solver->paths, (gpointer) path);
for (l = *paths; l != NULL; l = l->next) {
for (l = solver->paths; l != NULL; l = l->next) {
existing_path = (struct dijkstra_path*) l->data;
dijkstra_path_intersect(nodes, paths, path, existing_path);
dijkstra_path_intersect(solver, path, existing_path);
if (l == l_last) /* Avoid testing newly added paths */
break;
}
@ -246,46 +289,39 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
return path;
}
/*!
* \brief dijkstra_node_new creates a new dijkstra_node
* \param x x position
* \param y y position
* \return a new dijkstra node or NULL. Needs to be freed manually.
*/
struct dijkstra_node *dijkstra_node_new(float x,
float y)
struct dijkstra_solver *dijkstra_solver_new()
{
struct dijkstra_solver *solver;
solver = malloc(sizeof(*solver));
if (solver) {
solver->nodes = NULL;
solver->paths = NULL;
}
return solver;
}
void dijkstra_solver_free(struct dijkstra_solver *solver)
{
GList *l;
struct dijkstra_path *path;
struct dijkstra_node *node;
node = malloc(sizeof(*node));
if (node) {
node->position.x = x;
node->position.y = y;
node->paths = NULL;
// Free memory
for (l = solver->paths; l != NULL; l = l->next) {
path = (struct dijkstra_path*) l->data;
// TODO: free(path->name);
// Currently, we reuse the existing memory block when for the
// name when cloning streets. As such, clearing it here will
// cause a double free if the street has been split.
free(path);
}
g_list_free(solver->paths);
return node;
}
/*!
* \brief dijkstra_path_new creates a new dijkstra_path between two nodes.
* \param name the name of the path (pointer is not copied and must stay valid!)
* \return a new dijkstra path or NULL. Needs to be freed manually.
*/
struct dijkstra_path *dijkstra_path_new(char *name,
struct dijkstra_node *source,
struct dijkstra_node *destination,
dijkstra_cost weight)
{
struct dijkstra_path *path;
path = malloc(sizeof(*path));
if (path) {
path->name = name;
path->weight = weight;
dijkstra_connect_nodes_to_path(source, destination, path);
for (l = solver->nodes; l != NULL; l = l->next) {
node = (struct dijkstra_node*) l->data;
free(node);
}
return path;
g_list_free(solver->nodes);
}

View File

@ -5,6 +5,16 @@
typedef int dijkstra_cost;
struct dijkstra_solver {
GList *nodes;
GList *paths;
};
struct dijkstra_state {
dijkstra_cost cost;
int visited;
};
struct position {
float x;
float y;
@ -22,27 +32,18 @@ struct dijkstra_node {
GList *paths;
dijkstra_cost cost;
int uid;
};
struct dijkstra_node *dijkstra_node_new(float x,
float y);
struct dijkstra_path *dijkstra_path_new(char *name,
struct dijkstra_node *source,
struct dijkstra_node *destination,
dijkstra_cost weight);
int dijkstra_path_intersect(GList **nodes,
GList **paths,
struct dijkstra_path *path_a,
struct dijkstra_path *path_b);
struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
GList **paths,
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
float x1,
float y1,
float x2,
float y2,
char *name,
dijkstra_cost weight);
struct dijkstra_solver *dijkstra_solver_new();
void dijkstra_solver_free(struct dijkstra_solver *solver);
#endif // DIJKSTRASEARCH_H

View File

@ -6,8 +6,7 @@
#include <glib-object.h>
#include <json-glib/json-glib.h>
int add_geojson_to_dijkstra(GList **nodes,
GList **paths,
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
char *filename)
{
JsonParser *parser;
@ -81,7 +80,7 @@ int add_geojson_to_dijkstra(GList **nodes,
if (j > 0) {
stats.paths++;
dijkstra_path_new_to_list(nodes, paths,
dijkstra_path_new_to_list(solver,
x_last, y_last,
x, y,
name, 1);

View File

@ -2,9 +2,9 @@
#define GEOJSON_H
#include <glib.h>
#include "dijkstrasearch.h"
int add_geojson_to_dijkstra(GList **nodes,
GList **paths,
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
char *filename);
#endif // GEOJSON_H

View File

@ -7,18 +7,15 @@
#include "geojson.h"
#include "logging.h"
void add_test_map(GList **nodes,
GList **paths)
void add_test_map(struct dijkstra_solver *solver)
{
dijkstra_path_new_to_list(nodes,
paths,
dijkstra_path_new_to_list(solver,
0,0,
0,10,
"Vertical",
1);
dijkstra_path_new_to_list(nodes,
paths,
dijkstra_path_new_to_list(solver,
0,5,
10,5,
"Horizontal",
@ -41,8 +38,7 @@ int main(int argc, char *argv[])
int opt;
int i;
GList *nodes = NULL;
GList *paths = NULL;
struct dijkstra_solver *solver;
GList *l = NULL;
struct dijkstra_node *node;
@ -53,20 +49,20 @@ int main(int argc, char *argv[])
// Process arguments
while((opt = getopt(argc, argv, "vs")) != -1) {
switch(opt)
{
case 'v':
set_log_level(get_log_level() + 1);
break;
case 's':
set_log_level(0);
break;
case ':':
case '?':
help(argv[0]);
return 1;
default:
break;
}
{
case 'v':
set_log_level(get_log_level() + 1);
break;
case 's':
set_log_level(0);
break;
case ':':
case '?':
help(argv[0]);
return 1;
default:
break;
}
}
if (optind == argc) {
@ -74,21 +70,27 @@ int main(int argc, char *argv[])
return 1;
}
solver = dijkstra_solver_new();
if (!solver) {
report(LL_CRITICAL, "Memory allocation failure.");
return 2;
}
/* Parse file list */
for (i = optind; i < argc; ++i) {
add_geojson_to_dijkstra(&nodes, &paths, argv[i]);
add_geojson_to_dijkstra(solver, argv[i]);
}
// add_test_map(&nodes, &paths);
if (should_report(LL_NOISY)) {
for (l = nodes; l != NULL; l = l->next) {
for (l = solver->nodes; l != NULL; l = l->next) {
node = (struct dijkstra_node*) l->data;
printf("Node %p: %f,\t%f [%d paths]\n", node, node->position.x, node->position.y, g_list_length(node->paths));
}
printf("\n");
for (l = paths; l != NULL; l = l->next) {
for (l = solver->paths; l != NULL; l = l->next) {
path = (struct dijkstra_path*) l->data;
printf("Path %p: %p (%f,%f) -> %p (%f,%f) \t\"%s\"\n", path,
path->source, path->source->position.x, path->source->position.y,
@ -99,25 +101,10 @@ int main(int argc, char *argv[])
}
report(LL_INFO, "Created graph with %d nodes and %d paths.",
g_list_length(nodes),
g_list_length(paths));
g_list_length(solver->nodes),
g_list_length(solver->paths));
// Free memory
for (l = paths; l != NULL; l = l->next) {
path = (struct dijkstra_path*) l->data;
// TODO: free(path->name);
// Currently, we reuse the existing memory block when for the
// name when cloning streets. As such, clearing it here will
// cause a double free if the street has been split.
free(path);
}
g_list_free(paths);
for (l = nodes; l != NULL; l = l->next) {
node = (struct dijkstra_node*) l->data;
free(node);
}
g_list_free(nodes);
dijkstra_solver_free(solver);
return 0;
}