mpegts idnode: updates to idnode for more resopsive list types

input network select is now dynamic and will update when network names are
changed
This commit is contained in:
Adam Sutton 2013-08-07 15:27:53 +01:00
parent 29f6d712e8
commit 28b204a905
10 changed files with 149 additions and 37 deletions

View file

@ -152,6 +152,10 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class)
fprintf(stderr, "Id node collision\n");
abort();
}
/* Fire event */
idnode_notify(in, NULL, 0, 1);
return 0;
}
@ -163,7 +167,7 @@ idnode_unlink(idnode_t *in)
{
lock_assert(&global_lock);
RB_REMOVE(&idnodes, in, in_link);
idnode_updated(in);
idnode_notify(in, NULL, 0, 1);
}
/* **************************************************************************
@ -590,7 +594,7 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave )
}
if (save && dosave) {
if (savefn) savefn(self);
idnode_notify(self, NULL, 0);
idnode_notify(self, NULL, 0, 0);
}
return save;
}
@ -715,12 +719,31 @@ idnode_serialize0(idnode_t *self, int optmask)
* Notifcation
* *************************************************************************/
/**
* 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) {
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "uuid", uuid);
printf("event = %s\n", ic->ic_event);
notify_by_msg(ic->ic_event, m);
}
ic = ic->ic_super;
}
}
/**
* Notify on a given channel
*/
void
idnode_notify
(idnode_t *in, const char *chn, int force)
(idnode_t *in, const char *chn, int force, int event)
{
const char *uuid = idnode_uuid_as_str(in);
@ -739,12 +762,16 @@ idnode_notify
pthread_cond_signal(&idnode_cond);
pthread_mutex_unlock(&idnode_mutex);
}
/* Send event */
if (event)
idnode_notify_event(in);
}
void
idnode_notify_simple (void *in)
{
idnode_notify(in, NULL, 0);
idnode_notify(in, NULL, 0, 0);
}
void
@ -754,6 +781,7 @@ idnode_notify_title_changed (void *in)
htsmsg_add_str(m, "uuid", idnode_uuid_as_str(in));
htsmsg_add_str(m, "text", idnode_get_title(in));
notify_by_msg("idnodeUpdated", m);
idnode_notify_event(in);
}
/*

View file

@ -46,6 +46,7 @@ typedef struct idclass {
const char *ic_class; /// Class name
const char *ic_caption; /// Class description
const property_t *ic_properties; /// Property list
const char *ic_event; /// Events to fire on add/delete/title
/* Callbacks */
idnode_set_t *(*ic_get_childs)(idnode_t *self);
@ -116,9 +117,9 @@ int idnode_is_instance (idnode_t *in, const idclass_t *idc);
void *idnode_find (const char *uuid, const idclass_t *idc);
idnode_set_t *idnode_find_all(const idclass_t *idc);
#define idnode_updated(in) idnode_notify(in, NULL, 0)
#define idnode_updated(in) idnode_notify(in, NULL, 0, 0)
void idnode_notify
(idnode_t *in, const char *chn, int force);
(idnode_t *in, const char *chn, int force, int event);
void idnode_notify_simple (void *in);
void idnode_notify_title_changed (void *in);

View file

@ -410,6 +410,7 @@ struct mpegts_input
void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*);
int (*mi_has_subscription) (mpegts_input_t*, mpegts_mux_t *mm);
int (*mi_grace_period) (mpegts_input_t*, mpegts_mux_t *mm);
idnode_set_t *(*mi_network_list) (mpegts_input_t*);
};
/* ****************************************************************************
@ -445,6 +446,8 @@ mpegts_input_t *mpegts_input_create0
mpegts_input_create0(calloc(1, sizeof(mpegts_input_t)),\
&mpegts_input_class, u, c)
#define mpegts_input_find(u) idnode_find(u, &mpegts_input_class);
void mpegts_input_set_network ( mpegts_input_t *mi, mpegts_network_t *mn );
void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int init );

View file

@ -92,22 +92,15 @@ linuxdvb_frontend_class_network_set(void *o, const void *v)
static htsmsg_t *
linuxdvb_frontend_class_network_enum(void *o)
{
extern const idclass_t linuxdvb_network_class;
int i;
linuxdvb_frontend_t *lfe = o;
linuxdvb_network_t *ln;
htsmsg_t *m = htsmsg_create_list();
idnode_set_t *is = idnode_find_all(&linuxdvb_network_class);
for (i = 0; i < is->is_count; i++) {
ln = (linuxdvb_network_t*)is->is_array[i];
if (ln->ln_type == lfe->lfe_info.type) {
htsmsg_t *e = htsmsg_create_map();
htsmsg_add_str(e, "key", idnode_uuid_as_str(&ln->mn_id));
htsmsg_add_str(e, "val", ln->mn_network_name);
htsmsg_add_msg(m, NULL, e);
}
}
idnode_set_free(is);
htsmsg_t *m = htsmsg_create_map();
htsmsg_t *p = htsmsg_create_map();
htsmsg_add_str(m, "type", "api");
htsmsg_add_str(m, "uri", "mpegts/input");
htsmsg_add_str(p, "op", "network_list");
htsmsg_add_str(p, "uuid", idnode_uuid_as_str((idnode_t*)o));
htsmsg_add_str(m, "event", "mpegts_network");
htsmsg_add_msg(m, "params", p);
return m;
}
@ -368,6 +361,30 @@ exit:
mpegts_input_close_service(mi, s);
}
static idnode_set_t *
linuxdvb_frontend_network_list ( mpegts_input_t *mi )
{
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
const idclass_t *idc;
extern const idclass_t linuxdvb_network_dvbt_class;
extern const idclass_t linuxdvb_network_dvbc_class;
extern const idclass_t linuxdvb_network_dvbs_class;
extern const idclass_t linuxdvb_network_atsc_class;
if (lfe->lfe_info.type == FE_OFDM)
idc = &linuxdvb_network_dvbt_class;
else if (lfe->lfe_info.type == FE_QAM)
idc = &linuxdvb_network_dvbc_class;
else if (lfe->lfe_info.type == FE_QPSK)
idc = &linuxdvb_network_dvbs_class;
else if (lfe->lfe_info.type == FE_ATSC)
idc = &linuxdvb_network_atsc_class;
else
return NULL;
return idnode_find_all(idc);
}
/* **************************************************************************
* Data processing
* *************************************************************************/
@ -829,6 +846,7 @@ linuxdvb_frontend_create0
lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
lfe->mi_open_service = linuxdvb_frontend_open_service;
lfe->mi_close_service = linuxdvb_frontend_close_service;
lfe->mi_network_list = linuxdvb_frontend_network_list;
lfe->lfe_open_pid = linuxdvb_frontend_open_pid;
/* Adapter link */

View file

@ -564,9 +564,6 @@ linuxdvb_satconf_create0
if (!ls->ls_lnb)
ls->ls_lnb = linuxdvb_lnb_create0(NULL, NULL, ls);
/* Notification */
idnode_notify(&ls->mi_id, "linuxdvb_satconf", 0);
return ls;
}

View file

@ -163,6 +163,7 @@ const idclass_t mpegts_mux_class =
{
.ic_class = "mpegts_mux",
.ic_caption = "MPEGTS Multiplex",
.ic_event = "mpegts_mux",
.ic_save = mpegts_mux_class_save,
.ic_properties = (const property_t[]){
{
@ -556,10 +557,6 @@ mpegts_mux_create0
mm->mm_display_name(mm, buf, sizeof(buf));
tvhtrace("mpegts", "%s - created", buf);
/* Notification */
idnode_notify(&mm->mm_id, "mpegts_mux", 0);
idnode_updated(&mn->mn_id);
return mm;
}

View file

@ -84,12 +84,14 @@ const idclass_t mpegts_network_class =
.ic_class = "mpegts_network",
.ic_caption = "MPEGTS Network",
.ic_save = mpegts_network_class_save,
.ic_event = "mpegts_network",
.ic_properties = (const property_t[]){
{
.type = PT_STR,
.id = "networkname",
.name = "Network Name",
.off = offsetof(mpegts_network_t, mn_network_name),
.notify = idnode_notify_title_changed,
},
{
.type = PT_U16,
@ -279,9 +281,6 @@ mpegts_network_create0
mn->mn_display_name(mn, buf, sizeof(buf));
tvhtrace("mpegts", "created network %s", buf);
/* Notification */
idnode_notify(&mn->mn_id, "mpegts_network", 0);
return mn;
}

View file

@ -441,9 +441,6 @@ service_create0
if (conf)
service_load(t, conf);
/* Notify */
idnode_notify(&t->s_id, "service", 0);
return t;
}

View file

@ -387,7 +387,7 @@ extjs_mpegts_input
(http_connection_t *hc, const char *remain, void *opaque)
{
mpegts_input_t *mi;
//mpegts_network_t *mn;
mpegts_network_t *mn;
htsbuf_queue_t *hq = &hc->hc_reply;
const char *op = http_arg_get(&hc->hc_req_args, "op");
htsmsg_t *out = htsmsg_create_map();
@ -403,8 +403,32 @@ extjs_mpegts_input
idnode_set_add(&ins, (idnode_t*)mi, &conf.filter);
extjs_idnode_grid(&ins, &conf, out);
} else if (!strcmp(op, "class")) {
htsmsg_t *list= idclass_serialize(&mpegts_input_class);
htsmsg_t *list = idclass_serialize(&mpegts_input_class);
htsmsg_add_msg(out, "entries", list);
} else if (!strcmp(op, "network_list")) {
const char *uuid = http_arg_get(&hc->hc_req_args, "uuid");
if (!uuid) return HTTP_STATUS_BAD_REQUEST;
pthread_mutex_lock(&global_lock);
mi = mpegts_input_find(uuid);
if (mi) {
int i;
idnode_set_t *is = mi->mi_network_list(mi);
if (is) {
htsmsg_t *l = htsmsg_create_list();
for (i = 0; i < is->is_count; i++) {
char buf[256];
htsmsg_t *e = htsmsg_create_map();
mn = (mpegts_network_t*)is->is_array[i];
htsmsg_add_str(e, "key", idnode_uuid_as_str(is->is_array[i]));
mn->mn_display_name(mn, buf, sizeof(buf));
htsmsg_add_str(e, "val", buf);
htsmsg_add_msg(l, NULL, e);
}
htsmsg_add_msg(out, "entries", l);
idnode_set_free(is);
}
}
pthread_mutex_unlock(&global_lock);
#if 0
} else if (!strcmp(op, "network_class")) {
const char *uuid = http_arg_get(&hc->hc_req_args, "uuid");

View file

@ -1,3 +1,41 @@
/*
* Combobox stores
*/
tvheadend.idnode_enum_stores = {}
tvheadend.idnode_get_enum = function ( conf )
{
/* Build key */
key = conf.url;
if (conf.event)
key += conf.event;
if (conf.params)
key += Ext.util.JSON.encode(conf.params);
/* Use cached */
if (key in tvheadend.idnode_enum_stores)
return tvheadend.idnode_enum_stores[key];
/* Build combobox */
var st = new Ext.data.JsonStore({
root : conf.root || 'entries',
url : conf.url,
baseParams : conf.params || {},
fields : conf.fields || [ 'key', 'val' ],
autoLoad : true,
});
tvheadend.idnode_enum_stores[key] = st;
/* Event to update */
if (conf.event) {
tvheadend.comet.on(conf.event, function(){
st.reload();
});
}
return st;
}
json_decode = function(d)
{
if (d && d.responseText) {
@ -18,6 +56,16 @@ json_decode = function(d)
tvheadend.idnode_enum_store = function(f)
{
var store = null;
/* API fetch */
if (f.enum.type == 'api') {
return tvheadend.idnode_get_enum({
url : 'api/' + f.enum.uri,
params : f.enum.params,
event : f.enum.event
});
}
switch (f.type) {
case 'str':
if (f.enum.length > 0 && f.enum[0] instanceof Object)