service_mapper: fixes problems with saves when updating from services tab

Fixes #1999
This commit is contained in:
Adam Sutton 2014-03-14 22:51:06 +00:00
parent 5322bf6ba7
commit d328f74497
5 changed files with 54 additions and 32 deletions

View file

@ -424,7 +424,7 @@ channel_set_services_by_list ( channel_t *ch, htsmsg_t *svcs )
const char *str;
service_t *svc;
htsmsg_field_t *f;
channel_service_mapping_t *csm, *n;
channel_service_mapping_t *csm;
/* Mark all for deletion */
LIST_FOREACH(csm, &ch->ch_services, csm_chn_link)
@ -434,19 +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);
save |= service_mapper_link(svc, ch, 0);
}
/* Remove */
for (csm = LIST_FIRST(&ch->ch_services); csm != NULL; csm = n) {
n = LIST_NEXT(csm, csm_chn_link);
if (csm->csm_mark) {
LIST_REMOVE(csm, csm_chn_link);
LIST_REMOVE(csm, csm_svc_link);
free(csm);
save = 1;
}
}
save |= service_mapper_clean(NULL, ch, 0);
return save;
}
@ -567,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);
service_mapper_unlink(csm->csm_svc, ch, 0);
/* Subscriptions */
while((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) {

View file

@ -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);
service_mapper_link((service_t*)s, c, 0);
}
return s;
}

View file

@ -89,7 +89,7 @@ service_class_channel_set
const char *str;
htsmsg_field_t *f;
channel_t *ch;
channel_service_mapping_t *csm, *n;
channel_service_mapping_t *csm;
/* Mark all for deletion */
LIST_FOREACH(csm, &svc->s_channels, csm_svc_link)
@ -99,19 +99,11 @@ 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);
save |= service_mapper_link(svc, ch, 1);
}
/* Delete unlinked */
for (csm = LIST_FIRST(&svc->s_channels); csm != NULL; csm = n ) {
n = LIST_NEXT(csm, csm_svc_link);
if (csm->csm_mark) {
save = 1;
LIST_REMOVE(csm, csm_chn_link);
LIST_REMOVE(csm, csm_svc_link);
free(csm);
}
}
service_mapper_clean(svc, NULL, 1);
return save;
}

View file

@ -178,7 +178,7 @@ service_mapper_remove ( service_t *s )
* Link service and channel
*/
int
service_mapper_link ( service_t *s, channel_t *c )
service_mapper_link ( service_t *s, channel_t *c, int dosave )
{
channel_service_mapping_t *csm;
@ -200,25 +200,50 @@ service_mapper_link ( service_t *s, channel_t *c )
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);
return 1;
}
static void
service_mapper_unlink0 ( channel_service_mapping_t *csm, int save )
{
if (save) channel_save(csm->csm_chn);
LIST_REMOVE(csm, csm_chn_link);
LIST_REMOVE(csm, csm_svc_link);
free(csm);
}
void
service_mapper_unlink ( service_t *s, channel_t *c )
service_mapper_unlink ( service_t *s, channel_t *c, int save )
{
channel_service_mapping_t *csm;
/* Unlink */
LIST_FOREACH(csm, &s->s_channels, csm_svc_link) {
if (csm->csm_chn == c) {
LIST_REMOVE(csm, csm_chn_link);
LIST_REMOVE(csm, csm_svc_link);
free(csm);
service_mapper_unlink0(csm, save);
break;
}
}
}
int
service_mapper_clean ( service_t *s, channel_t *c, int dosave )
{
int save = 0;
channel_service_mapping_t *csm, *n;
csm = s ? LIST_FIRST(&s->s_channels) : LIST_FIRST(&c->ch_services);
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);
save = 1;
}
}
return save;
}
/*
* Process a service
*/
@ -250,7 +275,7 @@ service_mapper_process ( service_t *s )
/* Map */
if (chn) {
const char *prov;
service_mapper_link(s, chn);
service_mapper_link(s, chn, 0);
/* Type tags */
if (service_is_hdtv(s)) {

View file

@ -53,9 +53,22 @@ 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 service_mapper_link ( struct service *s, struct channel *c, int save );
// Unlink service from channel
void service_mapper_unlink ( struct service *s, struct channel *c );
void service_mapper_unlink ( struct service *s, struct channel *c, int save );
/**
* 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
*
* @return 1 if changes were made, else 0
*/
int service_mapper_clean ( struct service *s, struct channel *ch, int save );
#endif /* __TVH_SERVICE_MAPPER_H__ */