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:
parent
29f6d712e8
commit
28b204a905
10 changed files with 149 additions and 37 deletions
36
src/idnode.c
36
src/idnode.c
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -441,9 +441,6 @@ service_create0
|
|||
if (conf)
|
||||
service_load(t, conf);
|
||||
|
||||
/* Notify */
|
||||
idnode_notify(&t->s_id, "service", 0);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue