diff --git a/src/channels.c b/src/channels.c index 668bb09a..c1b86627 100644 --- a/src/channels.c +++ b/src/channels.c @@ -434,11 +434,11 @@ channel_set_services_by_list ( channel_t *ch, htsmsg_t *svcs ) HTSMSG_FOREACH(f, svcs) { if ((str = htsmsg_field_get_str(f))) if ((svc = service_find(str))) - save |= service_mapper_link(svc, ch, 0); + save |= service_mapper_link(svc, ch, ch); } /* Remove */ - save |= service_mapper_clean(NULL, ch, 0); + save |= service_mapper_clean(NULL, ch, ch); return save; } @@ -559,7 +559,7 @@ channel_delete ( channel_t *ch, int delconf ) /* Services */ while((csm = LIST_FIRST(&ch->ch_services)) != NULL) - service_mapper_unlink(csm->csm_svc, ch, 0); + service_mapper_unlink(csm->csm_svc, ch, ch); /* Subscriptions */ while((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) { diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index 938a0c1b..3e660e45 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -47,7 +47,7 @@ tsfile_network_create_service // TODO: HACK: REMOVE ME if (s) { channel_t *c = channel_create(NULL, NULL, NULL); - service_mapper_link((service_t*)s, c, 0); + service_mapper_link((service_t*)s, c, NULL); } return s; } diff --git a/src/service.c b/src/service.c index 5a250ef7..053b74fb 100644 --- a/src/service.c +++ b/src/service.c @@ -83,7 +83,6 @@ static int service_class_channel_set ( void *obj, const void *p ) { - int save = 0; service_t *svc = obj; htsmsg_t *chns = (htsmsg_t*)p; const char *str; @@ -99,13 +98,16 @@ service_class_channel_set HTSMSG_FOREACH(f, chns) { if ((str = htsmsg_field_get_str(f))) if ((ch = channel_find(str))) - save |= service_mapper_link(svc, ch, 1); + service_mapper_link(svc, ch, svc); } /* Delete unlinked */ - service_mapper_clean(svc, NULL, 1); - - return save; + service_mapper_clean(svc, NULL, svc); + + /* no save - the link information is in the saved channel record */ + /* only send a notify about the change to other clients */ + idnode_notify_simple(&svc->s_id); + return 0; } static htsmsg_t * diff --git a/src/service_mapper.c b/src/service_mapper.c index 349eee14..8f3ef301 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -174,11 +174,24 @@ service_mapper_remove ( service_t *s ) api_service_mapper_notify(); } +static void +service_mapper_notify ( channel_service_mapping_t *csm, void *origin ) +{ + if (origin == NULL) + return; + if (origin == csm->csm_svc) { + idnode_notify_simple(&csm->csm_chn->ch_id); + channel_save(csm->csm_chn); + } + if (origin == csm->csm_chn) + idnode_notify_simple(&csm->csm_svc->s_id); +} + /* * Link service and channel */ int -service_mapper_link ( service_t *s, channel_t *c, int dosave ) +service_mapper_link ( service_t *s, channel_t *c, void *origin ) { channel_service_mapping_t *csm; @@ -200,35 +213,35 @@ service_mapper_link ( service_t *s, channel_t *c, int dosave ) csm->csm_svc = s; LIST_INSERT_HEAD(&s->s_channels, csm, csm_svc_link); LIST_INSERT_HEAD(&c->ch_services, csm, csm_chn_link); - if (dosave) channel_save(c); + service_mapper_notify( csm, origin ); return 1; } static void -service_mapper_unlink0 ( channel_service_mapping_t *csm, int save ) +service_mapper_unlink0 ( channel_service_mapping_t *csm, void *origin ) { - if (save) channel_save(csm->csm_chn); LIST_REMOVE(csm, csm_chn_link); LIST_REMOVE(csm, csm_svc_link); + service_mapper_notify( csm, origin ); free(csm); } void -service_mapper_unlink ( service_t *s, channel_t *c, int save ) +service_mapper_unlink ( service_t *s, channel_t *c, void *origin ) { channel_service_mapping_t *csm; /* Unlink */ LIST_FOREACH(csm, &s->s_channels, csm_svc_link) { if (csm->csm_chn == c) { - service_mapper_unlink0(csm, save); + service_mapper_unlink0(csm, origin); break; } } } int -service_mapper_clean ( service_t *s, channel_t *c, int dosave ) +service_mapper_clean ( service_t *s, channel_t *c, void *origin ) { int save = 0; channel_service_mapping_t *csm, *n; @@ -237,7 +250,7 @@ service_mapper_clean ( service_t *s, channel_t *c, int dosave ) for (; csm != NULL; csm = n ) { n = s ? LIST_NEXT(csm, csm_svc_link) : LIST_NEXT(csm, csm_chn_link); if (csm->csm_mark) { - service_mapper_unlink0(csm, dosave); + service_mapper_unlink0(csm, origin); save = 1; } } @@ -275,7 +288,7 @@ service_mapper_process ( service_t *s ) /* Map */ if (chn) { const char *prov; - service_mapper_link(s, chn, 0); + service_mapper_link(s, chn, chn); /* Type tags */ if (service_is_hdtv(s)) { @@ -294,6 +307,7 @@ service_mapper_process ( service_t *s ) channel_tag_map(chn, channel_tag_find_by_name(prov, 1)); /* save */ + idnode_notify_simple(&chn->ch_id); channel_save(chn); } service_mapper_stat.ok++; diff --git a/src/service_mapper.h b/src/service_mapper.h index 8e54dd6e..43f23aef 100644 --- a/src/service_mapper.h +++ b/src/service_mapper.h @@ -53,22 +53,23 @@ void service_mapper_remove ( struct service *t ); service_mapper_status_t service_mapper_status ( void ); // Link service to channel -int service_mapper_link ( struct service *s, struct channel *c, int save ); +int service_mapper_link ( struct service *s, struct channel *c, void *origin ); // Unlink service from channel -void service_mapper_unlink ( struct service *s, struct channel *c, int save ); +void service_mapper_unlink ( struct service *s, struct channel *c, void *origin ); /** * Clean linkages that are marked for deletion * * Note: only ever pass one of s and c * - * @param s The service to clean linkages for - * @param c The channel to clean linkages for - * @parma save Force channel saves for affected channels + * @param s The service to clean linkages for + * @param c The channel to clean linkages for + * @parma origin Origin of the change (should be a service or a channel ptr). + * NULL = no save and notifications. * * @return 1 if changes were made, else 0 */ -int service_mapper_clean ( struct service *s, struct channel *ch, int save ); +int service_mapper_clean ( struct service *s, struct channel *ch, void *origin ); #endif /* __TVH_SERVICE_MAPPER_H__ */