Modularized vehicle
[navit-package] / src / vehicle.c
1 #include <glib.h>
2 #include <string.h>
3 #include "config.h"
4 #include "debug.h"
5 #include "coord.h"
6 #include "item.h"
7 #include "log.h"
8 #include "callback.h"
9 #include "plugin.h"
10 #include "vehicle.h"
11
12 struct vehicle {
13         struct vehicle_priv *priv;
14         struct vehicle_methods meth;
15         struct callback_list *cbl;
16         struct log *nmea_log, *gpx_log, *textfile_log;
17 };
18
19 static int
20 vehicle_add_log(struct vehicle *this_, struct log *log,
21                 struct attr **attrs)
22 {
23         struct attr *type;
24         type = attr_search(attrs, NULL, attr_type);
25         if (!type)
26                 return 1;
27         if (!strcmp(type->u.str, "nmea")) {
28                 this_->nmea_log = log;
29         } else if (!strcmp(type->u.str, "gpx")) {
30                 char *header =
31                     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpx version=\"1.0\" creator=\"Navit http://navit.sourceforge.net\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n<trk>\n<trkseg>\n";
32                 char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
33                 this_->gpx_log = log;
34                 log_set_header(log, header, strlen(header));
35                 log_set_trailer(log, trailer, strlen(trailer));
36         } else if (!strcmp(type->u.str, "textfile")) {
37                 char *header = "type=track\n";
38                 this_->textfile_log = log;
39                 log_set_header(log, header, strlen(header));
40         } else
41                 return 1;
42         return 0;
43 }
44
45 struct vehicle *
46 vehicle_new(struct attr **attrs)
47 {
48         struct vehicle *this_;
49         struct attr *source;
50         struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods *
51                                                  meth,
52                                                  struct callback_list *
53                                                  cbl,
54                                                  struct attr ** attrs);
55         char *type, *colon;
56
57         dbg(0, "enter\n");
58         source = attr_search(attrs, NULL, attr_source);
59         if (!source) {
60                 dbg(0, "no source\n");
61                 return NULL;
62         }
63
64         type = g_strdup(source->u.str);
65         colon = index(type, ':');
66         if (colon)
67                 *colon = '\0';
68         dbg(0, "source='%s' type='%s'\n", source->u.str, type);
69
70         vehicletype_new = plugin_get_vehicle_type(type);
71         if (!vehicletype_new) {
72                 dbg(0, "invalid type\n");
73                 return NULL;
74         }
75         this_ = g_new0(struct vehicle, 1);
76         this_->cbl = callback_list_new();
77         this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
78         if (!this_->priv) {
79                 dbg(0, "vehicletype_new failed\n");
80                 callback_list_destroy(this_->cbl);
81                 g_free(this_);
82                 return NULL;
83         }
84         dbg(0, "leave\n");
85
86         return this_;
87 }
88
89 int
90 vehicle_position_attr_get(struct vehicle *this_, enum attr_type type,
91                           struct attr *attr)
92 {
93         if (this_->meth.position_attr_get)
94                 return this_->meth.position_attr_get(this_->priv, type,
95                                                      attr);
96         return 0;
97 }
98
99 int
100 vehicle_set_attr(struct vehicle *this_, struct attr *attr,
101                  struct attr **attrs)
102 {
103         return 0;
104 }
105
106 int
107 vehicle_add_attr(struct vehicle *this_, struct attr *attr,
108                  struct attr **attrs)
109 {
110         switch (attr->type) {
111         case attr_callback:
112                 callback_list_add(this_->cbl, attr->u.callback);
113                 break;
114         case attr_log:
115                 return vehicle_add_log(this_, attr->u.log, attrs);
116         default:
117                 return 0;
118         }
119         return 1;
120 }
121
122 int
123 vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
124 {
125         switch (attr->type) {
126         case attr_callback:
127                 callback_list_remove(this_->cbl, attr->u.callback);
128                 break;
129         default:
130                 return 0;
131         }
132         return 1;
133 }
134
135 void
136 vehicle_destroy(struct vehicle *this_)
137 {
138         callback_list_destroy(this_->cbl);
139         g_free(this_);
140 }