return curr;
}
+enum attr_type
+attr_type_begin(enum attr_type type)
+{
+ if (type < attr_type_item_begin)
+ return attr_none;
+ if (type < attr_type_int_begin)
+ return attr_type_item_begin;
+ if (type < attr_type_string_begin)
+ return attr_type_int_begin;
+ if (type < attr_type_special_begin)
+ return attr_type_string_begin;
+ if (type < attr_type_double_begin)
+ return attr_type_special_begin;
+ if (type < attr_type_coord_geo_begin)
+ return attr_type_double_begin;
+ if (type < attr_type_color_begin)
+ return attr_type_coord_geo_begin;
+ if (type < attr_type_object_begin)
+ return attr_type_color_begin;
+ if (type < attr_type_coord_begin)
+ return attr_type_object_begin;
+ if (type < attr_type_pcoord_begin)
+ return attr_type_coord_begin;
+ if (type < attr_type_callback_begin)
+ return attr_type_pcoord_begin;
+ if (type < attr_type_int64_begin)
+ return attr_type_callback_begin;
+ if (type <= attr_type_int64_end)
+ return attr_type_int64_begin;
+ return attr_none;
+}
+
int
attr_data_size(struct attr *attr)
{
ATTR(pitch)
ATTR(roll)
ATTR(yaw)
+ATTR(route_status)
ATTR2(0x00028000,type_boolean_begin)
/* boolean */
ATTR(overwrite)
ATTR(county_name)
ATTR(state_name)
ATTR(message)
+ATTR(callbacks)
+ATTR(enable_expression)
ATTR2(0x0003ffff,type_string_end)
ATTR2(0x00040000,type_special_begin)
ATTR(order)
#include "item.h"
#include "attr.h"
#include "layout.h"
+#include "command.h"
static DBusConnection *connection;
return empty_reply(connection, message);
}
+static DBusHandlerResult
+request_navit_evaluate(DBusConnection *connection, DBusMessage *message)
+{
+ struct pcoord pc;
+ struct navit *navit;
+ char *command;
+ char *result;
+ struct attr attr;
+ DBusMessage *reply;
+ int error;
+
+ navit = object_get_from_message(message, "navit");
+ if (! navit)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ attr.type=attr_navit;
+ attr.u.navit=navit;
+ if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &command, DBUS_TYPE_INVALID))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ result=command_evaluate_to_string(&attr, command, &error);
+ reply = dbus_message_new_method_return(message);
+ if (error)
+ dbus_message_append_args(reply, DBUS_TYPE_INT32, &error, DBUS_TYPE_INVALID);
+ else
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
struct dbus_method {
char *path;
char *method;
{".navit", "set_destination", "ss", "coordinates,comment", "", "", request_navit_set_destination},
{".navit", "set_destination", "(is)s", "(projection,coordinates)comment", "", "", request_navit_set_destination},
{".navit", "set_destination", "(iii)s", "(projection,longitude,latitude)comment", "", "", request_navit_set_destination},
+ {".navit", "evaluate", "s", "command", "s", "", request_navit_evaluate},
#if 0
{".navit", "toggle_announcer", "", "", "", "", request_navit_toggle_announcer},
{".navit", "toggle_announcer", "i", "", "", "", request_navit_toggle_announcer},
--- /dev/null
+#! /usr/bin/python
+import dbus
+import sys
+bus = dbus.SessionBus()
+conn = bus.get_object('org.navit_project.navit',
+ '/org/navit_project/navit')
+iface = dbus.Interface(conn, dbus_interface='org.navit_project.navit');
+iter=iface.iter();
+navit=bus.get_object('org.navit_project.navit', conn.get_navit(iter));
+iface.iter_destroy(iter);
+navit_iface = dbus.Interface(navit, dbus_interface='org.navit_project.navit.navit');
+print navit_iface.evaluate(sys.argv[1]);
-
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
int varlen;
char *attrn;
int attrnlen;
+ int allocated;
};
struct context {
static void eval_comma(struct context *ctx, struct result *res);
static struct attr ** eval_list(struct context *ctx);
+static void
+result_free(struct result *res)
+{
+}
+
static char *
get_op(struct context *ctx, int test, ...)
{
static void
set_double(struct context *ctx, struct result *res, double val)
{
+ result_free(res);
res->val=val;
}
static void
set_int(struct context *ctx, struct result *res, int val)
{
+ result_free(res);
res->attr.type=attr_type_int_begin;
res->attr.u.num=val;
}
static void
eval_value(struct context *ctx, struct result *res) {
char *op;
- int dots=0;
+ int len,dots=0;
op=ctx->expr;
res->varlen=0;
res->var=NULL;
return;
}
if ((op[0] >= '0' && op[0] <= '9') ||
- (op[0] == '.' && op[1] >= '0' && op[1] <= '9')) {
- while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.') {
+ (op[0] == '.' && op[1] >= '0' && op[1] <= '9') ||
+ (op[0] == '-' && op[1] >= '0' && op[1] <= '9') ||
+ (op[0] == '-' && op[1] == '.' && op[2] >= '0' && op[2] <= '9')) {
+ while ((op[0] >= '0' && op[0] <= '9') || op[0] == '.' || (res->varlen == 0 && op[0] == '-')) {
if (op[0] == '.')
dots++;
if (dots > 1) {
ctx->expr=op;
return;
}
+ if (op[0] == '"') {
+ do {
+ op++;
+ } while (op[0] != '"');
+ res->attr.type=attr_type_string_begin;
+ len=op-ctx->expr-1;
+ res->attr.u.str=g_malloc(len+1);
+ strncpy(res->attr.u.str, ctx->expr+1, len);
+ res->attr.u.str[len]='\0';
+ op++;
+ ctx->expr=op;
+ return;
+ }
ctx->error=illegal_character;
}
set_int(ctx, res, (get_int(ctx, res) == get_int(ctx, &tmp)));
else
set_int(ctx, res, (get_int(ctx, res) != get_int(ctx, &tmp)));
+ result_free(&tmp);
}
}
#endif
void
-command_evaluate_to_void(struct attr *attr, char *expr)
+command_evaluate_to(struct attr *attr, char *expr, struct context *ctx, struct result *res)
+{
+ memset(res, 0, sizeof(*res));
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->attr=attr;
+ ctx->expr=expr;
+ eval_comma(ctx,res);
+}
+
+void
+command_evaluate_to_void(struct attr *attr, char *expr, int **error)
{
struct result res;
struct context ctx;
- memset(&res, 0, sizeof(res));
- memset(&ctx, 0, sizeof(ctx));
- ctx.attr=attr;
- ctx.error=0;
- ctx.expr=expr;
- eval_comma(&ctx,&res);
- resolve(&ctx, &res, NULL);
+ command_evaluate_to(attr, expr, &ctx, &res);
+ if (!ctx.error)
+ resolve(&ctx, &res, NULL);
+ if (error)
+ *error=ctx.error;
+
+}
+
+char *
+command_evaluate_to_string(struct attr *attr, char *expr, int **error)
+{
+ struct result res;
+ struct context ctx;
+ char *ret;
+
+ command_evaluate_to(attr, expr, &ctx, &res);
+ if (error)
+ *error=ctx.error;
+ if (!ctx.error)
+ ret=get_string(&ctx, &res);
+ if (ctx.error)
+ return NULL;
+ else
+ return ret;
}
void
#define command_cast(x) (int (*)(void *, char *, struct attr **, struct attr ***))(x)
-void command_evaluate_to_void(struct attr *attr, char *expr);
+void command_evaluate_to_void(struct attr *attr, char *expr, int **error);
+char *command_evaluate_to_string(struct attr *attr, char *expr, int **error);
+int command_evaluate_to_int(struct attr *attr, char *expr, int **error);
void command_evaluate(struct attr *attr, char *expr);
void command_add_table(struct callback_list *cbl, struct command_table *table, int count, void *data);
}
static void
-navigation_update(struct navigation *this_, int mode)
+navigation_update(struct navigation *this_, struct route *route, struct attr *attr)
{
struct map *map;
struct map_rect *mr;
struct item *sitem; /* Holds the corresponding item from the actual map */
struct attr street_item,street_direction;
struct navigation_itm *itm;
- int incr=0,first=1;
+ int mode,incr=0,first=1;
+ if (attr->type != attr_route_status)
+ return;
dbg(1,"enter %d\n", mode);
- if (mode < 2 || mode == 4)
+ if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new)
navigation_flush(this_);
- if (mode < 2)
+ if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental)
return;
if (! this_->route)
void
navigation_set_route(struct navigation *this_, struct route *route)
{
+ struct attr callback;
this_->route=route;
- this_->route_cb=callback_new_attr_1(callback_cast(navigation_update), attr_route, this_);
- route_add_callback(route, this_->route_cb);
+ this_->route_cb=callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_);
+ callback.type=attr_callback;
+ callback.u.callback=this_->route_cb;
+ route_add_attr(route, &callback);
}
void
}
static void
-navit_redraw_route(struct navit *this_, int updated)
+navit_redraw_route(struct navit *this_, struct route *route, struct attr *attr)
{
- dbg(1,"enter %d\n", updated);
+ int updated;
+ if (attr->type != attr_route_status)
+ return;
+ updated=attr->u.num;
if (this_->ready != 3)
return;
- if (updated <= 3)
+ if (updated != route_status_path_done_new)
return;
if (this_->vehicle) {
if (this_->vehicle->follow_curr == 1)
navit_add_former_destinations_from_file(this_);
}
if (this_->route) {
- this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route, this_);
- route_add_callback(this_->route, this_->route_cb);
+ struct attr callback;
+ this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
+ callback.type=attr_callback;
+ callback.u.callback=this_->route_cb;
+ route_add_attr(this_->route, &callback);
}
if (this_->navigation) {
if (this_->speech) {
{
struct message *msg;
int len,offset;
+ int ret=1;
switch (type) {
case attr_message:
break;
case attr_graphics:
attr->u.graphics=this_->gra;
- return (attr->u.graphics != NULL);
+ ret=(attr->u.graphics != NULL);
+ break;
case attr_gui:
attr->u.gui=this_->gui;
+ ret=(attr->u.gui != NULL);
break;
case attr_layout:
if (iter) {
return 0;
}
attr->type=type;
- return 1;
+ return ret;
}
static int
struct map *graph_map;
struct callback * route_graph_done_cb ; /**< Callback when route graph is done */
struct callback * route_graph_flood_done_cb ; /**< Callback when route graph flooding is done */
- struct callback_list *cbl; /**< Callback list to call when route changes */
+ struct callback_list *cbl2; /**< Callback list to call when route changes */
int destination_distance; /**< Distance to the destination at which the destination is considered "reached" */
struct route_preferences preferences; /**< Routing preferences */
+ int route_status; /**< Route Status */
};
/**
} else {
this->destination_distance = 50; // Default value
}
- this->cbl=callback_list_new();
+ this->cbl2=callback_list_new();
this->preferences.flags_forward_mask=AF_ONEWAYREV|AF_CAR;
this->preferences.flags_reverse_mask=AF_ONEWAY|AF_CAR;
this->preferences.flags=AF_CAR;
route_path_update_done(struct route *this, int new_graph)
{
struct route_path *oldpath=this->path2;
- int val;
+ struct attr route_status;
+ route_status.type=attr_route_status;
if (this->path2 && this->path2->in_use) {
this->path2->update_required=1+new_graph;
return;
}
+ route_status.u.num=route_status_building_path;
+ route_set_attr(this, &route_status);
this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, &this->preferences);
route_path_destroy(oldpath);
if (this->path2) {
- if (new_graph)
- val=4;
+ if (!new_graph && this->path2->updated)
+ route_status.u.num=route_status_path_done_incremental;
else
- val=2+!this->path2->updated;
+ route_status.u.num=route_status_path_done_new;
} else
- val=1;
- callback_list_call_attr_1(this->cbl, attr_route, (void *)val);
+ route_status.u.num=route_status_not_found;
+ route_set_attr(this, &route_status);
}
/**
this->dst=route_find_nearest_street(this->ms, dst);
if(this->dst)
route_info_distances(this->dst, dst->pro);
- } else
- callback_list_call_attr_1(this->cbl, attr_route, (void *)0);
+ } else {
+ struct attr route_status;
+ route_status.type=attr_route_status;
+ route_status.u.num=route_status_no_destination;
+ route_set_attr(this, &route_status);
+ }
profile(1,"find_nearest_street");
/* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */
struct route_path_segment *segment;
int seg_size,seg_dat_size;
- dbg(0,"line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x, end->y);
+ dbg(1,"line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x, end->y);
seg_size=sizeof(*segment) + sizeof(struct coord) * ccnt;
seg_dat_size=sizeof(struct route_segment_data);
segment=g_malloc0(seg_size + seg_dat_size);
route_path_add_item_from_graph(struct route_path *this, struct route_path *oldpath, struct route_graph_segment *rgs, int dir, struct route_info *pos, struct route_info *dst)
{
struct route_path_segment *segment;
- int i, ccnt, extra=0, ret=1;
+ int i, ccnt, extra=0, ret=0;
struct coord *c,*cd,ca[2048];
int offset=1;
int seg_size,seg_dat_size;
offset=RSD_OFFSET(&rgs->data);
dbg(1,"enter (0x%x,0x%x) dir=%d pos=%p dst=%p\n", rgs->data.item.id_hi, rgs->data.item.id_lo, dir, pos, dst);
- if (oldpath && !pos) {
+ if (oldpath) {
segment=item_hash_lookup(oldpath->path_hash, &rgs->data.item);
if (segment && segment->direction == dir) {
segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset);
- if (segment)
- goto linkold;
+ if (segment) {
+ ret=1;
+ if (!pos)
+ goto linkold;
+ }
}
}
route_check_roundabout(rgs, 13, (dir < 1), NULL);
}
- ret=0;
memcpy(segment->data, &rgs->data, seg_dat_size);
linkold:
static void
route_graph_update(struct route *this, struct callback *cb)
{
+ struct attr route_status;
+
+ route_status.type=attr_route_status;
route_graph_destroy(this->graph);
callback_destroy(this->route_graph_done_cb);
this->route_graph_done_cb=callback_new_2(callback_cast(route_graph_update_done), this, cb);
- callback_list_call_attr_1(this->cbl, attr_route, (void *)0);
+ route_status.u.num=route_status_building_graph;
+ route_set_attr(this, &route_status);
this->graph=route_graph_build(this->ms, &this->pos->c, &this->dst->c, this->route_graph_done_cb);
}
{
}
-void
-route_add_callback(struct route *this_, struct callback *cb)
+int
+route_set_attr(struct route *this_, struct attr *attr)
+{
+ int attr_updated=0;
+ switch (attr->type) {
+ case attr_route_status:
+ attr_updated = (this_->route_status != attr->u.num);
+ this_->route_status = attr->u.num;
+ break;
+ default:
+ return 0;
+ }
+ if (attr_updated)
+ callback_list_call_attr_2(this_->cbl2, attr->type, this_, attr);
+ return 1;
+}
+
+int
+route_add_attr(struct route *this_, struct attr *attr)
{
- callback_list_add(this_->cbl, cb);
+ switch (attr->type) {
+ case attr_callback:
+ dbg(0,"add\n");
+ callback_list_add(this_->cbl2, attr->u.callback);
+ return 1;
+ default:
+ return 0;
+ }
}
-void
-route_remove_callback(struct route *this_, struct callback *cb)
+int
+route_remove_attr(struct route *this_, struct attr *attr)
{
- callback_list_remove(this_->cbl, cb);
+ switch (attr->type) {
+ case attr_callback:
+ callback_list_remove(this_->cbl2, attr->u.callback);
+ return 1;
+ default:
+ return 0;
+ }
}
int
route_get_attr(struct route *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
{
+ int ret=1;
switch (type) {
case attr_map:
attr->u.map=route_get_map(this_);
- return attr->u.map != NULL;
+ ret=(attr->u.map != NULL);
+ break;
+ case attr_route_status:
+ attr->u.num=this_->route_status;
+ break;
default:
return 0;
}
+ attr->type=type;
+ return ret;
}
+
void
route_init(void)
{
#ifndef NAVIT_ROUTE_H
#define NAVIT_ROUTE_H
+enum route_status {
+ route_status_no_destination=0,
+ route_status_not_found=1|2,
+ route_status_building_path=1|4,
+ route_status_building_graph=1|4|8,
+ route_status_path_done_new=1|16,
+ route_status_path_done_incremental=1|32,
+};
+
struct route_crossing {
long segid;
int dir;
void route_toggle_routegraph_display(struct route *route);
void route_set_projection(struct route *this_, enum projection pro);
int route_destination_reached(struct route *this);
-void route_add_callback(struct route *this_, struct callback *cb);
-void route_remove_callback(struct route *this_, struct callback *cb);
+int route_set_attr(struct route *this_, struct attr *attr);
+int route_add_attr(struct route *this_, struct attr *attr);
+int route_remove_attr(struct route *this_, struct attr *attr);
+int route_get_attr(struct route *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
void route_init(void);
int route_pos_contains(struct route *this, struct item *item);
struct coord route_get_coord_dist(struct route *this_, int dist);
{ attr_plugin, NEW(plugin_new)},
{ attr_polygon, NEW(polygon_new), NULL, NULL, NULL, NULL, ADD(element_add_attr)},
{ attr_polyline, NEW(polyline_new), NULL, NULL, NULL, NULL, ADD(element_add_attr)},
- { attr_route, NEW(route_new)},
+ { attr_route, NEW(route_new), GET(route_get_attr)},
{ attr_speech, NEW(speech_new), GET(speech_get_attr), NULL, NULL, SET(speech_set_attr)},
{ attr_text, NEW(text_new)},
{ attr_tracking, NEW(tracking_new)},