if (lcn != tl->sl_lcn) {
tl->sl_lcn = lcn;
LIST_FOREACH(csm, &s->s_channels, csm_svc_link)
- idnode_notify_simple(&csm->csm_chn->ch_id);
+ idnode_notify_changed(&csm->csm_chn->ch_id);
}
tl->sl_seen = 1;
t = (service_t *)bq->bq_services->is_array[z];
LIST_FOREACH(csm, &t->s_channels, csm_svc_link)
if (csm->csm_chn->ch_bouquet == bq)
- idnode_notify_simple(&csm->csm_chn->ch_id);
+ idnode_notify_changed(&csm->csm_chn->ch_id);
}
}
htsmsg_destroy(c);
bq->bq_saveflag = 0;
if (notify)
- idnode_notify_simple(&bq->bq_id);
+ idnode_notify_changed(&bq->bq_id);
}
/* **************************************************************************
if (i > 1 || check_file(buf)) {
icon = ch->ch_icon = strdup(buf);
channel_save(ch);
- idnode_notify_simple(&ch->ch_id);
+ idnode_notify_changed(&ch->ch_id);
}
}
if (i > 1 || check_file(buf2)) {
icon = ch->ch_icon = strdup(icn);
channel_save(ch);
- idnode_notify_simple(&ch->ch_id);
+ idnode_notify_changed(&ch->ch_id);
break;
}
}
LIST_REMOVE(ctm, ctm_tag_link);
free(ctm);
channel_save(ch);
- idnode_notify_simple(&ch->ch_id);
+ idnode_notify_changed(&ch->ch_id);
if (ct->ct_enabled && !ct->ct_internal) {
htsp_tag_update(ct);
htsp_channel_update(ch);
{
if (cac->cac_status != status) {
cac->cac_status = status;
- idnode_notify_simple(&cac->cac_id);
+ idnode_notify_changed(&cac->cac_id);
}
}
while((dae = LIST_FIRST(&ct->ct_autorecs)) != NULL) {
LIST_REMOVE(dae, dae_channel_tag_link);
dae->dae_channel_tag = NULL;
- idnode_notify_simple(&dae->dae_id);
+ idnode_notify_changed(&dae->dae_id);
if (delconf)
dvr_autorec_save(dae);
}
if (saveconf)
dvr_entry_save(de);
- idnode_notify_simple(&de->de_id);
+ idnode_notify_changed(&de->de_id);
htsp_dvr_entry_update(de);
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
dvr_inotify_del(de);
htsp_dvr_entry_update(de);
- idnode_notify_simple(&de->de_id);
+ idnode_notify_changed(&de->de_id);
}
/*
while ((de = LIST_FIRST(&die->entries))) {
htsp_dvr_entry_update(de);
- idnode_notify_simple(&de->de_id);
+ idnode_notify_changed(&de->de_id);
dvr_inotify_del(de);
}
}
dvr_notify(dvr_entry_t *de, int now)
{
if (now || de->de_last_notify + 5 < dispatch_clock) {
- idnode_notify_simple(&de->de_id);
+ idnode_notify_changed(&de->de_id);
de->de_last_notify = dispatch_clock;
htsp_dvr_entry_update(de);
}
/*
*
*/
-void
+htsmsg_t *
htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub)
{
htsmsg_field_t *f;
f->hmf_msg.hm_islist = sub->hm_islist;
TAILQ_MOVE(&f->hmf_msg.hm_fields, &sub->hm_fields, hmf_link);
free(sub);
+
+ if (f->hmf_type == (f->hmf_msg.hm_islist ? HMF_LIST : HMF_MAP))
+ return &f->hmf_msg;
+
+ return NULL;
}
/**
* Add an field where source is a list or map message.
*/
-void htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
+htsmsg_t *htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
/**
* Add an field where source is a double
assert(c == NULL);
/* Fire event */
- idnode_notify_simple(in);
+ idnode_notify_changed(in);
return 0;
}
RB_REMOVE(&idnodes, in, in_link);
RB_REMOVE(in->in_domain, in, in_domain_link);
tvhtrace("idnode", "unlink node %s", idnode_uuid_as_str(in));
- idnode_notify_simple(in);
+ idnode_notify(in, "delete");
}
/**
*
*/
static void
-idnode_handler(size_t off, idnode_t *in)
+idnode_handler(size_t off, idnode_t *in, const char *action)
{
void (**fcn)(idnode_t *);
lock_assert(&global_lock);
while (idc) {
fcn = (void *)idc + off;
if (*fcn) {
+ if (action)
+ idnode_notify(in, action);
(*fcn)(in);
break;
}
idc = idc->ic_super;
}
+
}
void
idnode_delete(idnode_t *in)
{
- return idnode_handler(offsetof(idclass_t, ic_delete), in);
+ idnode_handler(offsetof(idclass_t, ic_delete), in, NULL);
}
void
idnode_moveup(idnode_t *in)
{
- return idnode_handler(offsetof(idclass_t, ic_moveup), in);
+ return idnode_handler(offsetof(idclass_t, ic_moveup), in, "moveup");
}
void
idnode_movedown(idnode_t *in)
{
- return idnode_handler(offsetof(idclass_t, ic_movedown), in);
+ return idnode_handler(offsetof(idclass_t, ic_movedown), in, "movedown");
}
/* **************************************************************************
if (save && dosave)
idnode_savefn(self);
if (dosave)
- idnode_notify_simple(self);
+ idnode_notify_changed(self);
// Note: always output event if "dosave", reason is that UI updates on
// these, but there are some subtle cases where it will expect
// an update and not get one. This include fields being set for
void
idnode_changed( idnode_t *self )
{
- idnode_notify_simple(self);
+ idnode_notify_changed(self);
idnode_savefn(self);
}
* Delayed notification
*/
static void
-idnode_notify_delayed ( idnode_t *in, const char *uuid, const char *event )
+idnode_notify_delayed
+ ( const char *uuid, const char *event, const char *action )
{
+ htsmsg_t *m = NULL, *e = NULL;
+ htsmsg_field_t *f;
+
pthread_mutex_lock(&idnode_mutex);
- if (!idnode_queue)
+ if (idnode_queue == NULL) {
idnode_queue = htsmsg_create_map();
- htsmsg_set_str(idnode_queue, uuid, event);
+ } else {
+ m = htsmsg_get_map(idnode_queue, event);
+ }
+ if (m == NULL) {
+ m = htsmsg_add_msg(idnode_queue, event, htsmsg_create_map());
+ } else {
+ e = htsmsg_get_list(m, action);
+ }
+ if (e == NULL)
+ e = htsmsg_add_msg(m, action, htsmsg_create_list());
+ HTSMSG_FOREACH(f, e)
+ if (strcmp(htsmsg_field_get_str(f) ?: "", uuid) == 0)
+ goto skip;
+ htsmsg_add_str(e, NULL, uuid);
pthread_cond_signal(&idnode_cond);
+skip:
pthread_mutex_unlock(&idnode_mutex);
}
/**
- * Update internal event pipes
- */
-static void
-idnode_notify_event ( idnode_t *in )
-{
- const idclass_t *ic = in->in_class;
- const char *uuid = idnode_uuid_as_str(in);
- while (ic) {
- if (ic->ic_event)
- idnode_notify_delayed(in, uuid, ic->ic_event);
- ic = ic->ic_super;
- }
-}
-
-/**
- * Notify on a given channel
+ * Notify about a change
*/
void
-idnode_notify
- (idnode_t *in, int event)
+idnode_notify ( idnode_t *in, const char *action )
{
+ const idclass_t *ic = in->in_class;
const char *uuid = idnode_uuid_as_str(in);
if (!tvheadend_running)
return;
- /* Immediate */
- if (!event) {
-
- const idclass_t *ic = in->in_class;
-
- while (ic) {
- if (ic->ic_event) {
- htsmsg_t *m = htsmsg_create_map();
- htsmsg_add_str(m, "uuid", uuid);
- notify_by_msg(ic->ic_event, m);
- }
- ic = ic->ic_super;
- }
-
- /* Rate-limited */
- } else {
- idnode_notify_event(in);
+ while (ic) {
+ if (ic->ic_event)
+ idnode_notify_delayed(uuid, ic->ic_event, action);
+ ic = ic->ic_super;
}
}
void
-idnode_notify_simple (void *in)
+idnode_notify_changed (void *in)
{
- idnode_notify(in, 1);
+ idnode_notify(in, "change");
}
void
htsmsg_add_str(m, "uuid", idnode_uuid_as_str(in));
htsmsg_add_str(m, "text", idnode_get_title(in));
notify_by_msg("title", m);
- idnode_notify_event(in);
+ idnode_notify_changed(in);
}
/*
void*
idnode_thread ( void *p )
{
- idnode_t *node;
- htsmsg_t *m, *q = NULL;
+ htsmsg_t *q = NULL;
htsmsg_field_t *f;
- const char *event;
pthread_mutex_lock(&idnode_mutex);
/* Process */
pthread_mutex_lock(&global_lock);
- HTSMSG_FOREACH(f, q) {
- node = idnode_find(f->hmf_name, NULL, NULL);
- event = htsmsg_field_get_str(f);
- if (event) {
- m = htsmsg_create_map();
- htsmsg_add_str(m, "uuid", f->hmf_name);
- if (!node)
- htsmsg_add_u32(m, "removed", 1);
- notify_by_msg(event, m);
- }
- }
+ HTSMSG_FOREACH(f, q)
+ notify_by_msg(f->hmf_name, htsmsg_detach_submsg(f));
/* Finished */
pthread_mutex_unlock(&global_lock);
idnode_set_t *idnode_find_all(const idclass_t *idc, const idnodes_rb_t *nodes);
-void idnode_notify (idnode_t *in, int event);
-void idnode_notify_simple (void *in);
+void idnode_notify (idnode_t *in, const char *action);
+void idnode_notify_changed (void *in);
void idnode_notify_title_changed (void *in);
void idclass_register ( const idclass_t *idc );
mnl->mnl_network = mn;
LIST_INSERT_HEAD(&mi->mi_networks, mnl, mnl_mi_link);
LIST_INSERT_HEAD(&mn->mn_inputs, mnl, mnl_mn_link);
- idnode_notify_simple(&mnl->mnl_network->mn_id);
+ idnode_notify_changed(&mnl->mnl_network->mn_id);
return 1;
}
static void
mpegts_input_del_network ( mpegts_network_link_t *mnl )
{
- idnode_notify_simple(&mnl->mnl_network->mn_id);
+ idnode_notify_changed(&mnl->mnl_network->mn_id);
LIST_REMOVE(mnl, mnl_mn_link);
LIST_REMOVE(mnl, mnl_mi_link);
free(mnl);
mpegts_mux_nice_name(mm, buf, sizeof(buf));
mm->mm_config_save(mm);
tvhtrace("mpegts", "%s - set onid %04X (%d)", buf, onid, onid);
- //idnode_notify(NULL, &mm->mm_id, 0, NULL);
+ idnode_notify_changed(&mm->mm_id);
return 1;
}
mpegts_mux_nice_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - set tsid %04X (%d)", buf, tsid, tsid);
#endif
- //idnode_notify(NULL, &mm->mm_id, 0, NULL);
+ idnode_notify_changed(&mm->mm_id);
return 1;
}
mpegts_mux_nice_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - set crid authority %s", buf, defauth);
#endif
- //idnode_notify(NULL, &mm->mm_id, 0, NULL);
+ idnode_notify_changed(&mm->mm_id);
return 1;
}
static void
mpegts_network_link_delete ( mpegts_network_link_t *mnl )
{
- idnode_notify_simple(&mnl->mnl_input->ti_id);
+ idnode_notify_changed(&mnl->mnl_input->ti_id);
LIST_REMOVE(mnl, mnl_mn_link);
LIST_REMOVE(mnl, mnl_mi_link);
free(mnl);
static void
mpegts_network_scan_notify ( mpegts_mux_t *mm )
{
- idnode_notify_simple(&mm->mm_id);
- idnode_notify_simple(&mm->mm_network->mn_id);
+ idnode_notify_changed(&mm->mm_id);
+ idnode_notify_changed(&mm->mm_network->mn_id);
}
static int
tvhlog(LOG_DEBUG, "mpegts", "%s - add service %04X %s", buf, s->s_dvb_service_id, s->s_dvb_svcname);
/* Notification */
- idnode_notify_simple(&mm->mm_id);
- idnode_notify_simple(&mm->mm_network->mn_id);
+ idnode_notify_changed(&mm->mm_id);
+ idnode_notify_changed(&mm->mm_network->mn_id);
/* Save the create time */
if (s->s_dvb_created == dispatch_clock)
/* 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);
+ idnode_notify_changed(&svc->s_id);
return 0;
}
t->s_auto = _auto;
service_class_notify_enabled(t);
service_request_save(t, 0);
- idnode_notify_simple(&t->s_id);
+ idnode_notify_changed(&t->s_id);
}
}
if (origin == NULL)
return;
if (origin == csm->csm_svc) {
- idnode_notify_simple(&csm->csm_chn->ch_id);
+ idnode_notify_changed(&csm->csm_chn->ch_id);
channel_save(csm->csm_chn);
}
if (origin == csm->csm_chn)
- idnode_notify_simple(&csm->csm_svc->s_id);
+ idnode_notify_changed(&csm->csm_svc->s_id);
}
/*
channel_tag_map(chn, channel_tag_find_by_name(prov, 1));
/* save */
- idnode_notify_simple(&chn->ch_id);
+ idnode_notify_changed(&chn->ch_id);
channel_save(chn);
}
if (!bq) {