bouquet: use hard channel tag link to allow tag renaming

This commit is contained in:
Jaroslav Kysela 2014-11-02 19:04:30 +01:00
parent 75cdc2831b
commit 8812f5c51c
3 changed files with 96 additions and 3 deletions

View file

@ -98,6 +98,8 @@ bouquet_destroy(bouquet_t *bq)
idnode_set_free(bq->bq_active_services);
idnode_set_free(bq->bq_services);
assert(bq->bq_services_waiting == NULL);
free((char *)bq->bq_chtag_waiting);
free(bq->bq_name);
free(bq->bq_src);
free(bq);
@ -118,6 +120,21 @@ bouquet_destroy_by_service(service_t *t)
idnode_set_remove(bq->bq_services, &t->s_id);
}
/**
*
*/
void
bouquet_destroy_by_channel_tag(channel_tag_t *ct)
{
bouquet_t *bq;
lock_assert(&global_lock);
RB_FOREACH(bq, &bouquets, bq_link)
if (bq->bq_chtag_ptr == ct)
bq->bq_chtag_ptr = NULL;
}
/*
*
*/
@ -146,10 +163,24 @@ bouquet_find_by_source(const char *name, const char *src, int create)
static channel_tag_t *
bouquet_tag(bouquet_t *bq, int create)
{
channel_tag_t *ct;
char buf[128];
/* TODO: cache the channel_tag_t * pointer */
assert(!bq->bq_in_load);
if (bq->bq_chtag_waiting) {
bq->bq_chtag_ptr = channel_tag_find_by_uuid(bq->bq_chtag_waiting);
free((char *)bq->bq_chtag_waiting);
bq->bq_chtag_waiting = NULL;
}
if (bq->bq_chtag_ptr)
return bq->bq_chtag_ptr;
snprintf(buf, sizeof(buf), "*** %s", bq->bq_name ?: "???");
return channel_tag_find_by_name(buf, create);
ct = channel_tag_find_by_name(buf, create);
if (ct) {
bq->bq_chtag_ptr = ct;
bouquet_save(bq, 0);
}
return ct;
}
/*
@ -386,6 +417,8 @@ bouquet_class_mapnolcn_notify ( void *obj )
service_t *t;
size_t z;
if (bq->bq_in_load)
return;
if (!bq->bq_mapnolcn && bq->bq_enabled && bq->bq_maptoch) {
for (z = 0; z < bq->bq_services->is_count; z++) {
t = (service_t *)bq->bq_services->is_array[z];
@ -404,6 +437,8 @@ bouquet_class_mapnoname_notify ( void *obj )
service_t *t;
size_t z;
if (bq->bq_in_load)
return;
if (!bq->bq_mapnoname && bq->bq_enabled && bq->bq_maptoch) {
for (z = 0; z < bq->bq_services->is_count; z++) {
t = (service_t *)bq->bq_services->is_array[z];
@ -424,6 +459,8 @@ bouquet_class_chtag_notify ( void *obj )
channel_tag_t *ct;
size_t z;
if (bq->bq_in_load)
return;
if (!bq->bq_chtag && bq->bq_enabled && bq->bq_maptoch) {
ct = bouquet_tag(bq, 0);
if (!ct)
@ -444,9 +481,46 @@ bouquet_class_chtag_notify ( void *obj )
static void
bouquet_class_lcn_offset_notify ( void *obj )
{
if (((bouquet_t *)obj)->bq_in_load)
return;
bouquet_notify_channels((bouquet_t *)obj);
}
static const void *
bouquet_class_chtag_ref_get ( void *obj )
{
static const char *buf;
bouquet_t *bq = obj;
if (bq->bq_chtag_ptr)
buf = idnode_uuid_as_str(&bq->bq_chtag_ptr->ct_id);
else
buf = "";
return &buf;
}
static char *
bouquet_class_chtag_ref_rend ( void *obj )
{
bouquet_t *bq = obj;
if (bq->bq_chtag_ptr)
return strdup(bq->bq_chtag_ptr->ct_name ?: "");
else
return strdup("");
}
static int
bouquet_class_chtag_ref_set ( void *obj, const void *p )
{
bouquet_t *bq = obj;
free((char *)bq->bq_chtag_waiting);
bq->bq_chtag_waiting = NULL;
if (bq->bq_in_load)
bq->bq_chtag_waiting = strdup((const char *)p);
return 0;
}
static const void *
bouquet_class_services_get ( void *obj )
{
@ -537,6 +611,15 @@ const idclass_t bouquet_class = {
.off = offsetof(bouquet_t, bq_chtag),
.notify = bouquet_class_chtag_notify,
},
{
.type = PT_STR,
.id = "chtag_ref",
.name = "Channel Tag Reference",
.get = bouquet_class_chtag_ref_get,
.set = bouquet_class_chtag_ref_set,
.rend = bouquet_class_chtag_ref_rend,
.opts = PO_RDONLY | PO_HIDDEN,
},
{
.type = PT_STR,
.id = "name",

View file

@ -22,6 +22,7 @@
#include "idnode.h"
#include "htsmsg.h"
#include "service.h"
#include "channels.h"
typedef struct bouquet {
idnode_t bq_id;
@ -37,6 +38,8 @@ typedef struct bouquet {
int bq_mapnolcn;
int bq_mapnoname;
int bq_chtag;
channel_tag_t*bq_chtag_ptr;
const char *bq_chtag_waiting;
char *bq_name;
char *bq_src;
char *bq_comment;
@ -63,6 +66,7 @@ bouquet_t * bouquet_create(const char *uuid, htsmsg_t *conf,
const char *name, const char *src);
void bouquet_destroy_by_service(service_t *t);
void bouquet_destroy_by_channel_tag(channel_tag_t *ct);
static inline bouquet_t *
bouquet_find_by_uuid(const char *uuid)

View file

@ -926,7 +926,12 @@ channel_tag_unmap(channel_t *ch, channel_tag_t *ct)
LIST_REMOVE(ctm, ctm_channel_link);
LIST_REMOVE(ctm, ctm_tag_link);
free(ctm);
channel_tag_save(ct);
channel_save(ch);
idnode_notify_simple(&ch->ch_id);
if (ct->ct_enabled && !ct->ct_internal) {
htsp_tag_update(ct);
htsp_channel_update(ch);
}
return;
}
}
@ -990,6 +995,7 @@ channel_tag_destroy(channel_tag_t *ct, int delconf)
TAILQ_REMOVE(&channel_tags, ct, ct_link);
idnode_unlink(&ct->ct_id);
bouquet_destroy_by_channel_tag(ct);
autorec_destroy_by_channel_tag(ct, delconf);
access_destroy_by_channel_tag(ct, delconf);